From 33034b13cae1429d526722374bd39be3f9605ae4 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Tue, 10 Jul 2012 12:37:54 -0700 Subject: [PATCH] Create telephony-common and mms-common - DO NOT MERGE These have been created to reduce the size and complexity of frameworks/base. mms-common was created by moving all of frameworks/base/core/java/com/google/android/mms to: frameworks/opt/mms telephony-common was created by moving some of frameworks/base/telephony to: frameworks/opt/telephony Change-Id: If6cb3c6ff952767fc10210f923dc0e4b343cd4ad --- Android.mk | 11 +- .../android/net/MobileDataStateTracker.java | 97 +- core/java/android/provider/CallLog.java | 8 +- core/java/android/provider/Telephony.java | 2037 --------- .../com/google/android/mms/ContentType.java | 229 - .../mms/InvalidHeaderValueException.java | 41 - .../com/google/android/mms/MmsException.java | 60 - core/java/com/google/android/mms/package.html | 5 - .../android/mms/pdu/AcknowledgeInd.java | 89 - .../com/google/android/mms/pdu/Base64.java | 167 - .../google/android/mms/pdu/CharacterSets.java | 172 - .../google/android/mms/pdu/DeliveryInd.java | 138 - .../android/mms/pdu/EncodedStringValue.java | 283 -- .../google/android/mms/pdu/GenericPdu.java | 113 - .../android/mms/pdu/MultimediaMessagePdu.java | 150 - .../android/mms/pdu/NotificationInd.java | 285 -- .../google/android/mms/pdu/NotifyRespInd.java | 114 - .../com/google/android/mms/pdu/PduBody.java | 191 - .../google/android/mms/pdu/PduComposer.java | 1179 ----- .../android/mms/pdu/PduContentTypes.java | 110 - .../google/android/mms/pdu/PduHeaders.java | 721 --- .../com/google/android/mms/pdu/PduParser.java | 1912 -------- .../com/google/android/mms/pdu/PduPart.java | 402 -- .../google/android/mms/pdu/PduPersister.java | 1477 ------- .../android/mms/pdu/QuotedPrintable.java | 68 - .../google/android/mms/pdu/ReadOrigInd.java | 153 - .../google/android/mms/pdu/ReadRecInd.java | 144 - .../google/android/mms/pdu/RetrieveConf.java | 300 -- .../com/google/android/mms/pdu/SendConf.java | 117 - .../com/google/android/mms/pdu/SendReq.java | 345 -- .../com/google/android/mms/pdu/package.html | 5 - .../android/mms/util/AbstractCache.java | 112 - .../android/mms/util/DownloadDrmHelper.java | 111 - .../android/mms/util/DrmConvertSession.java | 172 - .../com/google/android/mms/util/PduCache.java | 261 -- .../android/mms/util/PduCacheEntry.java | 44 - .../android/mms/util/SqliteWrapper.java | 120 - .../com/google/android/mms/util/package.html | 5 - core/tests/coretests/Android.mk | 2 +- packages/SettingsProvider/Android.mk | 2 +- .../providers/settings/DatabaseHelper.java | 4 +- packages/SystemUI/Android.mk | 2 +- .../statusbar/phone/CarrierLabel.java | 17 +- .../statusbar/phone/PhoneStatusBarPolicy.java | 30 +- .../statusbar/policy/NetworkController.java | 45 +- packages/WAPPushManager/Android.mk | 1 + packages/WAPPushManager/tests/Android.mk | 2 +- .../impl/KeyguardStatusViewManager.java | 16 +- .../policy/impl/KeyguardUpdateMonitor.java | 89 +- .../policy/impl/KeyguardViewMediator.java | 10 +- .../policy/impl/LockPatternKeyguardView.java | 26 +- .../LockPatternKeyguardViewProperties.java | 11 +- .../internal/policy/impl/LockScreen.java | 4 +- .../impl/LockPatternKeyguardViewTest.java | 8 +- services/java/Android.mk | 2 +- .../android/server/ConnectivityService.java | 17 +- .../com/android/server/TelephonyRegistry.java | 27 +- .../server/connectivity/Tethering.java | 9 +- .../server/location/GpsLocationProvider.java | 11 +- .../telephony/CellBroadcastMessage.java | 422 -- .../java/android/telephony/CellLocation.java | 10 +- .../android/telephony/PhoneStateListener.java | 1 - .../java/android/telephony/SmsCbCmasInfo.java | 308 -- .../java/android/telephony/SmsCbEtwsInfo.java | 206 - .../java/android/telephony/SmsCbLocation.java | 202 - .../java/android/telephony/SmsCbMessage.java | 382 -- .../java/android/telephony/SmsManager.java | 522 --- .../java/android/telephony/SmsMessage.java | 680 --- .../android/telephony/TelephonyManager.java | 148 +- .../android/telephony/gsm/SmsManager.java | 261 -- .../android/telephony/gsm/SmsMessage.java | 628 --- .../android/internal/telephony/ATParseEx.java | 35 - .../internal/telephony/ATResponseParser.java | 186 - .../android/internal/telephony/AdnRecord.java | 321 -- .../internal/telephony/AdnRecordCache.java | 364 -- .../internal/telephony/AdnRecordLoader.java | 284 -- .../internal/telephony/ApnContext.java | 228 - .../internal/telephony/ApnSetting.java | 200 - .../internal/telephony/BaseCommands.java | 721 --- .../com/android/internal/telephony/Call.java | 255 -- .../internal/telephony/CallForwardInfo.java | 42 - .../internal/telephony/CallManager.java | 1855 -------- .../telephony/CallStateException.java | 34 - .../internal/telephony/CallTracker.java | 182 - .../internal/telephony/CommandException.java | 98 - .../internal/telephony/CommandsInterface.java | 1579 ------- .../internal/telephony/Connection.java | 314 -- .../internal/telephony/DataCallState.java | 245 -- .../internal/telephony/DataConnection.java | 1277 ------ .../internal/telephony/DataConnectionAc.java | 591 --- .../telephony/DataConnectionTracker.java | 1285 ------ .../internal/telephony/DctConstants.java | 115 + .../internal/telephony/DebugService.java | 108 - .../telephony/DefaultPhoneNotifier.java | 281 -- .../internal/telephony/DriverCall.java | 162 - .../internal/telephony/EventLogTags.logtags | 73 - .../internal/telephony/GsmAlphabet.java | 89 +- .../internal/telephony/IIccPhoneBook.aidl | 101 - .../internal/telephony/IPhoneSubInfo.aidl | 0 .../com/android/internal/telephony/ISms.aidl | 201 - .../android/internal/telephony/IccCard.java | 1002 ----- .../telephony/IccCardApplication.java | 226 - .../internal/telephony/IccCardConstants.java | 73 + .../internal/telephony/IccCardStatus.java | 188 - .../internal/telephony/IccConstants.java | 90 - .../internal/telephony/IccException.java | 30 - .../internal/telephony/IccFileHandler.java | 551 --- .../internal/telephony/IccFileNotFound.java | 34 - .../telephony/IccFileTypeMismatch.java | 30 - .../internal/telephony/IccIoResult.java | 70 - .../IccPhoneBookInterfaceManager.java | 289 -- .../IccPhoneBookInterfaceManagerProxy.java | 75 - .../internal/telephony/IccProvider.java | 431 -- .../internal/telephony/IccRecords.java | 422 -- .../telephony/IccRefreshResponse.java | 42 - .../internal/telephony/IccServiceTable.java | 81 - .../telephony/IccSmsInterfaceManager.java | 217 - .../IccSmsInterfaceManagerProxy.java | 88 - .../android/internal/telephony/IccUtils.java | 530 --- .../telephony/IccVmFixedException.java | 32 - .../telephony/IccVmNotSupportedException.java | 32 - .../internal/telephony/IntRangeManager.java | 576 --- .../android/internal/telephony/MccTable.java | 571 --- .../android/internal/telephony/MmiCode.java | 62 - .../internal/telephony/OperatorInfo.java | 149 - .../com/android/internal/telephony/Phone.java | 1786 -------- .../android/internal/telephony/PhoneBase.java | 1188 ----- .../internal/telephony/PhoneConstants.java | 123 + .../internal/telephony/PhoneFactory.java | 249 -- .../internal/telephony/PhoneNotifier.java | 50 - .../internal/telephony/PhoneProxy.java | 972 ----- .../telephony/PhoneStateIntentReceiver.java | 203 - .../internal/telephony/PhoneSubInfo.java | 206 - .../internal/telephony/PhoneSubInfoProxy.java | 133 - .../com/android/internal/telephony/RIL.java | 3861 ----------------- .../internal/telephony/RestrictedState.java | 122 - .../internal/telephony/RetryManager.java | 404 -- .../internal/telephony/SMSDispatcher.java | 1251 ------ .../telephony/ServiceStateTracker.java | 538 --- .../internal/telephony/SmsAddress.java | 65 - .../internal/telephony/SmsConstants.java | 75 + .../android/internal/telephony/SmsHeader.java | 289 -- .../internal/telephony/SmsMessageBase.java | 404 -- .../internal/telephony/SmsRawData.java | 62 - .../internal/telephony/SmsResponse.java | 48 - .../internal/telephony/SmsStorageMonitor.java | 162 - .../internal/telephony/SmsUsageMonitor.java | 476 -- .../telephony/TelephonyCapabilities.java | 191 - .../internal/telephony/TelephonyIntents.java | 41 +- .../android/internal/telephony/UUSInfo.java | 100 - .../telephony/WapPushManagerParams.java | 70 - .../internal/telephony/WapPushOverSms.java | 275 -- .../internal/telephony/WspTypeDecoder.java | 731 ---- .../internal/telephony/cat/AppInterface.java | 96 - .../internal/telephony/cat/BerTlv.java | 123 - .../internal/telephony/cat/CatCmdMessage.java | 182 - .../internal/telephony/cat/CatException.java | 31 - .../internal/telephony/cat/CatLog.java | 41 - .../telephony/cat/CatResponseMessage.java | 54 - .../internal/telephony/cat/CatService.java | 750 ---- .../telephony/cat/CommandDetails.java | 115 - .../internal/telephony/cat/CommandParams.java | 199 - .../telephony/cat/CommandParamsFactory.java | 943 ---- .../telephony/cat/ComprehensionTlv.java | 203 - .../telephony/cat/ComprehensionTlvTag.java | 74 - .../internal/telephony/cat/Duration.java | 79 - .../internal/telephony/cat/FontSize.java | 50 - .../internal/telephony/cat/IconLoader.java | 362 -- .../telephony/cat/ImageDescriptor.java | 77 - .../android/internal/telephony/cat/Input.java | 101 - .../android/internal/telephony/cat/Item.java | 71 - .../telephony/cat/LaunchBrowserMode.java | 35 - .../android/internal/telephony/cat/Menu.java | 105 - .../telephony/cat/PresentationType.java | 32 - .../internal/telephony/cat/ResponseData.java | 281 -- .../internal/telephony/cat/ResultCode.java | 186 - .../telephony/cat/ResultException.java | 97 - .../telephony/cat/RilMessageDecoder.java | 177 - .../internal/telephony/cat/TextAlignment.java | 52 - .../internal/telephony/cat/TextAttribute.java | 49 - .../internal/telephony/cat/TextColor.java | 63 - .../internal/telephony/cat/TextMessage.java | 71 - .../android/internal/telephony/cat/Tone.java | 190 - .../internal/telephony/cat/ToneSettings.java | 62 - .../internal/telephony/cat/ValueParser.java | 341 -- .../internal/telephony/cat/package.html | 5 - .../internal/telephony/cdma/CDMALTEPhone.java | 272 -- .../internal/telephony/cdma/CDMAPhone.java | 1507 ------- .../telephony/cdma/CallFailCause.java | 59 - .../internal/telephony/cdma/CdmaCall.java | 208 - .../telephony/cdma/CdmaCallTracker.java | 1162 ----- .../cdma/CdmaCallWaitingNotification.java | 68 - .../telephony/cdma/CdmaConnection.java | 945 ---- .../telephony/cdma/CdmaDataConnection.java | 123 - .../cdma/CdmaDataConnectionTracker.java | 1040 ----- .../cdma/CdmaInformationRecords.java | 263 -- .../cdma/CdmaLteServiceStateTracker.java | 546 --- .../cdma/CdmaLteUiccFileHandler.java | 79 - .../telephony/cdma/CdmaLteUiccRecords.java | 451 -- .../internal/telephony/cdma/CdmaMmiCode.java | 296 -- .../telephony/cdma/CdmaSMSDispatcher.java | 428 -- .../cdma/CdmaServiceStateTracker.java | 1751 -------- .../cdma/CdmaSubscriptionSourceManager.java | 196 - .../internal/telephony/cdma/EriInfo.java | 45 - .../internal/telephony/cdma/EriManager.java | 492 --- .../telephony/cdma/RuimFileHandler.java | 89 - .../cdma/RuimPhoneBookInterfaceManager.java | 79 - .../internal/telephony/cdma/RuimRecords.java | 461 -- .../cdma/RuimSmsInterfaceManager.java | 222 - .../telephony/cdma/SignalToneUtil.java | 294 -- .../internal/telephony/cdma/SmsMessage.java | 997 ----- .../internal/telephony/cdma/TtyIntent.java | 67 - .../internal/telephony/cdma/package.html | 6 - .../telephony/cdma/sms/BearerData.java | 1942 --------- .../telephony/cdma/sms/CdmaSmsAddress.java | 228 - .../telephony/cdma/sms/CdmaSmsSubaddress.java | 27 - .../telephony/cdma/sms/SmsEnvelope.java | 130 - .../internal/telephony/cdma/sms/UserData.java | 165 - .../internal/telephony/cdma/sms/package.html | 6 - .../internal/telephony/gsm/CallFailCause.java | 53 - .../internal/telephony/gsm/GSMPhone.java | 1507 ------- .../internal/telephony/gsm/GsmCall.java | 208 - .../telephony/gsm/GsmCallTracker.java | 951 ---- .../internal/telephony/gsm/GsmConnection.java | 761 ---- .../telephony/gsm/GsmDataConnection.java | 165 - .../gsm/GsmDataConnectionTracker.java | 2594 ----------- .../internal/telephony/gsm/GsmMmiCode.java | 1357 ------ .../telephony/gsm/GsmSMSDispatcher.java | 472 -- .../telephony/gsm/GsmServiceStateTracker.java | 1727 -------- .../internal/telephony/gsm/GsmSmsAddress.java | 148 - .../telephony/gsm/GsmSmsCbMessage.java | 286 -- .../telephony/gsm/SIMFileHandler.java | 107 - .../internal/telephony/gsm/SIMRecords.java | 1674 ------- .../gsm/SimPhoneBookInterfaceManager.java | 79 - .../telephony/gsm/SimSmsInterfaceManager.java | 365 -- .../internal/telephony/gsm/SimTlv.java | 118 - .../telephony/gsm/SmsBroadcastConfigInfo.java | 133 - .../telephony/gsm/SmsCbConstants.java | 125 - .../internal/telephony/gsm/SmsCbHeader.java | 409 -- .../internal/telephony/gsm/SmsMessage.java | 1177 ----- .../internal/telephony/gsm/SpnOverride.java | 94 - .../gsm/SuppServiceNotification.java | 70 - .../gsm/UsimDataDownloadHandler.java | 267 -- .../telephony/gsm/UsimPhoneBookManager.java | 453 -- .../telephony/gsm/UsimServiceTable.java | 142 - .../telephony/gsm/VoiceMailConstants.java | 115 - .../internal/telephony/gsm/package.html | 6 - .../internal/telephony/ims/IsimRecords.java | 44 - .../telephony/ims/IsimUiccRecords.java | 157 - .../internal/telephony/sip/SipCallBase.java | 55 - .../telephony/sip/SipCommandInterface.java | 424 -- .../telephony/sip/SipConnectionBase.java | 181 - .../internal/telephony/sip/SipPhone.java | 938 ---- .../internal/telephony/sip/SipPhoneBase.java | 464 -- .../telephony/sip/SipPhoneFactory.java | 49 - .../telephony/test/ModelInterpreter.java | 741 ---- .../telephony/test/SimulatedCommands.java | 1525 ------- .../telephony/test/SimulatedGsmCallState.java | 809 ---- .../telephony/test/SimulatedRadioControl.java | 53 - .../internal/telephony/test/package.html | 5 - .../telephony/uicc/UiccController.java | 93 - telephony/mockril/Android.mk | 30 - .../telephony/mockril/MockRilController.java | 217 - .../tests/telephonymockriltests/Android.mk | 14 - .../telephonymockriltests/AndroidManifest.xml | 40 - .../TelephonyMockTestRunner.java | 64 - .../functional/SimpleTestUsingMockRil.java | 63 - telephony/tests/telephonytests/Android.mk | 14 - .../tests/telephonytests/AndroidManifest.xml | 44 - .../TelephonyMockRilTestRunner.java | 93 - .../telephony/ATResponseParserTest.java | 113 - .../internal/telephony/AdnRecordTest.java | 176 - .../internal/telephony/ApnSettingTest.java | 109 - .../internal/telephony/CallerInfoTest.java | 241 - .../internal/telephony/GsmAlphabetTest.java | 361 -- .../internal/telephony/GsmSmsTest.java | 538 --- .../telephony/IccServiceTableTest.java | 85 - .../telephony/IntRangeManagerTest.java | 374 -- .../internal/telephony/MccTableTest.java | 75 - .../telephony/NeighboringCellInfoTest.java | 79 - .../telephony/PhoneNumberUtilsTest.java | 657 --- .../telephony/PhoneNumberWatcherTest.java | 292 -- .../internal/telephony/SMSDispatcherTest.java | 105 - .../internal/telephony/SimPhoneBookTest.java | 106 - .../internal/telephony/SimSmsTest.java | 60 - .../internal/telephony/SimUtilsTest.java | 91 - .../telephony/SmsMessageBodyTest.java | 606 --- .../telephony/TelephonyUtilsTest.java | 219 - .../internal/telephony/TestPhoneNotifier.java | 66 - .../telephony/Wap230WspContentTypeTest.java | 853 ---- .../telephony/cdma/CdmaSmsCbTest.java | 746 ---- .../telephony/cdma/sms/CdmaSmsTest.java | 887 ---- .../internal/telephony/gsm/GSMPhoneTest.java | 1932 --------- .../telephony/gsm/GSMTestHandler.java | 118 - .../internal/telephony/gsm/GsmSmsCbTest.java | 758 ---- .../gsm/UsimDataDownloadCommands.java | 624 --- .../telephony/gsm/UsimDataDownloadTest.java | 144 - .../telephony/gsm/UsimServiceTableTest.java | 75 - .../telephony/mockril/MockRilTest.java | 304 -- tests/permission/Android.mk | 2 +- 300 files changed, 866 insertions(+), 98796 deletions(-) delete mode 100755 core/java/android/provider/Telephony.java delete mode 100644 core/java/com/google/android/mms/ContentType.java delete mode 100644 core/java/com/google/android/mms/InvalidHeaderValueException.java delete mode 100644 core/java/com/google/android/mms/MmsException.java delete mode 100755 core/java/com/google/android/mms/package.html delete mode 100644 core/java/com/google/android/mms/pdu/AcknowledgeInd.java delete mode 100644 core/java/com/google/android/mms/pdu/Base64.java delete mode 100644 core/java/com/google/android/mms/pdu/CharacterSets.java delete mode 100644 core/java/com/google/android/mms/pdu/DeliveryInd.java delete mode 100644 core/java/com/google/android/mms/pdu/EncodedStringValue.java delete mode 100644 core/java/com/google/android/mms/pdu/GenericPdu.java delete mode 100644 core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java delete mode 100644 core/java/com/google/android/mms/pdu/NotificationInd.java delete mode 100644 core/java/com/google/android/mms/pdu/NotifyRespInd.java delete mode 100644 core/java/com/google/android/mms/pdu/PduBody.java delete mode 100644 core/java/com/google/android/mms/pdu/PduComposer.java delete mode 100644 core/java/com/google/android/mms/pdu/PduContentTypes.java delete mode 100644 core/java/com/google/android/mms/pdu/PduHeaders.java delete mode 100755 core/java/com/google/android/mms/pdu/PduParser.java delete mode 100644 core/java/com/google/android/mms/pdu/PduPart.java delete mode 100644 core/java/com/google/android/mms/pdu/PduPersister.java delete mode 100644 core/java/com/google/android/mms/pdu/QuotedPrintable.java delete mode 100644 core/java/com/google/android/mms/pdu/ReadOrigInd.java delete mode 100644 core/java/com/google/android/mms/pdu/ReadRecInd.java delete mode 100644 core/java/com/google/android/mms/pdu/RetrieveConf.java delete mode 100644 core/java/com/google/android/mms/pdu/SendConf.java delete mode 100644 core/java/com/google/android/mms/pdu/SendReq.java delete mode 100755 core/java/com/google/android/mms/pdu/package.html delete mode 100644 core/java/com/google/android/mms/util/AbstractCache.java delete mode 100644 core/java/com/google/android/mms/util/DownloadDrmHelper.java delete mode 100644 core/java/com/google/android/mms/util/DrmConvertSession.java delete mode 100644 core/java/com/google/android/mms/util/PduCache.java delete mode 100644 core/java/com/google/android/mms/util/PduCacheEntry.java delete mode 100644 core/java/com/google/android/mms/util/SqliteWrapper.java delete mode 100755 core/java/com/google/android/mms/util/package.html delete mode 100644 telephony/java/android/telephony/CellBroadcastMessage.java delete mode 100644 telephony/java/android/telephony/SmsCbCmasInfo.java delete mode 100644 telephony/java/android/telephony/SmsCbEtwsInfo.java delete mode 100644 telephony/java/android/telephony/SmsCbLocation.java delete mode 100644 telephony/java/android/telephony/SmsCbMessage.java delete mode 100644 telephony/java/android/telephony/SmsManager.java delete mode 100644 telephony/java/android/telephony/SmsMessage.java delete mode 100644 telephony/java/android/telephony/gsm/SmsManager.java delete mode 100644 telephony/java/android/telephony/gsm/SmsMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/ATParseEx.java delete mode 100644 telephony/java/com/android/internal/telephony/ATResponseParser.java delete mode 100644 telephony/java/com/android/internal/telephony/AdnRecord.java delete mode 100644 telephony/java/com/android/internal/telephony/AdnRecordCache.java delete mode 100644 telephony/java/com/android/internal/telephony/AdnRecordLoader.java delete mode 100644 telephony/java/com/android/internal/telephony/ApnContext.java delete mode 100755 telephony/java/com/android/internal/telephony/ApnSetting.java delete mode 100644 telephony/java/com/android/internal/telephony/BaseCommands.java delete mode 100644 telephony/java/com/android/internal/telephony/Call.java delete mode 100644 telephony/java/com/android/internal/telephony/CallForwardInfo.java delete mode 100644 telephony/java/com/android/internal/telephony/CallManager.java delete mode 100644 telephony/java/com/android/internal/telephony/CallStateException.java delete mode 100644 telephony/java/com/android/internal/telephony/CallTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/CommandException.java delete mode 100644 telephony/java/com/android/internal/telephony/CommandsInterface.java delete mode 100644 telephony/java/com/android/internal/telephony/Connection.java delete mode 100644 telephony/java/com/android/internal/telephony/DataCallState.java delete mode 100644 telephony/java/com/android/internal/telephony/DataConnection.java delete mode 100644 telephony/java/com/android/internal/telephony/DataConnectionAc.java delete mode 100644 telephony/java/com/android/internal/telephony/DataConnectionTracker.java create mode 100644 telephony/java/com/android/internal/telephony/DctConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/DebugService.java delete mode 100644 telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java delete mode 100644 telephony/java/com/android/internal/telephony/DriverCall.java delete mode 100644 telephony/java/com/android/internal/telephony/EventLogTags.logtags delete mode 100644 telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl mode change 100755 => 100644 telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl delete mode 100644 telephony/java/com/android/internal/telephony/ISms.aidl delete mode 100644 telephony/java/com/android/internal/telephony/IccCard.java delete mode 100644 telephony/java/com/android/internal/telephony/IccCardApplication.java create mode 100644 telephony/java/com/android/internal/telephony/IccCardConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/IccCardStatus.java delete mode 100644 telephony/java/com/android/internal/telephony/IccConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/IccException.java delete mode 100644 telephony/java/com/android/internal/telephony/IccFileHandler.java delete mode 100644 telephony/java/com/android/internal/telephony/IccFileNotFound.java delete mode 100644 telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java delete mode 100644 telephony/java/com/android/internal/telephony/IccIoResult.java delete mode 100644 telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java delete mode 100644 telephony/java/com/android/internal/telephony/IccProvider.java delete mode 100644 telephony/java/com/android/internal/telephony/IccRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/IccRefreshResponse.java delete mode 100644 telephony/java/com/android/internal/telephony/IccServiceTable.java delete mode 100644 telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java delete mode 100644 telephony/java/com/android/internal/telephony/IccUtils.java delete mode 100644 telephony/java/com/android/internal/telephony/IccVmFixedException.java delete mode 100644 telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java delete mode 100644 telephony/java/com/android/internal/telephony/IntRangeManager.java delete mode 100644 telephony/java/com/android/internal/telephony/MccTable.java delete mode 100644 telephony/java/com/android/internal/telephony/MmiCode.java delete mode 100644 telephony/java/com/android/internal/telephony/OperatorInfo.java delete mode 100644 telephony/java/com/android/internal/telephony/Phone.java delete mode 100644 telephony/java/com/android/internal/telephony/PhoneBase.java create mode 100644 telephony/java/com/android/internal/telephony/PhoneConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/PhoneFactory.java delete mode 100644 telephony/java/com/android/internal/telephony/PhoneNotifier.java delete mode 100644 telephony/java/com/android/internal/telephony/PhoneProxy.java delete mode 100644 telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java delete mode 100755 telephony/java/com/android/internal/telephony/PhoneSubInfo.java delete mode 100755 telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java delete mode 100644 telephony/java/com/android/internal/telephony/RIL.java delete mode 100644 telephony/java/com/android/internal/telephony/RestrictedState.java delete mode 100644 telephony/java/com/android/internal/telephony/RetryManager.java delete mode 100644 telephony/java/com/android/internal/telephony/SMSDispatcher.java delete mode 100644 telephony/java/com/android/internal/telephony/ServiceStateTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsAddress.java create mode 100644 telephony/java/com/android/internal/telephony/SmsConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsHeader.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsMessageBase.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsRawData.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsResponse.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsStorageMonitor.java delete mode 100644 telephony/java/com/android/internal/telephony/SmsUsageMonitor.java delete mode 100644 telephony/java/com/android/internal/telephony/TelephonyCapabilities.java delete mode 100644 telephony/java/com/android/internal/telephony/UUSInfo.java delete mode 100644 telephony/java/com/android/internal/telephony/WapPushManagerParams.java delete mode 100755 telephony/java/com/android/internal/telephony/WapPushOverSms.java delete mode 100755 telephony/java/com/android/internal/telephony/WspTypeDecoder.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/AppInterface.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/BerTlv.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CatException.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CatLog.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CatService.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CommandDetails.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CommandParams.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/Duration.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/FontSize.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/IconLoader.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/Input.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/Item.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/Menu.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/PresentationType.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ResponseData.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ResultCode.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ResultException.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/TextAlignment.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/TextAttribute.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/TextColor.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/TextMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/Tone.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ToneSettings.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/ValueParser.java delete mode 100644 telephony/java/com/android/internal/telephony/cat/package.html delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CallFailCause.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaCall.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/EriInfo.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/EriManager.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java delete mode 100755 telephony/java/com/android/internal/telephony/cdma/RuimRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/SmsMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/TtyIntent.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/package.html delete mode 100755 telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/sms/UserData.java delete mode 100644 telephony/java/com/android/internal/telephony/cdma/sms/package.html delete mode 100644 telephony/java/com/android/internal/telephony/gsm/CallFailCause.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GSMPhone.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmCall.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmConnection.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java delete mode 100755 telephony/java/com/android/internal/telephony/gsm/SIMRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SimTlv.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SmsMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SpnOverride.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java delete mode 100755 telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java delete mode 100755 telephony/java/com/android/internal/telephony/gsm/package.html delete mode 100644 telephony/java/com/android/internal/telephony/ims/IsimRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java delete mode 100644 telephony/java/com/android/internal/telephony/sip/SipCallBase.java delete mode 100644 telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java delete mode 100644 telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java delete mode 100644 telephony/java/com/android/internal/telephony/sip/SipPhone.java delete mode 100755 telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java delete mode 100644 telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java delete mode 100644 telephony/java/com/android/internal/telephony/test/ModelInterpreter.java delete mode 100644 telephony/java/com/android/internal/telephony/test/SimulatedCommands.java delete mode 100644 telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java delete mode 100644 telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java delete mode 100755 telephony/java/com/android/internal/telephony/test/package.html delete mode 100644 telephony/java/com/android/internal/telephony/uicc/UiccController.java delete mode 100644 telephony/mockril/Android.mk delete mode 100644 telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java delete mode 100644 telephony/tests/telephonymockriltests/Android.mk delete mode 100644 telephony/tests/telephonymockriltests/AndroidManifest.xml delete mode 100644 telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java delete mode 100644 telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java delete mode 100644 telephony/tests/telephonytests/Android.mk delete mode 100644 telephony/tests/telephonytests/AndroidManifest.xml delete mode 100644 telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java delete mode 100755 telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java delete mode 100644 telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java diff --git a/Android.mk b/Android.mk index 4d567dfd17c4..b9157fe7e9d6 100644 --- a/Android.mk +++ b/Android.mk @@ -38,7 +38,6 @@ LOCAL_SRC_FILES += \ core/java/android/content/EventLogTags.logtags \ core/java/android/speech/tts/EventLogTags.logtags \ core/java/android/webkit/EventLogTags.logtags \ - telephony/java/com/android/internal/telephony/EventLogTags.logtags \ # The following filters out code we are temporarily not including at all. # TODO: Move AWT and beans (and associated harmony code) back into libcore. @@ -204,12 +203,10 @@ 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/ISms.aidl \ telephony/java/com/android/internal/telephony/IWapPushManager.aidl \ + telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \ wifi/java/android/net/wifi/IWifiManager.aidl \ wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \ - telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \ voip/java/android/net/sip/ISipSession.aidl \ voip/java/android/net/sip/ISipSessionListener.aidl \ voip/java/android/net/sip/ISipService.aidl @@ -339,7 +336,9 @@ include libcore/Docs.mk include external/junit/Common.mk non_base_dirs := \ - ../../external/apache-http/src/org/apache/http + ../../external/apache-http/src/org/apache/http \ + ../opt/telephony/src/java/android/telephony \ + ../opt/telephony/src/java/android/telephony/gsm \ # These are relative to frameworks/base dirs_to_check_apis := \ @@ -390,6 +389,8 @@ framework_docs_LOCAL_JAVA_LIBRARIES := \ core \ ext \ framework \ + mms-common \ + telephony-common \ framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 54a89ad61dcb..561294376335 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -16,11 +16,6 @@ package android.net; -import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_POLICY_DATA_ENABLE; -import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_USER_DATA_ENABLE; -import static com.android.internal.telephony.DataConnectionTracker.DISABLED; -import static com.android.internal.telephony.DataConnectionTracker.ENABLED; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -37,9 +32,9 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Slog; -import com.android.internal.telephony.DataConnectionTracker; +import com.android.internal.telephony.DctConstants; import com.android.internal.telephony.ITelephony; -import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.AsyncChannel; @@ -59,7 +54,7 @@ public class MobileDataStateTracker implements NetworkStateTracker { private static final boolean DBG = false; private static final boolean VDBG = false; - private Phone.DataState mMobileDataState; + private PhoneConstants.DataState mMobileDataState; private ITelephony mPhoneService; private String mApnType; @@ -108,10 +103,10 @@ public class MobileDataStateTracker implements NetworkStateTracker { IntentFilter filter = new IntentFilter(); filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); - filter.addAction(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER); + filter.addAction(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER); mContext.registerReceiver(new MobileDataStateReceiver(), filter); - mMobileDataState = Phone.DataState.DISCONNECTED; + mMobileDataState = PhoneConstants.DataState.DISCONNECTED; } static class MdstHandler extends Handler { @@ -180,7 +175,7 @@ public class MobileDataStateTracker implements NetworkStateTracker { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(TelephonyIntents. ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { - String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); + String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY); if (VDBG) { log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED" + "mApnType=%s %s received apnType=%s", mApnType, @@ -191,18 +186,18 @@ public class MobileDataStateTracker implements NetworkStateTracker { } mNetworkInfo.setSubtype(TelephonyManager.getDefault().getNetworkType(), TelephonyManager.getDefault().getNetworkTypeName()); - Phone.DataState state = Enum.valueOf(Phone.DataState.class, - intent.getStringExtra(Phone.STATE_KEY)); - String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); - String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); - mNetworkInfo.setRoaming(intent.getBooleanExtra(Phone.DATA_NETWORK_ROAMING_KEY, - false)); + PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class, + intent.getStringExtra(PhoneConstants.STATE_KEY)); + String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY); + String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY); + mNetworkInfo.setRoaming(intent.getBooleanExtra( + PhoneConstants.DATA_NETWORK_ROAMING_KEY, false)); if (VDBG) { log(mApnType + " setting isAvailable to " + - intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,false)); + intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false)); } - mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY, - false)); + mNetworkInfo.setIsAvailable(!intent.getBooleanExtra( + PhoneConstants.NETWORK_UNAVAILABLE_KEY, false)); if (DBG) { log("Received state=" + state + ", old=" + mMobileDataState + @@ -232,13 +227,13 @@ public class MobileDataStateTracker implements NetworkStateTracker { break; case CONNECTED: mLinkProperties = intent.getParcelableExtra( - Phone.DATA_LINK_PROPERTIES_KEY); + PhoneConstants.DATA_LINK_PROPERTIES_KEY); if (mLinkProperties == null) { loge("CONNECTED event did not supply link properties."); mLinkProperties = new LinkProperties(); } mLinkCapabilities = intent.getParcelableExtra( - Phone.DATA_LINK_CAPABILITIES_KEY); + PhoneConstants.DATA_LINK_CAPABILITIES_KEY); if (mLinkCapabilities == null) { loge("CONNECTED event did not supply link capabilities."); mLinkCapabilities = new LinkCapabilities(); @@ -248,8 +243,9 @@ public class MobileDataStateTracker implements NetworkStateTracker { } } else { // There was no state change. Check if LinkProperties has been updated. - if (TextUtils.equals(reason, Phone.REASON_LINK_PROPERTIES_CHANGED)) { - mLinkProperties = intent.getParcelableExtra(Phone.DATA_LINK_PROPERTIES_KEY); + if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) { + mLinkProperties = intent.getParcelableExtra( + PhoneConstants.DATA_LINK_PROPERTIES_KEY); if (mLinkProperties == null) { loge("No link property in LINK_PROPERTIES change event."); mLinkProperties = new LinkProperties(); @@ -264,7 +260,7 @@ public class MobileDataStateTracker implements NetworkStateTracker { } } else if (intent.getAction(). equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) { - String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); + String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY); if (!TextUtils.equals(apnType, mApnType)) { if (DBG) { log(String.format( @@ -273,17 +269,18 @@ public class MobileDataStateTracker implements NetworkStateTracker { } return; } - String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY); - String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); + String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY); + String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY); if (DBG) { log("Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); } setDetailedState(DetailedState.FAILED, reason, apnName); - } else if (intent.getAction(). - equals(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) { + } else if (intent.getAction().equals(DctConstants + .ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) { if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER"); - mMessenger = intent.getParcelableExtra(DataConnectionTracker.EXTRA_MESSENGER); + mMessenger = + intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER); AsyncChannel ac = new AsyncChannel(); ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger); } else { @@ -369,7 +366,7 @@ public class MobileDataStateTracker implements NetworkStateTracker { */ public boolean teardown() { setTeardownRequested(true); - return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED); + return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED); } /** @@ -418,17 +415,17 @@ public class MobileDataStateTracker implements NetworkStateTracker { boolean retValue = false; //connected or expect to be? setTeardownRequested(false); switch (setEnableApn(mApnType, true)) { - case Phone.APN_ALREADY_ACTIVE: + case PhoneConstants.APN_ALREADY_ACTIVE: // need to set self to CONNECTING so the below message is handled. retValue = true; break; - case Phone.APN_REQUEST_STARTED: + case PhoneConstants.APN_REQUEST_STARTED: // set IDLE here , avoid the following second FAILED not sent out mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null); retValue = true; break; - case Phone.APN_REQUEST_FAILED: - case Phone.APN_TYPE_NOT_AVAILABLE: + case PhoneConstants.APN_REQUEST_FAILED: + case PhoneConstants.APN_TYPE_NOT_AVAILABLE: break; default: loge("Error in reconnect - unexpected response."); @@ -470,7 +467,8 @@ public class MobileDataStateTracker implements NetworkStateTracker { if (DBG) log("setUserDataEnable: E enabled=" + enabled); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { - channel.sendMessage(CMD_SET_USER_DATA_ENABLE, enabled ? ENABLED : DISABLED); + channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE, + enabled ? DctConstants.ENABLED : DctConstants.DISABLED); mUserDataEnabled = enabled; } if (VDBG) log("setUserDataEnable: X enabled=" + enabled); @@ -481,7 +479,8 @@ public class MobileDataStateTracker implements NetworkStateTracker { if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")"); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { - channel.sendMessage(CMD_SET_POLICY_DATA_ENABLE, enabled ? ENABLED : DISABLED); + channel.sendMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE, + enabled ? DctConstants.ENABLED : DctConstants.DISABLED); mPolicyDataEnabled = enabled; } } @@ -491,12 +490,12 @@ public class MobileDataStateTracker implements NetworkStateTracker { * @param met */ public void setDependencyMet(boolean met) { - Bundle bundle = Bundle.forPair(DataConnectionTracker.APN_TYPE_KEY, mApnType); + Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType); try { if (DBG) log("setDependencyMet: E met=" + met); Message msg = Message.obtain(); - msg.what = DataConnectionTracker.CMD_SET_DEPENDENCY_MET; - msg.arg1 = (met ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED); + msg.what = DctConstants.CMD_SET_DEPENDENCY_MET; + msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED); msg.setData(bundle); mDataConnectionTrackerAc.sendMessage(msg); if (VDBG) log("setDependencyMet: X met=" + met); @@ -546,27 +545,27 @@ public class MobileDataStateTracker implements NetworkStateTracker { } loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\""); - return Phone.APN_REQUEST_FAILED; + return PhoneConstants.APN_REQUEST_FAILED; } public static String networkTypeToApnType(int netType) { switch(netType) { case ConnectivityManager.TYPE_MOBILE: - return Phone.APN_TYPE_DEFAULT; // TODO - use just one of these + return PhoneConstants.APN_TYPE_DEFAULT; // TODO - use just one of these case ConnectivityManager.TYPE_MOBILE_MMS: - return Phone.APN_TYPE_MMS; + return PhoneConstants.APN_TYPE_MMS; case ConnectivityManager.TYPE_MOBILE_SUPL: - return Phone.APN_TYPE_SUPL; + return PhoneConstants.APN_TYPE_SUPL; case ConnectivityManager.TYPE_MOBILE_DUN: - return Phone.APN_TYPE_DUN; + return PhoneConstants.APN_TYPE_DUN; case ConnectivityManager.TYPE_MOBILE_HIPRI: - return Phone.APN_TYPE_HIPRI; + return PhoneConstants.APN_TYPE_HIPRI; case ConnectivityManager.TYPE_MOBILE_FOTA: - return Phone.APN_TYPE_FOTA; + return PhoneConstants.APN_TYPE_FOTA; case ConnectivityManager.TYPE_MOBILE_IMS: - return Phone.APN_TYPE_IMS; + return PhoneConstants.APN_TYPE_IMS; case ConnectivityManager.TYPE_MOBILE_CBS: - return Phone.APN_TYPE_CBS; + return PhoneConstants.APN_TYPE_CBS; default: sloge("Error mapping networkType " + netType + " to apnType."); return null; diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 7824724c3214..22b68bc0f9a2 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -18,7 +18,7 @@ package android.provider; import com.android.internal.telephony.CallerInfo; -import com.android.internal.telephony.Connection; +import com.android.internal.telephony.PhoneConstants; import android.content.ContentResolver; import android.content.ContentValues; @@ -267,14 +267,14 @@ public class CallLog { // If this is a private number then set the number to Private, otherwise check // if the number field is empty and set the number to Unavailable - if (presentation == Connection.PRESENTATION_RESTRICTED) { + if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) { number = CallerInfo.PRIVATE_NUMBER; if (ci != null) ci.name = ""; - } else if (presentation == Connection.PRESENTATION_PAYPHONE) { + } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) { number = CallerInfo.PAYPHONE_NUMBER; if (ci != null) ci.name = ""; } else if (TextUtils.isEmpty(number) - || presentation == Connection.PRESENTATION_UNKNOWN) { + || presentation == PhoneConstants.PRESENTATION_UNKNOWN) { number = CallerInfo.UNKNOWN_NUMBER; if (ci != null) ci.name = ""; } diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java deleted file mode 100755 index 19d8d5c9a509..000000000000 --- a/core/java/android/provider/Telephony.java +++ /dev/null @@ -1,2037 +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.provider; - -import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.database.sqlite.SqliteWrapper; -import android.net.Uri; -import android.os.Environment; -import android.telephony.SmsMessage; -import android.text.TextUtils; -import android.util.Log; -import android.util.Patterns; - - -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * The Telephony provider contains data related to phone operation. - * - * @hide - */ -public final class Telephony { - private static final String TAG = "Telephony"; - private static final boolean DEBUG = true; - private static final boolean LOCAL_LOGV = false; - - // Constructor - public Telephony() { - } - - /** - * Base columns for tables that contain text based SMSs. - */ - public interface TextBasedSmsColumns { - /** - * The type of the message - *

Type: INTEGER

- */ - public static final String TYPE = "type"; - - public static final int MESSAGE_TYPE_ALL = 0; - public static final int MESSAGE_TYPE_INBOX = 1; - public static final int MESSAGE_TYPE_SENT = 2; - public static final int MESSAGE_TYPE_DRAFT = 3; - public static final int MESSAGE_TYPE_OUTBOX = 4; - public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages - public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later - - - /** - * The thread ID of the message - *

Type: INTEGER

- */ - public static final String THREAD_ID = "thread_id"; - - /** - * The address of the other party - *

Type: TEXT

- */ - public static final String ADDRESS = "address"; - - /** - * The person ID of the sender - *

Type: INTEGER (long)

- */ - public static final String PERSON_ID = "person"; - - /** - * The date the message was received - *

Type: INTEGER (long)

- */ - public static final String DATE = "date"; - - /** - * The date the message was sent - *

Type: INTEGER (long)

- */ - public static final String DATE_SENT = "date_sent"; - - /** - * Has the message been read - *

Type: INTEGER (boolean)

- */ - public static final String READ = "read"; - - /** - * Indicates whether this message has been seen by the user. The "seen" flag will be - * used to figure out whether we need to throw up a statusbar notification or not. - */ - public static final String SEEN = "seen"; - - /** - * The TP-Status value for the message, or -1 if no status has - * been received - */ - public static final String STATUS = "status"; - - public static final int STATUS_NONE = -1; - public static final int STATUS_COMPLETE = 0; - public static final int STATUS_PENDING = 32; - public static final int STATUS_FAILED = 64; - - /** - * The subject of the message, if present - *

Type: TEXT

- */ - public static final String SUBJECT = "subject"; - - /** - * The body of the message - *

Type: TEXT

- */ - public static final String BODY = "body"; - - /** - * The id of the sender of the conversation, if present - *

Type: INTEGER (reference to item in content://contacts/people)

- */ - public static final String PERSON = "person"; - - /** - * The protocol identifier code - *

Type: INTEGER

- */ - public static final String PROTOCOL = "protocol"; - - /** - * Whether the TP-Reply-Path bit was set on this message - *

Type: BOOLEAN

- */ - public static final String REPLY_PATH_PRESENT = "reply_path_present"; - - /** - * The service center (SC) through which to send the message, if present - *

Type: TEXT

- */ - public static final String SERVICE_CENTER = "service_center"; - - /** - * Has the message been locked? - *

Type: INTEGER (boolean)

- */ - public static final String LOCKED = "locked"; - - /** - * Error code associated with sending or receiving this message - *

Type: INTEGER

- */ - public static final String ERROR_CODE = "error_code"; - - /** - * Meta data used externally. - *

Type: TEXT

- */ - public static final String META_DATA = "meta_data"; -} - - /** - * Contains all text based SMS messages. - */ - public static final class Sms implements BaseColumns, TextBasedSmsColumns { - public static final Cursor query(ContentResolver cr, String[] projection) { - return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER); - } - - public static final Cursor query(ContentResolver cr, String[] projection, - String where, String orderBy) { - return cr.query(CONTENT_URI, projection, where, - null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy); - } - - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * Add an SMS to the given URI. - * - * @param resolver the content resolver to use - * @param uri the URI to add the message to - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @param read true if the message has been read, false if not - * @param deliveryReport true if a delivery report was requested, false if not - * @return the URI for the new message - */ - public static Uri addMessageToUri(ContentResolver resolver, - Uri uri, String address, String body, String subject, - Long date, boolean read, boolean deliveryReport) { - return addMessageToUri(resolver, uri, address, body, subject, - date, read, deliveryReport, -1L); - } - - /** - * Add an SMS to the given URI with thread_id specified. - * - * @param resolver the content resolver to use - * @param uri the URI to add the message to - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @param read true if the message has been read, false if not - * @param deliveryReport true if a delivery report was requested, false if not - * @param threadId the thread_id of the message - * @return the URI for the new message - */ - public static Uri addMessageToUri(ContentResolver resolver, - Uri uri, String address, String body, String subject, - Long date, boolean read, boolean deliveryReport, long threadId) { - ContentValues values = new ContentValues(7); - - values.put(ADDRESS, address); - if (date != null) { - values.put(DATE, date); - } - values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0)); - values.put(SUBJECT, subject); - values.put(BODY, body); - if (deliveryReport) { - values.put(STATUS, STATUS_PENDING); - } - if (threadId != -1L) { - values.put(THREAD_ID, threadId); - } - return resolver.insert(uri, values); - } - - /** - * Move a message to the given folder. - * - * @param context the context to use - * @param uri the message to move - * @param folder the folder to move to - * @return true if the operation succeeded - */ - public static boolean moveMessageToFolder(Context context, - Uri uri, int folder, int error) { - if (uri == null) { - return false; - } - - boolean markAsUnread = false; - boolean markAsRead = false; - switch(folder) { - case MESSAGE_TYPE_INBOX: - case MESSAGE_TYPE_DRAFT: - break; - case MESSAGE_TYPE_OUTBOX: - case MESSAGE_TYPE_SENT: - markAsRead = true; - break; - case MESSAGE_TYPE_FAILED: - case MESSAGE_TYPE_QUEUED: - markAsUnread = true; - break; - default: - return false; - } - - ContentValues values = new ContentValues(3); - - values.put(TYPE, folder); - if (markAsUnread) { - values.put(READ, Integer.valueOf(0)); - } else if (markAsRead) { - values.put(READ, Integer.valueOf(1)); - } - values.put(ERROR_CODE, error); - - return 1 == SqliteWrapper.update(context, context.getContentResolver(), - uri, values, null, null); - } - - /** - * Returns true iff the folder (message type) identifies an - * outgoing message. - */ - public static boolean isOutgoingFolder(int messageType) { - return (messageType == MESSAGE_TYPE_FAILED) - || (messageType == MESSAGE_TYPE_OUTBOX) - || (messageType == MESSAGE_TYPE_SENT) - || (messageType == MESSAGE_TYPE_QUEUED); - } - - /** - * Contains all text based SMS messages in the SMS app's inbox. - */ - public static final class Inbox implements BaseColumns, TextBasedSmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms/inbox"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * Add an SMS to the Draft box. - * - * @param resolver the content resolver to use - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @param read true if the message has been read, false if not - * @return the URI for the new message - */ - public static Uri addMessage(ContentResolver resolver, - String address, String body, String subject, Long date, - boolean read) { - return addMessageToUri(resolver, CONTENT_URI, address, body, - subject, date, read, false); - } - } - - /** - * Contains all sent text based SMS messages in the SMS app's. - */ - public static final class Sent implements BaseColumns, TextBasedSmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms/sent"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * Add an SMS to the Draft box. - * - * @param resolver the content resolver to use - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @return the URI for the new message - */ - public static Uri addMessage(ContentResolver resolver, - String address, String body, String subject, Long date) { - return addMessageToUri(resolver, CONTENT_URI, address, body, - subject, date, true, false); - } - } - - /** - * Contains all sent text based SMS messages in the SMS app's. - */ - public static final class Draft implements BaseColumns, TextBasedSmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms/draft"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * Add an SMS to the Draft box. - * - * @param resolver the content resolver to use - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @return the URI for the new message - */ - public static Uri addMessage(ContentResolver resolver, - String address, String body, String subject, Long date) { - return addMessageToUri(resolver, CONTENT_URI, address, body, - subject, date, true, false); - } - - /** - * Save over an existing draft message. - * - * @param resolver the content resolver to use - * @param uri of existing message - * @param body the new body for the draft message - * @return true is successful, false otherwise - */ - public static boolean saveMessage(ContentResolver resolver, - Uri uri, String body) { - ContentValues values = new ContentValues(2); - values.put(BODY, body); - values.put(DATE, System.currentTimeMillis()); - return resolver.update(uri, values, null, null) == 1; - } - } - - /** - * Contains all pending outgoing text based SMS messages. - */ - public static final class Outbox implements BaseColumns, TextBasedSmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms/outbox"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * Add an SMS to the Out box. - * - * @param resolver the content resolver to use - * @param address the address of the sender - * @param body the body of the message - * @param subject the psuedo-subject of the message - * @param date the timestamp for the message - * @param deliveryReport whether a delivery report was requested for the message - * @return the URI for the new message - */ - public static Uri addMessage(ContentResolver resolver, - String address, String body, String subject, Long date, - boolean deliveryReport, long threadId) { - return addMessageToUri(resolver, CONTENT_URI, address, body, - subject, date, true, deliveryReport, threadId); - } - } - - /** - * Contains all sent text-based SMS messages in the SMS app's. - */ - public static final class Conversations - implements BaseColumns, TextBasedSmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://sms/conversations"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * The first 45 characters of the body of the message - *

Type: TEXT

- */ - public static final String SNIPPET = "snippet"; - - /** - * The number of messages in the conversation - *

Type: INTEGER

- */ - public static final String MESSAGE_COUNT = "msg_count"; - } - - /** - * Contains info about SMS related Intents that are broadcast. - */ - public static final class Intents { - /** - * Set by BroadcastReceiver. Indicates the message was handled - * successfully. - */ - public static final int RESULT_SMS_HANDLED = 1; - - /** - * Set by BroadcastReceiver. Indicates a generic error while - * processing the message. - */ - public static final int RESULT_SMS_GENERIC_ERROR = 2; - - /** - * Set by BroadcastReceiver. Indicates insufficient memory to store - * the message. - */ - public static final int RESULT_SMS_OUT_OF_MEMORY = 3; - - /** - * Set by BroadcastReceiver. Indicates the message, while - * possibly valid, is of a format or encoding that is not - * supported. - */ - public static final int RESULT_SMS_UNSUPPORTED = 4; - - /** - * Broadcast Action: A new text based SMS message has been received - * by the device. The intent will have the following extra - * values:

- * - * - * - *

The extra values can be extracted using - * {@link #getMessagesFromIntent(Intent)}.

- * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_RECEIVED_ACTION = - "android.provider.Telephony.SMS_RECEIVED"; - - /** - * Broadcast Action: A new data based SMS message has been received - * by the device. The intent will have the following extra - * values:

- * - * - * - *

The extra values can be extracted using - * {@link #getMessagesFromIntent(Intent)}.

- * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String DATA_SMS_RECEIVED_ACTION = - "android.intent.action.DATA_SMS_RECEIVED"; - - /** - * Broadcast Action: A new WAP PUSH message has been received by the - * device. The intent will have the following extra - * values:

- * - * - * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- * - *

The contentTypeParameters extra value is map of content parameters keyed by - * their names.

- * - *

If any unassigned well-known parameters are encountered, the key of the map will - * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter. If - * a parameter has No-Value the value in the map will be null.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String WAP_PUSH_RECEIVED_ACTION = - "android.provider.Telephony.WAP_PUSH_RECEIVED"; - - /** - * Broadcast Action: A new Cell Broadcast message has been received - * by the device. The intent will have the following extra - * values:

- * - * - * - *

The extra values can be extracted using - * {@link #getMessagesFromIntent(Intent)}.

- * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_CB_RECEIVED_ACTION = - "android.provider.Telephony.SMS_CB_RECEIVED"; - - /** - * Broadcast Action: A new Emergency Broadcast message has been received - * by the device. The intent will have the following extra - * values:

- * - * - * - *

The extra values can be extracted using - * {@link #getMessagesFromIntent(Intent)}.

- * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION = - "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED"; - - /** - * Broadcast Action: A new CDMA SMS has been received containing Service Category - * Program Data (updates the list of enabled broadcast channels). The intent will - * have the following extra values:

- * - * - * - *

The extra values can be extracted using - * {@link #getMessagesFromIntent(Intent)}.

- * - *

If a BroadcastReceiver encounters an error while processing - * this intent it should set the result code appropriately.

- */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION = - "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED"; - - /** - * Broadcast Action: The SIM storage for SMS messages is full. If - * space is not freed, messages targeted for the SIM (class 2) may - * not be saved. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SIM_FULL_ACTION = - "android.provider.Telephony.SIM_FULL"; - - /** - * Broadcast Action: An incoming SMS has been rejected by the - * telephony framework. This intent is sent in lieu of any - * of the RECEIVED_ACTION intents. The intent will have the - * following extra value:

- * - * - - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_REJECTED_ACTION = - "android.provider.Telephony.SMS_REJECTED"; - - /** - * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a - * {@link #DATA_SMS_RECEIVED_ACTION} intent. - * - * @param intent the intent to read from - * @return an array of SmsMessages for the PDUs - */ - public static SmsMessage[] getMessagesFromIntent( - Intent intent) { - Object[] messages = (Object[]) intent.getSerializableExtra("pdus"); - String format = intent.getStringExtra("format"); - byte[][] pduObjs = new byte[messages.length][]; - - for (int i = 0; i < messages.length; i++) { - pduObjs[i] = (byte[]) messages[i]; - } - byte[][] pdus = new byte[pduObjs.length][]; - int pduCount = pdus.length; - SmsMessage[] msgs = new SmsMessage[pduCount]; - for (int i = 0; i < pduCount; i++) { - pdus[i] = pduObjs[i]; - msgs[i] = SmsMessage.createFromPdu(pdus[i], format); - } - return msgs; - } - } - } - - /** - * Base columns for tables that contain MMSs. - */ - public interface BaseMmsColumns extends BaseColumns { - - public static final int MESSAGE_BOX_ALL = 0; - public static final int MESSAGE_BOX_INBOX = 1; - public static final int MESSAGE_BOX_SENT = 2; - public static final int MESSAGE_BOX_DRAFTS = 3; - public static final int MESSAGE_BOX_OUTBOX = 4; - - /** - * The date the message was received. - *

Type: INTEGER (long)

- */ - public static final String DATE = "date"; - - /** - * The date the message was sent. - *

Type: INTEGER (long)

- */ - public static final String DATE_SENT = "date_sent"; - - /** - * The box which the message belong to, for example, MESSAGE_BOX_INBOX. - *

Type: INTEGER

- */ - public static final String MESSAGE_BOX = "msg_box"; - - /** - * Has the message been read. - *

Type: INTEGER (boolean)

- */ - public static final String READ = "read"; - - /** - * Indicates whether this message has been seen by the user. The "seen" flag will be - * used to figure out whether we need to throw up a statusbar notification or not. - */ - public static final String SEEN = "seen"; - - /** - * The Message-ID of the message. - *

Type: TEXT

- */ - public static final String MESSAGE_ID = "m_id"; - - /** - * The subject of the message, if present. - *

Type: TEXT

- */ - public static final String SUBJECT = "sub"; - - /** - * The character set of the subject, if present. - *

Type: INTEGER

- */ - public static final String SUBJECT_CHARSET = "sub_cs"; - - /** - * The Content-Type of the message. - *

Type: TEXT

- */ - public static final String CONTENT_TYPE = "ct_t"; - - /** - * The Content-Location of the message. - *

Type: TEXT

- */ - public static final String CONTENT_LOCATION = "ct_l"; - - /** - * The address of the sender. - *

Type: TEXT

- */ - public static final String FROM = "from"; - - /** - * The address of the recipients. - *

Type: TEXT

- */ - public static final String TO = "to"; - - /** - * The address of the cc. recipients. - *

Type: TEXT

- */ - public static final String CC = "cc"; - - /** - * The address of the bcc. recipients. - *

Type: TEXT

- */ - public static final String BCC = "bcc"; - - /** - * The expiry time of the message. - *

Type: INTEGER

- */ - public static final String EXPIRY = "exp"; - - /** - * The class of the message. - *

Type: TEXT

- */ - public static final String MESSAGE_CLASS = "m_cls"; - - /** - * The type of the message defined by MMS spec. - *

Type: INTEGER

- */ - public static final String MESSAGE_TYPE = "m_type"; - - /** - * The version of specification that this message conform. - *

Type: INTEGER

- */ - public static final String MMS_VERSION = "v"; - - /** - * The size of the message. - *

Type: INTEGER

- */ - public static final String MESSAGE_SIZE = "m_size"; - - /** - * The priority of the message. - *

Type: TEXT

- */ - public static final String PRIORITY = "pri"; - - /** - * The read-report of the message. - *

Type: TEXT

- */ - public static final String READ_REPORT = "rr"; - - /** - * Whether the report is allowed. - *

Type: TEXT

- */ - public static final String REPORT_ALLOWED = "rpt_a"; - - /** - * The response-status of the message. - *

Type: INTEGER

- */ - public static final String RESPONSE_STATUS = "resp_st"; - - /** - * The status of the message. - *

Type: INTEGER

- */ - public static final String STATUS = "st"; - - /** - * The transaction-id of the message. - *

Type: TEXT

- */ - public static final String TRANSACTION_ID = "tr_id"; - - /** - * The retrieve-status of the message. - *

Type: INTEGER

- */ - public static final String RETRIEVE_STATUS = "retr_st"; - - /** - * The retrieve-text of the message. - *

Type: TEXT

- */ - public static final String RETRIEVE_TEXT = "retr_txt"; - - /** - * The character set of the retrieve-text. - *

Type: TEXT

- */ - public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs"; - - /** - * The read-status of the message. - *

Type: INTEGER

- */ - public static final String READ_STATUS = "read_status"; - - /** - * The content-class of the message. - *

Type: INTEGER

- */ - public static final String CONTENT_CLASS = "ct_cls"; - - /** - * The delivery-report of the message. - *

Type: INTEGER

- */ - public static final String DELIVERY_REPORT = "d_rpt"; - - /** - * The delivery-time-token of the message. - *

Type: INTEGER

- */ - public static final String DELIVERY_TIME_TOKEN = "d_tm_tok"; - - /** - * The delivery-time of the message. - *

Type: INTEGER

- */ - public static final String DELIVERY_TIME = "d_tm"; - - /** - * The response-text of the message. - *

Type: TEXT

- */ - public static final String RESPONSE_TEXT = "resp_txt"; - - /** - * The sender-visibility of the message. - *

Type: TEXT

- */ - public static final String SENDER_VISIBILITY = "s_vis"; - - /** - * The reply-charging of the message. - *

Type: INTEGER

- */ - public static final String REPLY_CHARGING = "r_chg"; - - /** - * The reply-charging-deadline-token of the message. - *

Type: INTEGER

- */ - public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok"; - - /** - * The reply-charging-deadline of the message. - *

Type: INTEGER

- */ - public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl"; - - /** - * The reply-charging-id of the message. - *

Type: TEXT

- */ - public static final String REPLY_CHARGING_ID = "r_chg_id"; - - /** - * The reply-charging-size of the message. - *

Type: INTEGER

- */ - public static final String REPLY_CHARGING_SIZE = "r_chg_sz"; - - /** - * The previously-sent-by of the message. - *

Type: TEXT

- */ - public static final String PREVIOUSLY_SENT_BY = "p_s_by"; - - /** - * The previously-sent-date of the message. - *

Type: INTEGER

- */ - public static final String PREVIOUSLY_SENT_DATE = "p_s_d"; - - /** - * The store of the message. - *

Type: TEXT

- */ - public static final String STORE = "store"; - - /** - * The mm-state of the message. - *

Type: INTEGER

- */ - public static final String MM_STATE = "mm_st"; - - /** - * The mm-flags-token of the message. - *

Type: INTEGER

- */ - public static final String MM_FLAGS_TOKEN = "mm_flg_tok"; - - /** - * The mm-flags of the message. - *

Type: TEXT

- */ - public static final String MM_FLAGS = "mm_flg"; - - /** - * The store-status of the message. - *

Type: TEXT

- */ - public static final String STORE_STATUS = "store_st"; - - /** - * The store-status-text of the message. - *

Type: TEXT

- */ - public static final String STORE_STATUS_TEXT = "store_st_txt"; - - /** - * The stored of the message. - *

Type: TEXT

- */ - public static final String STORED = "stored"; - - /** - * The totals of the message. - *

Type: TEXT

- */ - public static final String TOTALS = "totals"; - - /** - * The mbox-totals of the message. - *

Type: TEXT

- */ - public static final String MBOX_TOTALS = "mb_t"; - - /** - * The mbox-totals-token of the message. - *

Type: INTEGER

- */ - public static final String MBOX_TOTALS_TOKEN = "mb_t_tok"; - - /** - * The quotas of the message. - *

Type: TEXT

- */ - public static final String QUOTAS = "qt"; - - /** - * The mbox-quotas of the message. - *

Type: TEXT

- */ - public static final String MBOX_QUOTAS = "mb_qt"; - - /** - * The mbox-quotas-token of the message. - *

Type: INTEGER

- */ - public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok"; - - /** - * The message-count of the message. - *

Type: INTEGER

- */ - public static final String MESSAGE_COUNT = "m_cnt"; - - /** - * The start of the message. - *

Type: INTEGER

- */ - public static final String START = "start"; - - /** - * The distribution-indicator of the message. - *

Type: TEXT

- */ - public static final String DISTRIBUTION_INDICATOR = "d_ind"; - - /** - * The element-descriptor of the message. - *

Type: TEXT

- */ - public static final String ELEMENT_DESCRIPTOR = "e_des"; - - /** - * The limit of the message. - *

Type: INTEGER

- */ - public static final String LIMIT = "limit"; - - /** - * The recommended-retrieval-mode of the message. - *

Type: INTEGER

- */ - public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod"; - - /** - * The recommended-retrieval-mode-text of the message. - *

Type: TEXT

- */ - public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt"; - - /** - * The status-text of the message. - *

Type: TEXT

- */ - public static final String STATUS_TEXT = "st_txt"; - - /** - * The applic-id of the message. - *

Type: TEXT

- */ - public static final String APPLIC_ID = "apl_id"; - - /** - * The reply-applic-id of the message. - *

Type: TEXT

- */ - public static final String REPLY_APPLIC_ID = "r_apl_id"; - - /** - * The aux-applic-id of the message. - *

Type: TEXT

- */ - public static final String AUX_APPLIC_ID = "aux_apl_id"; - - /** - * The drm-content of the message. - *

Type: TEXT

- */ - public static final String DRM_CONTENT = "drm_c"; - - /** - * The adaptation-allowed of the message. - *

Type: TEXT

- */ - public static final String ADAPTATION_ALLOWED = "adp_a"; - - /** - * The replace-id of the message. - *

Type: TEXT

- */ - public static final String REPLACE_ID = "repl_id"; - - /** - * The cancel-id of the message. - *

Type: TEXT

- */ - public static final String CANCEL_ID = "cl_id"; - - /** - * The cancel-status of the message. - *

Type: INTEGER

- */ - public static final String CANCEL_STATUS = "cl_st"; - - /** - * The thread ID of the message - *

Type: INTEGER

- */ - public static final String THREAD_ID = "thread_id"; - - /** - * Has the message been locked? - *

Type: INTEGER (boolean)

- */ - public static final String LOCKED = "locked"; - - /** - * Meta data used externally. - *

Type: TEXT

- */ - public static final String META_DATA = "meta_data"; - } - - /** - * Columns for the "canonical_addresses" table used by MMS and - * SMS." - */ - public interface CanonicalAddressesColumns extends BaseColumns { - /** - * An address used in MMS or SMS. Email addresses are - * converted to lower case and are compared by string - * equality. Other addresses are compared using - * PHONE_NUMBERS_EQUAL. - *

Type: TEXT

- */ - public static final String ADDRESS = "address"; - } - - /** - * Columns for the "threads" table used by MMS and SMS. - */ - public interface ThreadsColumns extends BaseColumns { - /** - * The date at which the thread was created. - * - *

Type: INTEGER (long)

- */ - public static final String DATE = "date"; - - /** - * A string encoding of the recipient IDs of the recipients of - * the message, in numerical order and separated by spaces. - *

Type: TEXT

- */ - public static final String RECIPIENT_IDS = "recipient_ids"; - - /** - * The message count of the thread. - *

Type: INTEGER

- */ - public static final String MESSAGE_COUNT = "message_count"; - /** - * Indicates whether all messages of the thread have been read. - *

Type: INTEGER

- */ - public static final String READ = "read"; - - /** - * The snippet of the latest message in the thread. - *

Type: TEXT

- */ - public static final String SNIPPET = "snippet"; - /** - * The charset of the snippet. - *

Type: INTEGER

- */ - public static final String SNIPPET_CHARSET = "snippet_cs"; - /** - * Type of the thread, either Threads.COMMON_THREAD or - * Threads.BROADCAST_THREAD. - *

Type: INTEGER

- */ - public static final String TYPE = "type"; - /** - * Indicates whether there is a transmission error in the thread. - *

Type: INTEGER

- */ - public static final String ERROR = "error"; - /** - * Indicates whether this thread contains any attachments. - *

Type: INTEGER

- */ - public static final String HAS_ATTACHMENT = "has_attachment"; - } - - /** - * Helper functions for the "threads" table used by MMS and SMS. - */ - public static final class Threads implements ThreadsColumns { - private static final String[] ID_PROJECTION = { BaseColumns._ID }; - private static final String STANDARD_ENCODING = "UTF-8"; - private static final Uri THREAD_ID_CONTENT_URI = Uri.parse( - "content://mms-sms/threadID"); - public static final Uri CONTENT_URI = Uri.withAppendedPath( - MmsSms.CONTENT_URI, "conversations"); - public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath( - CONTENT_URI, "obsolete"); - - public static final int COMMON_THREAD = 0; - public static final int BROADCAST_THREAD = 1; - - // No one should construct an instance of this class. - private Threads() { - } - - /** - * This is a single-recipient version of - * getOrCreateThreadId. It's convenient for use with SMS - * messages. - */ - public static long getOrCreateThreadId(Context context, String recipient) { - Set recipients = new HashSet(); - - recipients.add(recipient); - return getOrCreateThreadId(context, recipients); - } - - /** - * Given the recipients list and subject of an unsaved message, - * return its thread ID. If the message starts a new thread, - * allocate a new thread ID. Otherwise, use the appropriate - * existing thread ID. - * - * Find the thread ID of the same set of recipients (in - * any order, without any additions). If one - * is found, return it. Otherwise, return a unique thread ID. - */ - public static long getOrCreateThreadId( - Context context, Set recipients) { - Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon(); - - for (String recipient : recipients) { - if (Mms.isEmailAddress(recipient)) { - recipient = Mms.extractAddrSpec(recipient); - } - - uriBuilder.appendQueryParameter("recipient", recipient); - } - - Uri uri = uriBuilder.build(); - //if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri); - - Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(), - uri, ID_PROJECTION, null, null, null); - if (cursor != null) { - try { - if (cursor.moveToFirst()) { - return cursor.getLong(0); - } else { - Log.e(TAG, "getOrCreateThreadId returned no rows!"); - } - } finally { - cursor.close(); - } - } - - Log.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString()); - throw new IllegalArgumentException("Unable to find or allocate a thread ID."); - } - } - - /** - * Contains all MMS messages. - */ - public static final class Mms implements BaseMmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = Uri.parse("content://mms"); - - public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath( - CONTENT_URI, "report-request"); - - public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath( - CONTENT_URI, "report-status"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - - /** - * mailbox = name-addr - * name-addr = [display-name] angle-addr - * angle-addr = [CFWS] "<" addr-spec ">" [CFWS] - */ - public static final Pattern NAME_ADDR_EMAIL_PATTERN = - Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*"); - - /** - * quoted-string = [CFWS] - * DQUOTE *([FWS] qcontent) [FWS] DQUOTE - * [CFWS] - */ - public static final Pattern QUOTED_STRING_PATTERN = - Pattern.compile("\\s*\"([^\"]*)\"\\s*"); - - public static final Cursor query( - ContentResolver cr, String[] projection) { - return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER); - } - - public static final Cursor query( - ContentResolver cr, String[] projection, - String where, String orderBy) { - return cr.query(CONTENT_URI, projection, - where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy); - } - - public static final String getMessageBoxName(int msgBox) { - switch (msgBox) { - case MESSAGE_BOX_ALL: - return "all"; - case MESSAGE_BOX_INBOX: - return "inbox"; - case MESSAGE_BOX_SENT: - return "sent"; - case MESSAGE_BOX_DRAFTS: - return "drafts"; - case MESSAGE_BOX_OUTBOX: - return "outbox"; - default: - throw new IllegalArgumentException("Invalid message box: " + msgBox); - } - } - - public static String extractAddrSpec(String address) { - Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address); - - if (match.matches()) { - return match.group(2); - } - return address; - } - - /** - * Returns true if the address is an email address - * - * @param address the input address to be tested - * @return true if address is an email address - */ - public static boolean isEmailAddress(String address) { - if (TextUtils.isEmpty(address)) { - return false; - } - - String s = extractAddrSpec(address); - Matcher match = Patterns.EMAIL_ADDRESS.matcher(s); - return match.matches(); - } - - /** - * Returns true if the number is a Phone number - * - * @param number the input number to be tested - * @return true if number is a Phone number - */ - public static boolean isPhoneNumber(String number) { - if (TextUtils.isEmpty(number)) { - return false; - } - - Matcher match = Patterns.PHONE.matcher(number); - return match.matches(); - } - - /** - * Contains all MMS messages in the MMS app's inbox. - */ - public static final class Inbox implements BaseMmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri - CONTENT_URI = Uri.parse("content://mms/inbox"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - } - - /** - * Contains all MMS messages in the MMS app's sent box. - */ - public static final class Sent implements BaseMmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri - CONTENT_URI = Uri.parse("content://mms/sent"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - } - - /** - * Contains all MMS messages in the MMS app's drafts box. - */ - public static final class Draft implements BaseMmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri - CONTENT_URI = Uri.parse("content://mms/drafts"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - } - - /** - * Contains all MMS messages in the MMS app's outbox. - */ - public static final class Outbox implements BaseMmsColumns { - /** - * The content:// style URL for this table - */ - public static final Uri - CONTENT_URI = Uri.parse("content://mms/outbox"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "date DESC"; - } - - public static final class Addr implements BaseColumns { - /** - * The ID of MM which this address entry belongs to. - */ - public static final String MSG_ID = "msg_id"; - - /** - * The ID of contact entry in Phone Book. - */ - public static final String CONTACT_ID = "contact_id"; - - /** - * The address text. - */ - public static final String ADDRESS = "address"; - - /** - * Type of address, must be one of PduHeaders.BCC, - * PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO. - */ - public static final String TYPE = "type"; - - /** - * Character set of this entry. - */ - public static final String CHARSET = "charset"; - } - - public static final class Part implements BaseColumns { - /** - * The identifier of the message which this part belongs to. - *

Type: INTEGER

- */ - public static final String MSG_ID = "mid"; - - /** - * The order of the part. - *

Type: INTEGER

- */ - public static final String SEQ = "seq"; - - /** - * The content type of the part. - *

Type: TEXT

- */ - public static final String CONTENT_TYPE = "ct"; - - /** - * The name of the part. - *

Type: TEXT

- */ - public static final String NAME = "name"; - - /** - * The charset of the part. - *

Type: TEXT

- */ - public static final String CHARSET = "chset"; - - /** - * The file name of the part. - *

Type: TEXT

- */ - public static final String FILENAME = "fn"; - - /** - * The content disposition of the part. - *

Type: TEXT

- */ - public static final String CONTENT_DISPOSITION = "cd"; - - /** - * The content ID of the part. - *

Type: INTEGER

- */ - public static final String CONTENT_ID = "cid"; - - /** - * The content location of the part. - *

Type: INTEGER

- */ - public static final String CONTENT_LOCATION = "cl"; - - /** - * The start of content-type of the message. - *

Type: INTEGER

- */ - public static final String CT_START = "ctt_s"; - - /** - * The type of content-type of the message. - *

Type: TEXT

- */ - public static final String CT_TYPE = "ctt_t"; - - /** - * The location(on filesystem) of the binary data of the part. - *

Type: INTEGER

- */ - public static final String _DATA = "_data"; - - public static final String TEXT = "text"; - - } - - public static final class Rate { - public static final Uri CONTENT_URI = Uri.withAppendedPath( - Mms.CONTENT_URI, "rate"); - /** - * When a message was successfully sent. - *

Type: INTEGER

- */ - public static final String SENT_TIME = "sent_time"; - } - - public static final class Intents { - private Intents() { - // Non-instantiatable. - } - - /** - * The extra field to store the contents of the Intent, - * which should be an array of Uri. - */ - public static final String EXTRA_CONTENTS = "contents"; - /** - * The extra field to store the type of the contents, - * which should be an array of String. - */ - public static final String EXTRA_TYPES = "types"; - /** - * The extra field to store the 'Cc' addresses. - */ - public static final String EXTRA_CC = "cc"; - /** - * The extra field to store the 'Bcc' addresses; - */ - public static final String EXTRA_BCC = "bcc"; - /** - * The extra field to store the 'Subject'. - */ - public static final String EXTRA_SUBJECT = "subject"; - /** - * Indicates that the contents of specified URIs were changed. - * The application which is showing or caching these contents - * should be updated. - */ - public static final String - CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED"; - /** - * An extra field which stores the URI of deleted contents. - */ - public static final String DELETED_CONTENTS = "deleted_contents"; - } - } - - /** - * Contains all MMS and SMS messages. - */ - public static final class MmsSms implements BaseColumns { - /** - * The column to distinguish SMS & MMS messages in query results. - */ - public static final String TYPE_DISCRIMINATOR_COLUMN = - "transport_type"; - - public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/"); - - public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse( - "content://mms-sms/conversations"); - - public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse( - "content://mms-sms/messages/byphone"); - - public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse( - "content://mms-sms/undelivered"); - - public static final Uri CONTENT_DRAFT_URI = Uri.parse( - "content://mms-sms/draft"); - - public static final Uri CONTENT_LOCKED_URI = Uri.parse( - "content://mms-sms/locked"); - - /*** - * Pass in a query parameter called "pattern" which is the text - * to search for. - * The sort order is fixed to be thread_id ASC,date DESC. - */ - public static final Uri SEARCH_URI = Uri.parse( - "content://mms-sms/search"); - - // Constants for message protocol types. - public static final int SMS_PROTO = 0; - public static final int MMS_PROTO = 1; - - // Constants for error types of pending messages. - public static final int NO_ERROR = 0; - public static final int ERR_TYPE_GENERIC = 1; - public static final int ERR_TYPE_SMS_PROTO_TRANSIENT = 2; - public static final int ERR_TYPE_MMS_PROTO_TRANSIENT = 3; - public static final int ERR_TYPE_TRANSPORT_FAILURE = 4; - public static final int ERR_TYPE_GENERIC_PERMANENT = 10; - public static final int ERR_TYPE_SMS_PROTO_PERMANENT = 11; - public static final int ERR_TYPE_MMS_PROTO_PERMANENT = 12; - - public static final class PendingMessages implements BaseColumns { - public static final Uri CONTENT_URI = Uri.withAppendedPath( - MmsSms.CONTENT_URI, "pending"); - /** - * The type of transport protocol(MMS or SMS). - *

Type: INTEGER

- */ - public static final String PROTO_TYPE = "proto_type"; - /** - * The ID of the message to be sent or downloaded. - *

Type: INTEGER

- */ - public static final String MSG_ID = "msg_id"; - /** - * The type of the message to be sent or downloaded. - * This field is only valid for MM. For SM, its value is always - * set to 0. - */ - public static final String MSG_TYPE = "msg_type"; - /** - * The type of the error code. - *

Type: INTEGER

- */ - public static final String ERROR_TYPE = "err_type"; - /** - * The error code of sending/retrieving process. - *

Type: INTEGER

- */ - public static final String ERROR_CODE = "err_code"; - /** - * How many times we tried to send or download the message. - *

Type: INTEGER

- */ - public static final String RETRY_INDEX = "retry_index"; - /** - * The time to do next retry. - */ - public static final String DUE_TIME = "due_time"; - /** - * The time we last tried to send or download the message. - */ - public static final String LAST_TRY = "last_try"; - } - - public static final class WordsTable { - public static final String ID = "_id"; - public static final String SOURCE_ROW_ID = "source_id"; - public static final String TABLE_ID = "table_to_use"; - public static final String INDEXED_TEXT = "index_text"; - } - } - - public static final class Carriers implements BaseColumns { - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://telephony/carriers"); - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = "name ASC"; - - public static final String NAME = "name"; - - public static final String APN = "apn"; - - public static final String PROXY = "proxy"; - - public static final String PORT = "port"; - - public static final String MMSPROXY = "mmsproxy"; - - public static final String MMSPORT = "mmsport"; - - public static final String SERVER = "server"; - - public static final String USER = "user"; - - public static final String PASSWORD = "password"; - - public static final String MMSC = "mmsc"; - - public static final String MCC = "mcc"; - - public static final String MNC = "mnc"; - - public static final String NUMERIC = "numeric"; - - public static final String AUTH_TYPE = "authtype"; - - public static final String TYPE = "type"; - - public static final String INACTIVE_TIMER = "inactivetimer"; - - // Only if enabled try Data Connection. - public static final String ENABLED = "enabled"; - - // Rules apply based on class. - public static final String CLASS = "class"; - - /** - * The protocol to be used to connect to this APN. - * - * One of the PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - */ - public static final String PROTOCOL = "protocol"; - - /** - * The protocol to be used to connect to this APN when roaming. - * - * The syntax is the same as protocol. - */ - public static final String ROAMING_PROTOCOL = "roaming_protocol"; - - public static final String CURRENT = "current"; - - /** - * Current status of APN - * true : enabled APN, false : disabled APN. - */ - public static final String CARRIER_ENABLED = "carrier_enabled"; - - /** - * Radio Access Technology info - * To check what values can hold, refer to ServiceState.java. - * This should be spread to other technologies, - * but currently only used for LTE(14) and EHRPD(13). - */ - public static final String BEARER = "bearer"; - } - - /** - * Contains received SMS cell broadcast messages. - */ - public static final class CellBroadcasts implements BaseColumns { - - /** Not instantiable. */ - private CellBroadcasts() {} - - /** - * The content:// style URL for this table - */ - public static final Uri CONTENT_URI = - Uri.parse("content://cellbroadcasts"); - - /** - * Message geographical scope. - *

Type: INTEGER

- */ - public static final String GEOGRAPHICAL_SCOPE = "geo_scope"; - - /** - * Message serial number. - *

Type: INTEGER

- */ - public static final String SERIAL_NUMBER = "serial_number"; - - /** - * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a - * broadcast for duplicate detection purposes. - *

Type: TEXT

- */ - public static final String PLMN = "plmn"; - - /** - * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA. - * Only included if Geographical Scope of message is not PLMN wide (01). - *

Type: INTEGER

- */ - public static final String LAC = "lac"; - - /** - * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the - * Geographical Scope of message is cell wide (00 or 11). - *

Type: INTEGER

- */ - public static final String CID = "cid"; - - /** - * Message code (OBSOLETE: merged into SERIAL_NUMBER). - *

Type: INTEGER

- */ - public static final String V1_MESSAGE_CODE = "message_code"; - - /** - * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY). - *

Type: INTEGER

- */ - public static final String V1_MESSAGE_IDENTIFIER = "message_id"; - - /** - * Service category (GSM/UMTS message identifier, CDMA service category). - *

Type: INTEGER

- */ - public static final String SERVICE_CATEGORY = "service_category"; - - /** - * Message language code. - *

Type: TEXT

- */ - public static final String LANGUAGE_CODE = "language"; - - /** - * Message body. - *

Type: TEXT

- */ - public static final String MESSAGE_BODY = "body"; - - /** - * Message delivery time. - *

Type: INTEGER (long)

- */ - public static final String DELIVERY_TIME = "date"; - - /** - * Has the message been viewed? - *

Type: INTEGER (boolean)

- */ - public static final String MESSAGE_READ = "read"; - - /** - * Message format (3GPP or 3GPP2). - *

Type: INTEGER

- */ - public static final String MESSAGE_FORMAT = "format"; - - /** - * Message priority (including emergency). - *

Type: INTEGER

- */ - public static final String MESSAGE_PRIORITY = "priority"; - - /** - * ETWS warning type (ETWS alerts only). - *

Type: INTEGER

- */ - public static final String ETWS_WARNING_TYPE = "etws_warning_type"; - - /** - * CMAS message class (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_MESSAGE_CLASS = "cmas_message_class"; - - /** - * CMAS category (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_CATEGORY = "cmas_category"; - - /** - * CMAS response type (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_RESPONSE_TYPE = "cmas_response_type"; - - /** - * CMAS severity (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_SEVERITY = "cmas_severity"; - - /** - * CMAS urgency (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_URGENCY = "cmas_urgency"; - - /** - * CMAS certainty (CMAS alerts only). - *

Type: INTEGER

- */ - public static final String CMAS_CERTAINTY = "cmas_certainty"; - - /** - * The default sort order for this table - */ - public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC"; - - /** - * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects. - */ - public static final String[] QUERY_COLUMNS = { - _ID, - GEOGRAPHICAL_SCOPE, - PLMN, - LAC, - CID, - SERIAL_NUMBER, - SERVICE_CATEGORY, - LANGUAGE_CODE, - MESSAGE_BODY, - DELIVERY_TIME, - MESSAGE_READ, - MESSAGE_FORMAT, - MESSAGE_PRIORITY, - ETWS_WARNING_TYPE, - CMAS_MESSAGE_CLASS, - CMAS_CATEGORY, - CMAS_RESPONSE_TYPE, - CMAS_SEVERITY, - CMAS_URGENCY, - CMAS_CERTAINTY - }; - } - - public static final class Intents { - private Intents() { - // Not instantiable - } - - /** - * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are - * of the form *#*##*#*. The intent will have the data URI:

- * - *

android_secret_code://<code>

- */ - public static final String SECRET_CODE_ACTION = - "android.provider.Telephony.SECRET_CODE"; - - /** - * Broadcast Action: The Service Provider string(s) have been updated. Activities or - * services that use these strings should update their display. - * The intent will have the following extra values:

- *
    - *
  • showPlmn - Boolean that indicates whether the PLMN should be shown.
  • - *
  • plmn - The operator name of the registered network, as a string.
  • - *
  • showSpn - Boolean that indicates whether the SPN should be shown.
  • - *
  • spn - The service provider name, as a string.
  • - *
- * Note that showPlmn may indicate that plmn should be displayed, even - * though the value for plmn is null. This can happen, for example, if the phone - * has not registered to a network yet. In this case the receiver may substitute an - * appropriate placeholder string (eg, "No service"). - * - * It is recommended to display plmn before / above spn if - * both are displayed. - * - *

Note this is a protected intent that can only be sent - * by the system. - */ - public static final String SPN_STRINGS_UPDATED_ACTION = - "android.provider.Telephony.SPN_STRINGS_UPDATED"; - - public static final String EXTRA_SHOW_PLMN = "showPlmn"; - public static final String EXTRA_PLMN = "plmn"; - public static final String EXTRA_SHOW_SPN = "showSpn"; - public static final String EXTRA_SPN = "spn"; - } -} diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java deleted file mode 100644 index 12a134399c33..000000000000 --- a/core/java/com/google/android/mms/ContentType.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms; - -import java.util.ArrayList; - -public class ContentType { - public static final String MMS_MESSAGE = "application/vnd.wap.mms-message"; - // The phony content type for generic PDUs (e.g. ReadOrig.ind, - // Notification.ind, Delivery.ind). - public static final String MMS_GENERIC = "application/vnd.wap.mms-generic"; - public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed"; - public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related"; - public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative"; - - public static final String TEXT_PLAIN = "text/plain"; - public static final String TEXT_HTML = "text/html"; - public static final String TEXT_VCALENDAR = "text/x-vCalendar"; - public static final String TEXT_VCARD = "text/x-vCard"; - - public static final String IMAGE_UNSPECIFIED = "image/*"; - public static final String IMAGE_JPEG = "image/jpeg"; - public static final String IMAGE_JPG = "image/jpg"; - public static final String IMAGE_GIF = "image/gif"; - public static final String IMAGE_WBMP = "image/vnd.wap.wbmp"; - public static final String IMAGE_PNG = "image/png"; - public static final String IMAGE_X_MS_BMP = "image/x-ms-bmp"; - - public static final String AUDIO_UNSPECIFIED = "audio/*"; - public static final String AUDIO_AAC = "audio/aac"; - public static final String AUDIO_AMR = "audio/amr"; - public static final String AUDIO_IMELODY = "audio/imelody"; - public static final String AUDIO_MID = "audio/mid"; - public static final String AUDIO_MIDI = "audio/midi"; - public static final String AUDIO_MP3 = "audio/mp3"; - public static final String AUDIO_MPEG3 = "audio/mpeg3"; - public static final String AUDIO_MPEG = "audio/mpeg"; - public static final String AUDIO_MPG = "audio/mpg"; - public static final String AUDIO_MP4 = "audio/mp4"; - public static final String AUDIO_X_MID = "audio/x-mid"; - public static final String AUDIO_X_MIDI = "audio/x-midi"; - public static final String AUDIO_X_MP3 = "audio/x-mp3"; - public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3"; - public static final String AUDIO_X_MPEG = "audio/x-mpeg"; - public static final String AUDIO_X_MPG = "audio/x-mpg"; - public static final String AUDIO_3GPP = "audio/3gpp"; - public static final String AUDIO_X_WAV = "audio/x-wav"; - public static final String AUDIO_OGG = "application/ogg"; - - public static final String VIDEO_UNSPECIFIED = "video/*"; - public static final String VIDEO_3GPP = "video/3gpp"; - public static final String VIDEO_3G2 = "video/3gpp2"; - public static final String VIDEO_H263 = "video/h263"; - public static final String VIDEO_MP4 = "video/mp4"; - - public static final String APP_SMIL = "application/smil"; - public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml"; - public static final String APP_XHTML = "application/xhtml+xml"; - - public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content"; - public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message"; - - private static final ArrayList sSupportedContentTypes = new ArrayList(); - private static final ArrayList sSupportedImageTypes = new ArrayList(); - private static final ArrayList sSupportedAudioTypes = new ArrayList(); - private static final ArrayList sSupportedVideoTypes = new ArrayList(); - - static { - sSupportedContentTypes.add(TEXT_PLAIN); - sSupportedContentTypes.add(TEXT_HTML); - sSupportedContentTypes.add(TEXT_VCALENDAR); - sSupportedContentTypes.add(TEXT_VCARD); - - sSupportedContentTypes.add(IMAGE_JPEG); - sSupportedContentTypes.add(IMAGE_GIF); - sSupportedContentTypes.add(IMAGE_WBMP); - sSupportedContentTypes.add(IMAGE_PNG); - sSupportedContentTypes.add(IMAGE_JPG); - sSupportedContentTypes.add(IMAGE_X_MS_BMP); - //supportedContentTypes.add(IMAGE_SVG); not yet supported. - - sSupportedContentTypes.add(AUDIO_AAC); - sSupportedContentTypes.add(AUDIO_AMR); - sSupportedContentTypes.add(AUDIO_IMELODY); - sSupportedContentTypes.add(AUDIO_MID); - sSupportedContentTypes.add(AUDIO_MIDI); - sSupportedContentTypes.add(AUDIO_MP3); - sSupportedContentTypes.add(AUDIO_MPEG3); - sSupportedContentTypes.add(AUDIO_MPEG); - sSupportedContentTypes.add(AUDIO_MPG); - sSupportedContentTypes.add(AUDIO_X_MID); - sSupportedContentTypes.add(AUDIO_X_MIDI); - sSupportedContentTypes.add(AUDIO_X_MP3); - sSupportedContentTypes.add(AUDIO_X_MPEG3); - sSupportedContentTypes.add(AUDIO_X_MPEG); - sSupportedContentTypes.add(AUDIO_X_MPG); - sSupportedContentTypes.add(AUDIO_X_WAV); - sSupportedContentTypes.add(AUDIO_3GPP); - sSupportedContentTypes.add(AUDIO_OGG); - - sSupportedContentTypes.add(VIDEO_3GPP); - sSupportedContentTypes.add(VIDEO_3G2); - sSupportedContentTypes.add(VIDEO_H263); - sSupportedContentTypes.add(VIDEO_MP4); - - sSupportedContentTypes.add(APP_SMIL); - sSupportedContentTypes.add(APP_WAP_XHTML); - sSupportedContentTypes.add(APP_XHTML); - - sSupportedContentTypes.add(APP_DRM_CONTENT); - sSupportedContentTypes.add(APP_DRM_MESSAGE); - - // add supported image types - sSupportedImageTypes.add(IMAGE_JPEG); - sSupportedImageTypes.add(IMAGE_GIF); - sSupportedImageTypes.add(IMAGE_WBMP); - sSupportedImageTypes.add(IMAGE_PNG); - sSupportedImageTypes.add(IMAGE_JPG); - sSupportedImageTypes.add(IMAGE_X_MS_BMP); - - // add supported audio types - sSupportedAudioTypes.add(AUDIO_AAC); - sSupportedAudioTypes.add(AUDIO_AMR); - sSupportedAudioTypes.add(AUDIO_IMELODY); - sSupportedAudioTypes.add(AUDIO_MID); - sSupportedAudioTypes.add(AUDIO_MIDI); - sSupportedAudioTypes.add(AUDIO_MP3); - sSupportedAudioTypes.add(AUDIO_MPEG3); - sSupportedAudioTypes.add(AUDIO_MPEG); - sSupportedAudioTypes.add(AUDIO_MPG); - sSupportedAudioTypes.add(AUDIO_MP4); - sSupportedAudioTypes.add(AUDIO_X_MID); - sSupportedAudioTypes.add(AUDIO_X_MIDI); - sSupportedAudioTypes.add(AUDIO_X_MP3); - sSupportedAudioTypes.add(AUDIO_X_MPEG3); - sSupportedAudioTypes.add(AUDIO_X_MPEG); - sSupportedAudioTypes.add(AUDIO_X_MPG); - sSupportedAudioTypes.add(AUDIO_X_WAV); - sSupportedAudioTypes.add(AUDIO_3GPP); - sSupportedAudioTypes.add(AUDIO_OGG); - - // add supported video types - sSupportedVideoTypes.add(VIDEO_3GPP); - sSupportedVideoTypes.add(VIDEO_3G2); - sSupportedVideoTypes.add(VIDEO_H263); - sSupportedVideoTypes.add(VIDEO_MP4); - } - - // This class should never be instantiated. - private ContentType() { - } - - public static boolean isSupportedType(String contentType) { - return (null != contentType) && sSupportedContentTypes.contains(contentType); - } - - public static boolean isSupportedImageType(String contentType) { - return isImageType(contentType) && isSupportedType(contentType); - } - - public static boolean isSupportedAudioType(String contentType) { - return isAudioType(contentType) && isSupportedType(contentType); - } - - public static boolean isSupportedVideoType(String contentType) { - return isVideoType(contentType) && isSupportedType(contentType); - } - - public static boolean isTextType(String contentType) { - return (null != contentType) && contentType.startsWith("text/"); - } - - public static boolean isImageType(String contentType) { - return (null != contentType) && contentType.startsWith("image/"); - } - - public static boolean isAudioType(String contentType) { - return (null != contentType) && contentType.startsWith("audio/"); - } - - public static boolean isVideoType(String contentType) { - return (null != contentType) && contentType.startsWith("video/"); - } - - public static boolean isDrmType(String contentType) { - return (null != contentType) - && (contentType.equals(APP_DRM_CONTENT) - || contentType.equals(APP_DRM_MESSAGE)); - } - - public static boolean isUnspecified(String contentType) { - return (null != contentType) && contentType.endsWith("*"); - } - - @SuppressWarnings("unchecked") - public static ArrayList getImageTypes() { - return (ArrayList) sSupportedImageTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getAudioTypes() { - return (ArrayList) sSupportedAudioTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getVideoTypes() { - return (ArrayList) sSupportedVideoTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getSupportedTypes() { - return (ArrayList) sSupportedContentTypes.clone(); - } -} diff --git a/core/java/com/google/android/mms/InvalidHeaderValueException.java b/core/java/com/google/android/mms/InvalidHeaderValueException.java deleted file mode 100644 index 73d78328e257..000000000000 --- a/core/java/com/google/android/mms/InvalidHeaderValueException.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms; - -/** - * Thrown when an invalid header value was set. - */ -public class InvalidHeaderValueException extends MmsException { - private static final long serialVersionUID = -2053384496042052262L; - - /** - * Constructs an InvalidHeaderValueException with no detailed message. - */ - public InvalidHeaderValueException() { - super(); - } - - /** - * Constructs an InvalidHeaderValueException with the specified detailed message. - * - * @param message the detailed message. - */ - public InvalidHeaderValueException(String message) { - super(message); - } -} diff --git a/core/java/com/google/android/mms/MmsException.java b/core/java/com/google/android/mms/MmsException.java deleted file mode 100644 index 6ca0c7eab9ac..000000000000 --- a/core/java/com/google/android/mms/MmsException.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms; - -/** - * A generic exception that is thrown by the Mms client. - */ -public class MmsException extends Exception { - private static final long serialVersionUID = -7323249827281485390L; - - /** - * Creates a new MmsException. - */ - public MmsException() { - super(); - } - - /** - * Creates a new MmsException with the specified detail message. - * - * @param message the detail message. - */ - public MmsException(String message) { - super(message); - } - - /** - * Creates a new MmsException with the specified cause. - * - * @param cause the cause. - */ - public MmsException(Throwable cause) { - super(cause); - } - - /** - * Creates a new MmsException with the specified detail message and cause. - * - * @param message the detail message. - * @param cause the cause. - */ - public MmsException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/core/java/com/google/android/mms/package.html b/core/java/com/google/android/mms/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/core/java/com/google/android/mms/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - - diff --git a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java b/core/java/com/google/android/mms/pdu/AcknowledgeInd.java deleted file mode 100644 index 0e96c60bd096..000000000000 --- a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Acknowledge.ind PDU. - */ -public class AcknowledgeInd extends GenericPdu { - /** - * Constructor, used when composing a M-Acknowledge.ind pdu. - * - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - */ - public AcknowledgeInd(int mmsVersion, byte[] transactionId) - throws InvalidHeaderValueException { - super(); - - setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - AcknowledgeInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/core/java/com/google/android/mms/pdu/Base64.java b/core/java/com/google/android/mms/pdu/Base64.java deleted file mode 100644 index 604bee0d50fe..000000000000 --- a/core/java/com/google/android/mms/pdu/Base64.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -public class Base64 { - /** - * Used to get the number of Quadruples. - */ - static final int FOURBYTE = 4; - - /** - * Byte used to pad output. - */ - static final byte PAD = (byte) '='; - - /** - * The base length. - */ - static final int BASELENGTH = 255; - - // Create arrays to hold the base64 characters - private static byte[] base64Alphabet = new byte[BASELENGTH]; - - // Populating the character arrays - static { - for (int i = 0; i < BASELENGTH; i++) { - base64Alphabet[i] = (byte) -1; - } - for (int i = 'Z'; i >= 'A'; i--) { - base64Alphabet[i] = (byte) (i - 'A'); - } - for (int i = 'z'; i >= 'a'; i--) { - base64Alphabet[i] = (byte) (i - 'a' + 26); - } - for (int i = '9'; i >= '0'; i--) { - base64Alphabet[i] = (byte) (i - '0' + 52); - } - - base64Alphabet['+'] = 62; - base64Alphabet['/'] = 63; - } - - /** - * Decodes Base64 data into octects - * - * @param base64Data Byte array containing Base64 data - * @return Array containing decoded data. - */ - public static byte[] decodeBase64(byte[] base64Data) { - // RFC 2045 requires that we discard ALL non-Base64 characters - base64Data = discardNonBase64(base64Data); - - // handle the edge case, so we don't have to worry about it later - if (base64Data.length == 0) { - return new byte[0]; - } - - int numberQuadruple = base64Data.length / FOURBYTE; - byte decodedData[] = null; - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; - - // Throw away anything not in base64Data - - int encodedIndex = 0; - int dataIndex = 0; - { - // this sizes the output array properly - rlw - int lastData = base64Data.length; - // ignore the '=' padding - while (base64Data[lastData - 1] == PAD) { - if (--lastData == 0) { - return new byte[0]; - } - } - decodedData = new byte[lastData - numberQuadruple]; - } - - for (int i = 0; i < numberQuadruple; i++) { - dataIndex = i * 4; - marker0 = base64Data[dataIndex + 2]; - marker1 = base64Data[dataIndex + 3]; - - b1 = base64Alphabet[base64Data[dataIndex]]; - b2 = base64Alphabet[base64Data[dataIndex + 1]]; - - if (marker0 != PAD && marker1 != PAD) { - //No PAD e.g 3cQl - b3 = base64Alphabet[marker0]; - b4 = base64Alphabet[marker1]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); - } else if (marker0 == PAD) { - //Two PAD e.g. 3c[Pad][Pad] - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - } else if (marker1 == PAD) { - //One PAD e.g. 3cQ[Pad] - b3 = base64Alphabet[marker0]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - } - encodedIndex += 3; - } - return decodedData; - } - - /** - * Check octect wheter it is a base64 encoding. - * - * @param octect to be checked byte - * @return ture if it is base64 encoding, false otherwise. - */ - private static boolean isBase64(byte octect) { - if (octect == PAD) { - return true; - } else if (base64Alphabet[octect] == -1) { - return false; - } else { - return true; - } - } - - /** - * Discards any characters outside of the base64 alphabet, per - * the requirements on page 25 of RFC 2045 - "Any characters - * outside of the base64 alphabet are to be ignored in base64 - * encoded data." - * - * @param data The base-64 encoded data to groom - * @return The data, less non-base64 characters (see RFC 2045). - */ - static byte[] discardNonBase64(byte[] data) { - byte groomedData[] = new byte[data.length]; - int bytesCopied = 0; - - for (int i = 0; i < data.length; i++) { - if (isBase64(data[i])) { - groomedData[bytesCopied++] = data[i]; - } - } - - byte packedData[] = new byte[bytesCopied]; - - System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); - - return packedData; - } -} diff --git a/core/java/com/google/android/mms/pdu/CharacterSets.java b/core/java/com/google/android/mms/pdu/CharacterSets.java deleted file mode 100644 index 4e22ca5e2cf8..000000000000 --- a/core/java/com/google/android/mms/pdu/CharacterSets.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import java.io.UnsupportedEncodingException; -import java.util.HashMap; - -public class CharacterSets { - /** - * IANA assigned MIB enum numbers. - * - * From wap-230-wsp-20010705-a.pdf - * Any-charset = - * Equivalent to the special RFC2616 charset value "*" - */ - public static final int ANY_CHARSET = 0x00; - public static final int US_ASCII = 0x03; - public static final int ISO_8859_1 = 0x04; - public static final int ISO_8859_2 = 0x05; - public static final int ISO_8859_3 = 0x06; - public static final int ISO_8859_4 = 0x07; - public static final int ISO_8859_5 = 0x08; - public static final int ISO_8859_6 = 0x09; - public static final int ISO_8859_7 = 0x0A; - public static final int ISO_8859_8 = 0x0B; - public static final int ISO_8859_9 = 0x0C; - public static final int SHIFT_JIS = 0x11; - public static final int UTF_8 = 0x6A; - public static final int BIG5 = 0x07EA; - public static final int UCS2 = 0x03E8; - public static final int UTF_16 = 0x03F7; - - /** - * If the encoding of given data is unsupported, use UTF_8 to decode it. - */ - public static final int DEFAULT_CHARSET = UTF_8; - - /** - * Array of MIB enum numbers. - */ - private static final int[] MIBENUM_NUMBERS = { - ANY_CHARSET, - US_ASCII, - ISO_8859_1, - ISO_8859_2, - ISO_8859_3, - ISO_8859_4, - ISO_8859_5, - ISO_8859_6, - ISO_8859_7, - ISO_8859_8, - ISO_8859_9, - SHIFT_JIS, - UTF_8, - BIG5, - UCS2, - UTF_16, - }; - - /** - * The Well-known-charset Mime name. - */ - public static final String MIMENAME_ANY_CHARSET = "*"; - public static final String MIMENAME_US_ASCII = "us-ascii"; - public static final String MIMENAME_ISO_8859_1 = "iso-8859-1"; - public static final String MIMENAME_ISO_8859_2 = "iso-8859-2"; - public static final String MIMENAME_ISO_8859_3 = "iso-8859-3"; - public static final String MIMENAME_ISO_8859_4 = "iso-8859-4"; - public static final String MIMENAME_ISO_8859_5 = "iso-8859-5"; - public static final String MIMENAME_ISO_8859_6 = "iso-8859-6"; - public static final String MIMENAME_ISO_8859_7 = "iso-8859-7"; - public static final String MIMENAME_ISO_8859_8 = "iso-8859-8"; - public static final String MIMENAME_ISO_8859_9 = "iso-8859-9"; - public static final String MIMENAME_SHIFT_JIS = "shift_JIS"; - public static final String MIMENAME_UTF_8 = "utf-8"; - public static final String MIMENAME_BIG5 = "big5"; - public static final String MIMENAME_UCS2 = "iso-10646-ucs-2"; - public static final String MIMENAME_UTF_16 = "utf-16"; - - public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8; - - /** - * Array of the names of character sets. - */ - private static final String[] MIME_NAMES = { - MIMENAME_ANY_CHARSET, - MIMENAME_US_ASCII, - MIMENAME_ISO_8859_1, - MIMENAME_ISO_8859_2, - MIMENAME_ISO_8859_3, - MIMENAME_ISO_8859_4, - MIMENAME_ISO_8859_5, - MIMENAME_ISO_8859_6, - MIMENAME_ISO_8859_7, - MIMENAME_ISO_8859_8, - MIMENAME_ISO_8859_9, - MIMENAME_SHIFT_JIS, - MIMENAME_UTF_8, - MIMENAME_BIG5, - MIMENAME_UCS2, - MIMENAME_UTF_16, - }; - - private static final HashMap MIBENUM_TO_NAME_MAP; - private static final HashMap NAME_TO_MIBENUM_MAP; - - static { - // Create the HashMaps. - MIBENUM_TO_NAME_MAP = new HashMap(); - NAME_TO_MIBENUM_MAP = new HashMap(); - assert(MIBENUM_NUMBERS.length == MIME_NAMES.length); - int count = MIBENUM_NUMBERS.length - 1; - for(int i = 0; i <= count; i++) { - MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]); - NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]); - } - } - - private CharacterSets() {} // Non-instantiatable - - /** - * Map an MIBEnum number to the name of the charset which this number - * is assigned to by IANA. - * - * @param mibEnumValue An IANA assigned MIBEnum number. - * @return The name string of the charset. - * @throws UnsupportedEncodingException - */ - public static String getMimeName(int mibEnumValue) - throws UnsupportedEncodingException { - String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue); - if (name == null) { - throw new UnsupportedEncodingException(); - } - return name; - } - - /** - * Map a well-known charset name to its assigned MIBEnum number. - * - * @param mimeName The charset name. - * @return The MIBEnum number assigned by IANA for this charset. - * @throws UnsupportedEncodingException - */ - public static int getMibEnumValue(String mimeName) - throws UnsupportedEncodingException { - if(null == mimeName) { - return -1; - } - - Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName); - if (mibEnumValue == null) { - throw new UnsupportedEncodingException(); - } - return mibEnumValue; - } -} diff --git a/core/java/com/google/android/mms/pdu/DeliveryInd.java b/core/java/com/google/android/mms/pdu/DeliveryInd.java deleted file mode 100644 index dafa8d11b871..000000000000 --- a/core/java/com/google/android/mms/pdu/DeliveryInd.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Delivery.Ind Pdu. - */ -public class DeliveryInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public DeliveryInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - DeliveryInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value, should not be null - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get Status value. - * - * @return the value - */ - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Set Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public EncodedStringValue getStatusText() {return null;} - * public void setStatusText(EncodedStringValue value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/EncodedStringValue.java b/core/java/com/google/android/mms/pdu/EncodedStringValue.java deleted file mode 100644 index 9495c1c5700e..000000000000 --- a/core/java/com/google/android/mms/pdu/EncodedStringValue.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; - -/** - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ -public class EncodedStringValue implements Cloneable { - private static final String TAG = "EncodedStringValue"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - /** - * The Char-set value. - */ - private int mCharacterSet; - - /** - * The Text-string value. - */ - private byte[] mData; - - /** - * Constructor. - * - * @param charset the Char-set value - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public EncodedStringValue(int charset, byte[] data) { - // TODO: CharSet needs to be validated against MIBEnum. - if(null == data) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mCharacterSet = charset; - mData = new byte[data.length]; - System.arraycopy(data, 0, mData, 0, data.length); - } - - /** - * Constructor. - * - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public EncodedStringValue(byte[] data) { - this(CharacterSets.DEFAULT_CHARSET, data); - } - - public EncodedStringValue(String data) { - try { - mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); - mCharacterSet = CharacterSets.DEFAULT_CHARSET; - } catch (UnsupportedEncodingException e) { - Log.e(TAG, "Default encoding must be supported.", e); - } - } - - /** - * Get Char-set value. - * - * @return the value - */ - public int getCharacterSet() { - return mCharacterSet; - } - - /** - * Set Char-set value. - * - * @param charset the Char-set value - */ - public void setCharacterSet(int charset) { - // TODO: CharSet needs to be validated against MIBEnum. - mCharacterSet = charset; - } - - /** - * Get Text-string value. - * - * @return the value - */ - public byte[] getTextString() { - byte[] byteArray = new byte[mData.length]; - - System.arraycopy(mData, 0, byteArray, 0, mData.length); - return byteArray; - } - - /** - * Set Text-string value. - * - * @param textString the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public void setTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } - - /** - * Convert this object to a {@link java.lang.String}. If the encoding of - * the EncodedStringValue is null or unsupported, it will be - * treated as iso-8859-1 encoding. - * - * @return The decoded String. - */ - public String getString() { - if (CharacterSets.ANY_CHARSET == mCharacterSet) { - return new String(mData); // system default encoding. - } else { - try { - String name = CharacterSets.getMimeName(mCharacterSet); - return new String(mData, name); - } catch (UnsupportedEncodingException e) { - if (LOCAL_LOGV) { - Log.v(TAG, e.getMessage(), e); - } - try { - return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException _) { - return new String(mData); // system default encoding. - } - } - } - } - - /** - * Append to Text-string. - * - * @param textString the textString to append - * @throws NullPointerException if the text String is null - * or an IOException occured. - */ - public void appendTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("Text-string is null."); - } - - if(null == mData) { - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } else { - ByteArrayOutputStream newTextString = new ByteArrayOutputStream(); - try { - newTextString.write(mData); - newTextString.write(textString); - } catch (IOException e) { - e.printStackTrace(); - throw new NullPointerException( - "appendTextString: failed when write a new Text-string"); - } - - mData = newTextString.toByteArray(); - } - } - - /* - * (non-Javadoc) - * @see java.lang.Object#clone() - */ - @Override - public Object clone() throws CloneNotSupportedException { - super.clone(); - int len = mData.length; - byte[] dstBytes = new byte[len]; - System.arraycopy(mData, 0, dstBytes, 0, len); - - try { - return new EncodedStringValue(mCharacterSet, dstBytes); - } catch (Exception e) { - Log.e(TAG, "failed to clone an EncodedStringValue: " + this); - e.printStackTrace(); - throw new CloneNotSupportedException(e.getMessage()); - } - } - - /** - * Split this encoded string around matches of the given pattern. - * - * @param pattern the delimiting pattern - * @return the array of encoded strings computed by splitting this encoded - * string around matches of the given pattern - */ - public EncodedStringValue[] split(String pattern) { - String[] temp = getString().split(pattern); - EncodedStringValue[] ret = new EncodedStringValue[temp.length]; - for (int i = 0; i < ret.length; ++i) { - try { - ret[i] = new EncodedStringValue(mCharacterSet, - temp[i].getBytes()); - } catch (NullPointerException _) { - // Can't arrive here - return null; - } - } - return ret; - } - - /** - * Extract an EncodedStringValue[] from a given String. - */ - public static EncodedStringValue[] extract(String src) { - String[] values = src.split(";"); - - ArrayList list = new ArrayList(); - for (int i = 0; i < values.length; i++) { - if (values[i].length() > 0) { - list.add(new EncodedStringValue(values[i])); - } - } - - int len = list.size(); - if (len > 0) { - return list.toArray(new EncodedStringValue[len]); - } else { - return null; - } - } - - /** - * Concatenate an EncodedStringValue[] into a single String. - */ - public static String concat(EncodedStringValue[] addr) { - StringBuilder sb = new StringBuilder(); - int maxIndex = addr.length - 1; - for (int i = 0; i <= maxIndex; i++) { - sb.append(addr[i].getString()); - if (i < maxIndex) { - sb.append(";"); - } - } - - return sb.toString(); - } - - public static EncodedStringValue copy(EncodedStringValue value) { - if (value == null) { - return null; - } - - return new EncodedStringValue(value.mCharacterSet, value.mData); - } - - public static EncodedStringValue[] encodeStrings(String[] array) { - int count = array.length; - if (count > 0) { - EncodedStringValue[] encodedArray = new EncodedStringValue[count]; - for (int i = 0; i < count; i++) { - encodedArray[i] = new EncodedStringValue(array[i]); - } - return encodedArray; - } - return null; - } -} diff --git a/core/java/com/google/android/mms/pdu/GenericPdu.java b/core/java/com/google/android/mms/pdu/GenericPdu.java deleted file mode 100644 index 705de6afb8b6..000000000000 --- a/core/java/com/google/android/mms/pdu/GenericPdu.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -public class GenericPdu { - /** - * The headers of pdu. - */ - PduHeaders mPduHeaders = null; - - /** - * Constructor. - */ - public GenericPdu() { - mPduHeaders = new PduHeaders(); - } - - /** - * Constructor. - * - * @param headers Headers for this PDU. - */ - GenericPdu(PduHeaders headers) { - mPduHeaders = headers; - } - - /** - * Get the headers of this PDU. - * - * @return A PduHeaders of this PDU. - */ - PduHeaders getPduHeaders() { - return mPduHeaders; - } - - /** - * Get X-Mms-Message-Type field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getMessageType() { - return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - } - - /** - * Set X-Mms-Message-Type field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - public void setMessageType(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE); - } - - /** - * Get X-Mms-MMS-Version field value. - * - * @return the X-Mms-MMS-Version value - */ - public int getMmsVersion() { - return mPduHeaders.getOctet(PduHeaders.MMS_VERSION); - } - - /** - * Set X-Mms-MMS-Version field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - public void setMmsVersion(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } -} diff --git a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java deleted file mode 100644 index 5a85e0e79ddc..000000000000 --- a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * Multimedia message PDU. - */ -public class MultimediaMessagePdu extends GenericPdu{ - /** - * The body. - */ - private PduBody mMessageBody; - - /** - * Constructor. - */ - public MultimediaMessagePdu() { - super(); - } - - /** - * Constructor. - * - * @param header the header of this PDU - * @param body the body of this PDU - */ - public MultimediaMessagePdu(PduHeaders header, PduBody body) { - super(header); - mMessageBody = body; - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - MultimediaMessagePdu(PduHeaders headers) { - super(headers); - } - - /** - * Get body of the PDU. - * - * @return the body - */ - public PduBody getBody() { - return mMessageBody; - } - - /** - * Set body of the PDU. - * - * @param body the body - */ - public void setBody(PduBody body) { - mMessageBody = body; - } - - /** - * Get subject. - * - * @return the value - */ - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Add a "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addTo(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Priority value. - * - * @return the value - */ - public int getPriority() { - return mPduHeaders.getOctet(PduHeaders.PRIORITY); - } - - /** - * Set X-Mms-Priority value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setPriority(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.PRIORITY); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value in seconds. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } -} diff --git a/core/java/com/google/android/mms/pdu/NotificationInd.java b/core/java/com/google/android/mms/pdu/NotificationInd.java deleted file mode 100644 index c56cba6d14bf..000000000000 --- a/core/java/com/google/android/mms/pdu/NotificationInd.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Notification.ind PDU. - */ -public class NotificationInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - * RuntimeException if an undeclared error occurs. - */ - public NotificationInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - NotificationInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Content-Class Value. - * - * @return the value - */ - public int getContentClass() { - return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS); - } - - /** - * Set X-Mms-Content-Class Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setContentClass(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS); - } - - /** - * Get X-Mms-Content-Location value. - * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf: - * Content-location-value = Uri-value - * - * @return the value - */ - public byte[] getContentLocation() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION); - } - - /** - * Set X-Mms-Content-Location value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setContentLocation(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Message-Size value. - * Message-size-value = Long-integer - * - * @return the value - */ - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-Message-Size value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get subject. - * - * @return the value - */ - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /** - * Get X-Mms-Delivery-Report Value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public ElementDescriptorValue getElementDescriptor() {return null;} - * public void getElementDescriptor(ElementDescriptorValue value) {} - * - * public byte getPriority() {return 0x00;} - * public void setPriority(byte value) {} - * - * public byte getRecommendedRetrievalMode() {return 0x00;} - * public void setRecommendedRetrievalMode(byte value) {} - * - * public byte getRecommendedRetrievalModeText() {return 0x00;} - * public void setRecommendedRetrievalModeText(byte value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte getStored() {return 0x00;} - * public void setStored(byte value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/NotifyRespInd.java b/core/java/com/google/android/mms/pdu/NotifyRespInd.java deleted file mode 100644 index 2cc2fce0812d..000000000000 --- a/core/java/com/google/android/mms/pdu/NotifyRespInd.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-NofifyResp.ind PDU. - */ -public class NotifyRespInd extends GenericPdu { - /** - * Constructor, used when composing a M-NotifyResp.ind pdu. - * - * @param mmsVersion current version of mms - * @param transactionId the transaction-id value - * @param status the status value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - * RuntimeException if an undeclared error occurs. - */ - public NotifyRespInd(int mmsVersion, - byte[] transactionId, - int status) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - setStatus(status); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - NotifyRespInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Status field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * GetX-Mms-Status field value. - * - * @return the X-Mms-Status value - */ - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/core/java/com/google/android/mms/pdu/PduBody.java b/core/java/com/google/android/mms/pdu/PduBody.java deleted file mode 100644 index fa0416c6be6a..000000000000 --- a/core/java/com/google/android/mms/pdu/PduBody.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -public class PduBody { - private Vector mParts = null; - - private Map mPartMapByContentId = null; - private Map mPartMapByContentLocation = null; - private Map mPartMapByName = null; - private Map mPartMapByFileName = null; - - /** - * Constructor. - */ - public PduBody() { - mParts = new Vector(); - - mPartMapByContentId = new HashMap(); - mPartMapByContentLocation = new HashMap(); - mPartMapByName = new HashMap(); - mPartMapByFileName = new HashMap(); - } - - private void putPartToMaps(PduPart part) { - // Put part to mPartMapByContentId. - byte[] contentId = part.getContentId(); - if(null != contentId) { - mPartMapByContentId.put(new String(contentId), part); - } - - // Put part to mPartMapByContentLocation. - byte[] contentLocation = part.getContentLocation(); - if(null != contentLocation) { - String clc = new String(contentLocation); - mPartMapByContentLocation.put(clc, part); - } - - // Put part to mPartMapByName. - byte[] name = part.getName(); - if(null != name) { - String clc = new String(name); - mPartMapByName.put(clc, part); - } - - // Put part to mPartMapByFileName. - byte[] fileName = part.getFilename(); - if(null != fileName) { - String clc = new String(fileName); - mPartMapByFileName.put(clc, part); - } - } - - /** - * Appends the specified part to the end of this body. - * - * @param part part to be appended - * @return true when success, false when fail - * @throws NullPointerException when part is null - */ - public boolean addPart(PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - return mParts.add(part); - } - - /** - * Inserts the specified part at the specified position. - * - * @param index index at which the specified part is to be inserted - * @param part part to be inserted - * @throws NullPointerException when part is null - */ - public void addPart(int index, PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - mParts.add(index, part); - } - - /** - * Removes the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - public PduPart removePart(int index) { - return mParts.remove(index); - } - - /** - * Remove all of the parts. - */ - public void removeAll() { - mParts.clear(); - } - - /** - * Get the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - public PduPart getPart(int index) { - return mParts.get(index); - } - - /** - * Get the index of the specified part. - * - * @param part the part object - * @return index the index of the first occurrence of the part in this body - */ - public int getPartIndex(PduPart part) { - return mParts.indexOf(part); - } - - /** - * Get the number of parts. - * - * @return the number of parts - */ - public int getPartsNum() { - return mParts.size(); - } - - /** - * Get pdu part by content id. - * - * @param cid the value of content id. - * @return the pdu part. - */ - public PduPart getPartByContentId(String cid) { - return mPartMapByContentId.get(cid); - } - - /** - * Get pdu part by Content-Location. Content-Location of part is - * the same as filename and name(param of content-type). - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByContentLocation(String contentLocation) { - return mPartMapByContentLocation.get(contentLocation); - } - - /** - * Get pdu part by name. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByName(String name) { - return mPartMapByName.get(name); - } - - /** - * Get pdu part by filename. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByFileName(String filename) { - return mPartMapByFileName.get(filename); - } -} diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java deleted file mode 100644 index d426f89bcb6c..000000000000 --- a/core/java/com/google/android/mms/pdu/PduComposer.java +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import android.content.ContentResolver; -import android.content.Context; -import android.util.Log; -import android.text.TextUtils; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; - -public class PduComposer { - /** - * Address type. - */ - static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1; - static private final int PDU_EMAIL_ADDRESS_TYPE = 2; - static private final int PDU_IPV4_ADDRESS_TYPE = 3; - static private final int PDU_IPV6_ADDRESS_TYPE = 4; - static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5; - - /** - * Address regular expression string. - */ - static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+"; - static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" + - "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}"; - static final String REGEXP_IPV6_ADDRESS_TYPE = - "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}"; - static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" + - "[0-9]{1,3}\\.{1}[0-9]{1,3}"; - - /** - * The postfix strings of address. - */ - static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN"; - static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4"; - static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6"; - - /** - * Error values. - */ - static private final int PDU_COMPOSE_SUCCESS = 0; - static private final int PDU_COMPOSE_CONTENT_ERROR = 1; - static private final int PDU_COMPOSE_FIELD_NOT_SET = 2; - static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3; - - /** - * WAP values defined in WSP spec. - */ - static private final int QUOTED_STRING_FLAG = 34; - static private final int END_STRING_FLAG = 0; - static private final int LENGTH_QUOTE = 31; - static private final int TEXT_MAX = 127; - static private final int SHORT_INTEGER_MAX = 127; - static private final int LONG_INTEGER_LENGTH_MAX = 8; - - /** - * Block size when read data from InputStream. - */ - static private final int PDU_COMPOSER_BLOCK_SIZE = 1024; - - /** - * The output message. - */ - protected ByteArrayOutputStream mMessage = null; - - /** - * The PDU. - */ - private GenericPdu mPdu = null; - - /** - * Current visiting position of the mMessage. - */ - protected int mPosition = 0; - - /** - * Message compose buffer stack. - */ - private BufferStack mStack = null; - - /** - * Content resolver. - */ - private final ContentResolver mResolver; - - /** - * Header of this pdu. - */ - private PduHeaders mPduHeader = null; - - /** - * Map of all content type - */ - private static HashMap mContentTypeMap = null; - - static { - mContentTypeMap = new HashMap(); - - int i; - for (i = 0; i < PduContentTypes.contentTypes.length; i++) { - mContentTypeMap.put(PduContentTypes.contentTypes[i], i); - } - } - - /** - * Constructor. - * - * @param context the context - * @param pdu the pdu to be composed - */ - public PduComposer(Context context, GenericPdu pdu) { - mPdu = pdu; - mResolver = context.getContentResolver(); - mPduHeader = pdu.getPduHeaders(); - mStack = new BufferStack(); - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Make the message. No need to check whether mandatory fields are set, - * because the constructors of outgoing pdus are taking care of this. - * - * @return OutputStream of maked message. Return null if - * the PDU is invalid. - */ - public byte[] make() { - // Get Message-type. - int type = mPdu.getMessageType(); - - /* make the message */ - switch (type) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - if (makeAckInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - default: - return null; - } - - return mMessage.toByteArray(); - } - - /** - * Copy buf to mMessage. - */ - protected void arraycopy(byte[] buf, int pos, int length) { - mMessage.write(buf, pos, length); - mPosition = mPosition + length; - } - - /** - * Append a byte to mMessage. - */ - protected void append(int value) { - mMessage.write(value); - mPosition ++; - } - - /** - * Append short integer value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendShortInteger(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-integer = OCTET - * ; Integers in range 0-127 shall be encoded as a one octet value - * ; with the most significant bit set to one (1xxx xxxx) and with - * ; the value in the remaining least significant bits. - * In our implementation, only low 7 bits are stored and otherwise - * bits are ignored. - */ - append((value | 0x80) & 0xff); - } - - /** - * Append an octet number between 128 and 255 into mMessage. - * NOTE: - * A value between 0 and 127 should be appended by using appendShortInteger. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendOctet(int number) { - append(number); - } - - /** - * Append a short length into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendShortLength(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-length = - */ - append(value); - } - - /** - * Append long integer into mMessage. it's used for really long integers. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendLongInteger(long longInt) { - /* - * From WAP-230-WSP-20010705-a: - * Long-integer = Short-length Multi-octet-integer - * ; The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * ; The content octets shall be an unsigned integer value with the - * ; most significant octet encoded first (big-endian representation). - * ; The minimum number of octets must be used to encode the value. - */ - int size; - long temp = longInt; - - // Count the length of the long integer. - for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) { - temp = (temp >>> 8); - } - - // Set Length. - appendShortLength(size); - - // Count and set the long integer. - int i; - int shift = (size -1) * 8; - - for (i = 0; i < size; i++) { - append((int)((longInt >>> shift) & 0xff)); - shift = shift - 8; - } - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendTextString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255 - append(TEXT_MAX); - } - - arraycopy(text, 0, text.length); - append(0); - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendTextString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - appendTextString(str.getBytes()); - } - - /** - * Append encoded string value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendEncodedString(EncodedStringValue enStr) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(enStr != null); - - int charset = enStr.getCharacterSet(); - byte[] textString = enStr.getTextString(); - if (null == textString) { - return; - } - - /* - * In the implementation of EncodedStringValue, the charset field will - * never be 0. It will always be composed as - * Encoded-string-value = Value-length Char-set Text-string - */ - mStack.newbuf(); - PositionMarker start = mStack.mark(); - - appendShortInteger(charset); - appendTextString(textString); - - int len = start.getLength(); - mStack.pop(); - appendValueLength(len); - mStack.copy(); - } - - /** - * Append uintvar integer into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendUintvarInteger(long value) { - /* - * From WAP-230-WSP-20010705-a: - * To encode a large unsigned integer, split it into 7-bit fragments - * and place them in the payloads of multiple octets. The most significant - * bits are placed in the first octets with the least significant bits - * ending up in the last octet. All octets MUST set the Continue bit to 1 - * except the last octet, which MUST set the Continue bit to 0. - */ - int i; - long max = SHORT_INTEGER_MAX; - - for (i = 0; i < 5; i++) { - if (value < max) { - break; - } - - max = (max << 7) | 0x7fl; - } - - while(i > 0) { - long temp = value >>> (i * 7); - temp = temp & 0x7f; - - append((int)((temp | 0x80) & 0xff)); - - i--; - } - - append((int)(value & 0x7f)); - } - - /** - * Append date value into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendDateValue(long date) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Date-value = Long-integer - */ - appendLongInteger(date); - } - - /** - * Append value length to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendValueLength(long value) { - /* - * From WAP-230-WSP-20010705-a: - * Value-length = Short-length | (Length-quote Length) - * ; Value length is used to indicate the length of the value to follow - * Short-length = - * Length-quote = - * Length = Uintvar-integer - */ - if (value < LENGTH_QUOTE) { - appendShortLength((int) value); - return; - } - - append(LENGTH_QUOTE); - appendUintvarInteger(value); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendQuotedString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - append(QUOTED_STRING_FLAG); - arraycopy(text, 0, text.length); - append(END_STRING_FLAG); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendQuotedString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - appendQuotedString(str.getBytes()); - } - - private EncodedStringValue appendAddressType(EncodedStringValue address) { - EncodedStringValue temp = null; - - try { - int addressType = checkAddressType(address.getString()); - temp = EncodedStringValue.copy(address); - if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) { - // Phone number. - temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV4_ADDRESS_TYPE == addressType) { - // Ipv4 address. - temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV6_ADDRESS_TYPE == addressType) { - // Ipv6 address. - temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes()); - } - } catch (NullPointerException e) { - return null; - } - - return temp; - } - - /** - * Append header to mMessage. - */ - private int appendHeader(int field) { - switch (field) { - case PduHeaders.MMS_VERSION: - appendOctet(field); - - int version = mPduHeader.getOctet(field); - if (0 == version) { - appendShortInteger(PduHeaders.CURRENT_MMS_VERSION); - } else { - appendShortInteger(version); - } - - break; - - case PduHeaders.MESSAGE_ID: - case PduHeaders.TRANSACTION_ID: - byte[] textString = mPduHeader.getTextString(field); - if (null == textString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendTextString(textString); - break; - - case PduHeaders.TO: - case PduHeaders.BCC: - case PduHeaders.CC: - EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field); - - if (null == addr) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - EncodedStringValue temp; - for (int i = 0; i < addr.length; i++) { - temp = appendAddressType(addr[i]); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendOctet(field); - appendEncodedString(temp); - } - break; - - case PduHeaders.FROM: - // Value-length (Address-present-token Encoded-string-value | Insert-address-token) - appendOctet(field); - - EncodedStringValue from = mPduHeader.getEncodedStringValue(field); - if ((from == null) - || TextUtils.isEmpty(from.getString()) - || new String(from.getTextString()).equals( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { - // Length of from = 1 - append(1); - // Insert-address-token = - append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN); - } else { - mStack.newbuf(); - PositionMarker fstart = mStack.mark(); - - // Address-present-token = - append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN); - - temp = appendAddressType(from); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendEncodedString(temp); - - int flen = fstart.getLength(); - mStack.pop(); - appendValueLength(flen); - mStack.copy(); - } - break; - - case PduHeaders.READ_STATUS: - case PduHeaders.STATUS: - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.PRIORITY: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.READ_REPORT: - int octet = mPduHeader.getOctet(field); - if (0 == octet) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendOctet(octet); - break; - - case PduHeaders.DATE: - long date = mPduHeader.getLongInteger(field); - if (-1 == date) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendDateValue(date); - break; - - case PduHeaders.SUBJECT: - EncodedStringValue enString = - mPduHeader.getEncodedStringValue(field); - if (null == enString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendEncodedString(enString); - break; - - case PduHeaders.MESSAGE_CLASS: - byte[] messageClass = mPduHeader.getTextString(field); - if (null == messageClass) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_AUTO); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL); - } else { - appendTextString(messageClass); - } - break; - - case PduHeaders.EXPIRY: - long expiry = mPduHeader.getLongInteger(field); - if (-1 == expiry) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - - mStack.newbuf(); - PositionMarker expiryStart = mStack.mark(); - - append(PduHeaders.VALUE_RELATIVE_TOKEN); - appendLongInteger(expiry); - - int expiryLength = expiryStart.getLength(); - mStack.pop(); - appendValueLength(expiryLength); - mStack.copy(); - break; - - default: - return PDU_COMPOSE_FIELD_NOT_SUPPORTED; - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make ReadRec.Ind. - */ - private int makeReadRecInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Message-ID - if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Optional - appendHeader(PduHeaders.DATE); - - // X-Mms-Read-Status - if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Applic-ID Optional(not support) - // X-Mms-Reply-Applic-ID Optional(not support) - // X-Mms-Aux-Applic-Info Optional(not support) - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make NotifyResp.Ind. - */ - private int makeNotifyResp() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Status - if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional (not support) - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Acknowledge.Ind. - */ - private int makeAckInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional - appendHeader(PduHeaders.REPORT_ALLOWED); - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Send.req. - */ - private int makeSendReqPdu() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ); - - // X-Mms-Transaction-ID - appendOctet(PduHeaders.TRANSACTION_ID); - - byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID); - if (trid == null) { - // Transaction-ID should be set(by Transaction) before make(). - throw new IllegalArgumentException("Transaction-ID is null."); - } - appendTextString(trid); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Date-value Optional. - appendHeader(PduHeaders.DATE); - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - boolean recipient = false; - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Cc - if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Bcc - if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Need at least one of "cc", "bcc" and "to". - if (false == recipient) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Subject Optional - appendHeader(PduHeaders.SUBJECT); - - // X-Mms-Message-Class Optional - // Message-class-value = Class-identifier | Token-text - appendHeader(PduHeaders.MESSAGE_CLASS); - - // X-Mms-Expiry Optional - appendHeader(PduHeaders.EXPIRY); - - // X-Mms-Priority Optional - appendHeader(PduHeaders.PRIORITY); - - // X-Mms-Delivery-Report Optional - appendHeader(PduHeaders.DELIVERY_REPORT); - - // X-Mms-Read-Report Optional - appendHeader(PduHeaders.READ_REPORT); - - // Content-Type - appendOctet(PduHeaders.CONTENT_TYPE); - - // Message body - return makeMessageBody(); - } - - /** - * Make message body. - */ - private int makeMessageBody() { - // 1. add body informations - mStack.newbuf(); // Switching buffer because we need to - - PositionMarker ctStart = mStack.mark(); - - // This contentTypeIdentifier should be used for type of attachment... - String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE)); - Integer contentTypeIdentifier = mContentTypeMap.get(contentType); - if (contentTypeIdentifier == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendShortInteger(contentTypeIdentifier.intValue()); - - // content-type parameter: start - PduBody body = ((SendReq) mPdu).getBody(); - if (null == body || body.getPartsNum() == 0) { - // empty message - appendUintvarInteger(0); - mStack.pop(); - mStack.copy(); - return PDU_COMPOSE_SUCCESS; - } - - PduPart part; - try { - part = body.getPart(0); - - byte[] start = part.getContentId(); - if (start != null) { - appendOctet(PduPart.P_DEP_START); - if (('<' == start[0]) && ('>' == start[start.length - 1])) { - appendTextString(start); - } else { - appendTextString("<" + new String(start) + ">"); - } - } - - // content-type parameter: type - appendOctet(PduPart.P_CT_MR_TYPE); - appendTextString(part.getContentType()); - } - catch (ArrayIndexOutOfBoundsException e){ - e.printStackTrace(); - } - - int ctLength = ctStart.getLength(); - mStack.pop(); - appendValueLength(ctLength); - mStack.copy(); - - // 3. add content - int partNum = body.getPartsNum(); - appendUintvarInteger(partNum); - for (int i = 0; i < partNum; i++) { - part = body.getPart(i); - mStack.newbuf(); // Leaving space for header lengh and data length - PositionMarker attachment = mStack.mark(); - - mStack.newbuf(); // Leaving space for Content-Type length - PositionMarker contentTypeBegin = mStack.mark(); - - byte[] partContentType = part.getContentType(); - - if (partContentType == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - // content-type value - Integer partContentTypeIdentifier = - mContentTypeMap.get(new String(partContentType)); - if (partContentTypeIdentifier == null) { - appendTextString(partContentType); - } else { - appendShortInteger(partContentTypeIdentifier.intValue()); - } - - /* Content-type parameter : name. - * The value of name, filename, content-location is the same. - * Just one of them is enough for this PDU. - */ - byte[] name = part.getName(); - - if (null == name) { - name = part.getFilename(); - - if (null == name) { - name = part.getContentLocation(); - - if (null == name) { - /* at lease one of name, filename, Content-location - * should be available. - */ - return PDU_COMPOSE_CONTENT_ERROR; - } - } - } - appendOctet(PduPart.P_DEP_NAME); - appendTextString(name); - - // content-type parameter : charset - int charset = part.getCharset(); - if (charset != 0) { - appendOctet(PduPart.P_CHARSET); - appendShortInteger(charset); - } - - int contentTypeLength = contentTypeBegin.getLength(); - mStack.pop(); - appendValueLength(contentTypeLength); - mStack.copy(); - - // content id - byte[] contentId = part.getContentId(); - - if (null != contentId) { - appendOctet(PduPart.P_CONTENT_ID); - if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) { - appendQuotedString(contentId); - } else { - appendQuotedString("<" + new String(contentId) + ">"); - } - } - - // content-location - byte[] contentLocation = part.getContentLocation(); - if (null != contentLocation) { - appendOctet(PduPart.P_CONTENT_LOCATION); - appendTextString(contentLocation); - } - - // content - int headerLength = attachment.getLength(); - - int dataLength = 0; // Just for safety... - byte[] partData = part.getData(); - - if (partData != null) { - arraycopy(partData, 0, partData.length); - dataLength = partData.length; - } else { - InputStream cr; - try { - byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE]; - cr = mResolver.openInputStream(part.getDataUri()); - int len = 0; - while ((len = cr.read(buffer)) != -1) { - mMessage.write(buffer, 0, len); - mPosition += len; - dataLength += len; - } - } catch (FileNotFoundException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (IOException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (RuntimeException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } - } - - if (dataLength != (attachment.getLength() - headerLength)) { - throw new RuntimeException("BUG: Length sanity check failed"); - } - - mStack.pop(); - appendUintvarInteger(headerLength); - appendUintvarInteger(dataLength); - mStack.copy(); - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Record current message informations. - */ - static private class LengthRecordNode { - ByteArrayOutputStream currentMessage = null; - public int currentPosition = 0; - - public LengthRecordNode next = null; - } - - /** - * Mark current message position and stact size. - */ - private class PositionMarker { - private int c_pos; // Current position - private int currentStackSize; // Current stack size - - int getLength() { - // If these assert fails, likely that you are finding the - // size of buffer that is deep in BufferStack you can only - // find the length of the buffer that is on top - if (currentStackSize != mStack.stackSize) { - throw new RuntimeException("BUG: Invalid call to getLength()"); - } - - return mPosition - c_pos; - } - } - - /** - * This implementation can be OPTIMIZED to use only - * 2 buffers. This optimization involves changing BufferStack - * only... Its usage (interface) will not change. - */ - private class BufferStack { - private LengthRecordNode stack = null; - private LengthRecordNode toCopy = null; - - int stackSize = 0; - - /** - * Create a new message buffer and push it into the stack. - */ - void newbuf() { - // You can't create a new buff when toCopy != null - // That is after calling pop() and before calling copy() - // If you do, it is a bug - if (toCopy != null) { - throw new RuntimeException("BUG: Invalid newbuf() before copy()"); - } - - LengthRecordNode temp = new LengthRecordNode(); - - temp.currentMessage = mMessage; - temp.currentPosition = mPosition; - - temp.next = stack; - stack = temp; - - stackSize = stackSize + 1; - - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Pop the message before and record current message in the stack. - */ - void pop() { - ByteArrayOutputStream currentMessage = mMessage; - int currentPosition = mPosition; - - mMessage = stack.currentMessage; - mPosition = stack.currentPosition; - - toCopy = stack; - // Re using the top element of the stack to avoid memory allocation - - stack = stack.next; - stackSize = stackSize - 1; - - toCopy.currentMessage = currentMessage; - toCopy.currentPosition = currentPosition; - } - - /** - * Append current message to the message before. - */ - void copy() { - arraycopy(toCopy.currentMessage.toByteArray(), 0, - toCopy.currentPosition); - - toCopy = null; - } - - /** - * Mark current message position - */ - PositionMarker mark() { - PositionMarker m = new PositionMarker(); - - m.c_pos = mPosition; - m.currentStackSize = stackSize; - - return m; - } - } - - /** - * Check address type. - * - * @param address address string without the postfix stinng type, - * such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4" - * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number, - * PDU_EMAIL_ADDRESS_TYPE if it is email address, - * PDU_IPV4_ADDRESS_TYPE if it is ipv4 address, - * PDU_IPV6_ADDRESS_TYPE if it is ipv6 address, - * PDU_UNKNOWN_ADDRESS_TYPE if it is unknown. - */ - protected static int checkAddressType(String address) { - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8. - * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode) - * e-mail = mailbox; to the definition of mailbox as described in - * section 3.4 of [RFC2822], but excluding the - * obsolete definitions as indicated by the "obs-" prefix. - * device-address = ( global-phone-number "/TYPE=PLMN" ) - * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" ) - * / ( escaped-value "/TYPE=" address-type ) - * - * global-phone-number = ["+"] 1*( DIGIT / written-sep ) - * written-sep =("-"/".") - * - * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value - * - * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373 - */ - - if (null == address) { - return PDU_UNKNOWN_ADDRESS_TYPE; - } - - if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) { - // Ipv4 address. - return PDU_IPV4_ADDRESS_TYPE; - }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) { - // Phone number. - return PDU_PHONE_NUMBER_ADDRESS_TYPE; - } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) { - // Email address. - return PDU_EMAIL_ADDRESS_TYPE; - } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) { - // Ipv6 address. - return PDU_IPV6_ADDRESS_TYPE; - } else { - // Unknown address. - return PDU_UNKNOWN_ADDRESS_TYPE; - } - } -} diff --git a/core/java/com/google/android/mms/pdu/PduContentTypes.java b/core/java/com/google/android/mms/pdu/PduContentTypes.java deleted file mode 100644 index 7799e0e834af..000000000000 --- a/core/java/com/google/android/mms/pdu/PduContentTypes.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -public class PduContentTypes { - /** - * All content types. From: - * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm - */ - static final String[] contentTypes = { - "*/*", /* 0x00 */ - "text/*", /* 0x01 */ - "text/html", /* 0x02 */ - "text/plain", /* 0x03 */ - "text/x-hdml", /* 0x04 */ - "text/x-ttml", /* 0x05 */ - "text/x-vCalendar", /* 0x06 */ - "text/x-vCard", /* 0x07 */ - "text/vnd.wap.wml", /* 0x08 */ - "text/vnd.wap.wmlscript", /* 0x09 */ - "text/vnd.wap.wta-event", /* 0x0A */ - "multipart/*", /* 0x0B */ - "multipart/mixed", /* 0x0C */ - "multipart/form-data", /* 0x0D */ - "multipart/byterantes", /* 0x0E */ - "multipart/alternative", /* 0x0F */ - "application/*", /* 0x10 */ - "application/java-vm", /* 0x11 */ - "application/x-www-form-urlencoded", /* 0x12 */ - "application/x-hdmlc", /* 0x13 */ - "application/vnd.wap.wmlc", /* 0x14 */ - "application/vnd.wap.wmlscriptc", /* 0x15 */ - "application/vnd.wap.wta-eventc", /* 0x16 */ - "application/vnd.wap.uaprof", /* 0x17 */ - "application/vnd.wap.wtls-ca-certificate", /* 0x18 */ - "application/vnd.wap.wtls-user-certificate", /* 0x19 */ - "application/x-x509-ca-cert", /* 0x1A */ - "application/x-x509-user-cert", /* 0x1B */ - "image/*", /* 0x1C */ - "image/gif", /* 0x1D */ - "image/jpeg", /* 0x1E */ - "image/tiff", /* 0x1F */ - "image/png", /* 0x20 */ - "image/vnd.wap.wbmp", /* 0x21 */ - "application/vnd.wap.multipart.*", /* 0x22 */ - "application/vnd.wap.multipart.mixed", /* 0x23 */ - "application/vnd.wap.multipart.form-data", /* 0x24 */ - "application/vnd.wap.multipart.byteranges", /* 0x25 */ - "application/vnd.wap.multipart.alternative", /* 0x26 */ - "application/xml", /* 0x27 */ - "text/xml", /* 0x28 */ - "application/vnd.wap.wbxml", /* 0x29 */ - "application/x-x968-cross-cert", /* 0x2A */ - "application/x-x968-ca-cert", /* 0x2B */ - "application/x-x968-user-cert", /* 0x2C */ - "text/vnd.wap.si", /* 0x2D */ - "application/vnd.wap.sic", /* 0x2E */ - "text/vnd.wap.sl", /* 0x2F */ - "application/vnd.wap.slc", /* 0x30 */ - "text/vnd.wap.co", /* 0x31 */ - "application/vnd.wap.coc", /* 0x32 */ - "application/vnd.wap.multipart.related", /* 0x33 */ - "application/vnd.wap.sia", /* 0x34 */ - "text/vnd.wap.connectivity-xml", /* 0x35 */ - "application/vnd.wap.connectivity-wbxml", /* 0x36 */ - "application/pkcs7-mime", /* 0x37 */ - "application/vnd.wap.hashed-certificate", /* 0x38 */ - "application/vnd.wap.signed-certificate", /* 0x39 */ - "application/vnd.wap.cert-response", /* 0x3A */ - "application/xhtml+xml", /* 0x3B */ - "application/wml+xml", /* 0x3C */ - "text/css", /* 0x3D */ - "application/vnd.wap.mms-message", /* 0x3E */ - "application/vnd.wap.rollover-certificate", /* 0x3F */ - "application/vnd.wap.locc+wbxml", /* 0x40 */ - "application/vnd.wap.loc+xml", /* 0x41 */ - "application/vnd.syncml.dm+wbxml", /* 0x42 */ - "application/vnd.syncml.dm+xml", /* 0x43 */ - "application/vnd.syncml.notification", /* 0x44 */ - "application/vnd.wap.xhtml+xml", /* 0x45 */ - "application/vnd.wv.csp.cir", /* 0x46 */ - "application/vnd.oma.dd+xml", /* 0x47 */ - "application/vnd.oma.drm.message", /* 0x48 */ - "application/vnd.oma.drm.content", /* 0x49 */ - "application/vnd.oma.drm.rights+xml", /* 0x4A */ - "application/vnd.oma.drm.rights+wbxml", /* 0x4B */ - "application/vnd.wv.csp+xml", /* 0x4C */ - "application/vnd.wv.csp+wbxml", /* 0x4D */ - "application/vnd.syncml.ds.notification", /* 0x4E */ - "audio/*", /* 0x4F */ - "video/*", /* 0x50 */ - "application/vnd.oma.dd2+xml", /* 0x51 */ - "application/mikey" /* 0x52 */ - }; -} diff --git a/core/java/com/google/android/mms/pdu/PduHeaders.java b/core/java/com/google/android/mms/pdu/PduHeaders.java deleted file mode 100644 index 43138150f804..000000000000 --- a/core/java/com/google/android/mms/pdu/PduHeaders.java +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -import java.util.ArrayList; -import java.util.HashMap; - -public class PduHeaders { - /** - * All pdu header fields. - */ - public static final int BCC = 0x81; - public static final int CC = 0x82; - public static final int CONTENT_LOCATION = 0x83; - public static final int CONTENT_TYPE = 0x84; - public static final int DATE = 0x85; - public static final int DELIVERY_REPORT = 0x86; - public static final int DELIVERY_TIME = 0x87; - public static final int EXPIRY = 0x88; - public static final int FROM = 0x89; - public static final int MESSAGE_CLASS = 0x8A; - public static final int MESSAGE_ID = 0x8B; - public static final int MESSAGE_TYPE = 0x8C; - public static final int MMS_VERSION = 0x8D; - public static final int MESSAGE_SIZE = 0x8E; - public static final int PRIORITY = 0x8F; - - public static final int READ_REPLY = 0x90; - public static final int READ_REPORT = 0x90; - public static final int REPORT_ALLOWED = 0x91; - public static final int RESPONSE_STATUS = 0x92; - public static final int RESPONSE_TEXT = 0x93; - public static final int SENDER_VISIBILITY = 0x94; - public static final int STATUS = 0x95; - public static final int SUBJECT = 0x96; - public static final int TO = 0x97; - public static final int TRANSACTION_ID = 0x98; - public static final int RETRIEVE_STATUS = 0x99; - public static final int RETRIEVE_TEXT = 0x9A; - public static final int READ_STATUS = 0x9B; - public static final int REPLY_CHARGING = 0x9C; - public static final int REPLY_CHARGING_DEADLINE = 0x9D; - public static final int REPLY_CHARGING_ID = 0x9E; - public static final int REPLY_CHARGING_SIZE = 0x9F; - - public static final int PREVIOUSLY_SENT_BY = 0xA0; - public static final int PREVIOUSLY_SENT_DATE = 0xA1; - public static final int STORE = 0xA2; - public static final int MM_STATE = 0xA3; - public static final int MM_FLAGS = 0xA4; - public static final int STORE_STATUS = 0xA5; - public static final int STORE_STATUS_TEXT = 0xA6; - public static final int STORED = 0xA7; - public static final int ATTRIBUTES = 0xA8; - public static final int TOTALS = 0xA9; - public static final int MBOX_TOTALS = 0xAA; - public static final int QUOTAS = 0xAB; - public static final int MBOX_QUOTAS = 0xAC; - public static final int MESSAGE_COUNT = 0xAD; - public static final int CONTENT = 0xAE; - public static final int START = 0xAF; - - public static final int ADDITIONAL_HEADERS = 0xB0; - public static final int DISTRIBUTION_INDICATOR = 0xB1; - public static final int ELEMENT_DESCRIPTOR = 0xB2; - public static final int LIMIT = 0xB3; - public static final int RECOMMENDED_RETRIEVAL_MODE = 0xB4; - public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5; - public static final int STATUS_TEXT = 0xB6; - public static final int APPLIC_ID = 0xB7; - public static final int REPLY_APPLIC_ID = 0xB8; - public static final int AUX_APPLIC_ID = 0xB9; - public static final int CONTENT_CLASS = 0xBA; - public static final int DRM_CONTENT = 0xBB; - public static final int ADAPTATION_ALLOWED = 0xBC; - public static final int REPLACE_ID = 0xBD; - public static final int CANCEL_ID = 0xBE; - public static final int CANCEL_STATUS = 0xBF; - - /** - * X-Mms-Message-Type field types. - */ - public static final int MESSAGE_TYPE_SEND_REQ = 0x80; - public static final int MESSAGE_TYPE_SEND_CONF = 0x81; - public static final int MESSAGE_TYPE_NOTIFICATION_IND = 0x82; - public static final int MESSAGE_TYPE_NOTIFYRESP_IND = 0x83; - public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; - public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND = 0x85; - public static final int MESSAGE_TYPE_DELIVERY_IND = 0x86; - public static final int MESSAGE_TYPE_READ_REC_IND = 0x87; - public static final int MESSAGE_TYPE_READ_ORIG_IND = 0x88; - public static final int MESSAGE_TYPE_FORWARD_REQ = 0x89; - public static final int MESSAGE_TYPE_FORWARD_CONF = 0x8A; - public static final int MESSAGE_TYPE_MBOX_STORE_REQ = 0x8B; - public static final int MESSAGE_TYPE_MBOX_STORE_CONF = 0x8C; - public static final int MESSAGE_TYPE_MBOX_VIEW_REQ = 0x8D; - public static final int MESSAGE_TYPE_MBOX_VIEW_CONF = 0x8E; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ = 0x8F; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF = 0x90; - public static final int MESSAGE_TYPE_MBOX_DELETE_REQ = 0x91; - public static final int MESSAGE_TYPE_MBOX_DELETE_CONF = 0x92; - public static final int MESSAGE_TYPE_MBOX_DESCR = 0x93; - public static final int MESSAGE_TYPE_DELETE_REQ = 0x94; - public static final int MESSAGE_TYPE_DELETE_CONF = 0x95; - public static final int MESSAGE_TYPE_CANCEL_REQ = 0x96; - public static final int MESSAGE_TYPE_CANCEL_CONF = 0x97; - - /** - * X-Mms-Delivery-Report | - * X-Mms-Read-Report | - * X-Mms-Report-Allowed | - * X-Mms-Sender-Visibility | - * X-Mms-Store | - * X-Mms-Stored | - * X-Mms-Totals | - * X-Mms-Quotas | - * X-Mms-Distribution-Indicator | - * X-Mms-DRM-Content | - * X-Mms-Adaptation-Allowed | - * field types. - */ - public static final int VALUE_YES = 0x80; - public static final int VALUE_NO = 0x81; - - /** - * Delivery-Time | - * Expiry and Reply-Charging-Deadline | - * field type components. - */ - public static final int VALUE_ABSOLUTE_TOKEN = 0x80; - public static final int VALUE_RELATIVE_TOKEN = 0x81; - - /** - * X-Mms-MMS-Version field types. - */ - public static final int MMS_VERSION_1_3 = ((1 << 4) | 3); - public static final int MMS_VERSION_1_2 = ((1 << 4) | 2); - public static final int MMS_VERSION_1_1 = ((1 << 4) | 1); - public static final int MMS_VERSION_1_0 = ((1 << 4) | 0); - - // Current version is 1.2. - public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2; - - /** - * From field type components. - */ - public static final int FROM_ADDRESS_PRESENT_TOKEN = 0x80; - public static final int FROM_INSERT_ADDRESS_TOKEN = 0x81; - - public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token"; - public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token"; - - /** - * X-Mms-Status Field. - */ - public static final int STATUS_EXPIRED = 0x80; - public static final int STATUS_RETRIEVED = 0x81; - public static final int STATUS_REJECTED = 0x82; - public static final int STATUS_DEFERRED = 0x83; - public static final int STATUS_UNRECOGNIZED = 0x84; - public static final int STATUS_INDETERMINATE = 0x85; - public static final int STATUS_FORWARDED = 0x86; - public static final int STATUS_UNREACHABLE = 0x87; - - /** - * MM-Flags field type components. - */ - public static final int MM_FLAGS_ADD_TOKEN = 0x80; - public static final int MM_FLAGS_REMOVE_TOKEN = 0x81; - public static final int MM_FLAGS_FILTER_TOKEN = 0x82; - - /** - * X-Mms-Message-Class field types. - */ - public static final int MESSAGE_CLASS_PERSONAL = 0x80; - public static final int MESSAGE_CLASS_ADVERTISEMENT = 0x81; - public static final int MESSAGE_CLASS_INFORMATIONAL = 0x82; - public static final int MESSAGE_CLASS_AUTO = 0x83; - - public static final String MESSAGE_CLASS_PERSONAL_STR = "personal"; - public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"; - public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational"; - public static final String MESSAGE_CLASS_AUTO_STR = "auto"; - - /** - * X-Mms-Priority field types. - */ - public static final int PRIORITY_LOW = 0x80; - public static final int PRIORITY_NORMAL = 0x81; - public static final int PRIORITY_HIGH = 0x82; - - /** - * X-Mms-Response-Status field types. - */ - public static final int RESPONSE_STATUS_OK = 0x80; - public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED = 0x81; - public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = 0x83; - public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = 0x85; - public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = 0x86; - public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87; - public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = 0x88; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC2; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC3; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS = 0xC4; - - public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED = 0xE3; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE4; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED = 0xE5; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED = 0xE8; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED = 0xE9; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED = 0xEA; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID = 0xEB; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_END = 0xFF; - - /** - * X-Mms-Retrieve-Status field types. - */ - public static final int RETRIEVE_STATUS_OK = 0x80; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC1; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3; - public static final int RETRIEVE_STATUS_ERROR_END = 0xFF; - - /** - * X-Mms-Sender-Visibility field types. - */ - public static final int SENDER_VISIBILITY_HIDE = 0x80; - public static final int SENDER_VISIBILITY_SHOW = 0x81; - - /** - * X-Mms-Read-Status field types. - */ - public static final int READ_STATUS_READ = 0x80; - public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81; - - /** - * X-Mms-Cancel-Status field types. - */ - public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80; - public static final int CANCEL_STATUS_REQUEST_CORRUPTED = 0x81; - - /** - * X-Mms-Reply-Charging field types. - */ - public static final int REPLY_CHARGING_REQUESTED = 0x80; - public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81; - public static final int REPLY_CHARGING_ACCEPTED = 0x82; - public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY = 0x83; - - /** - * X-Mms-MM-State field types. - */ - public static final int MM_STATE_DRAFT = 0x80; - public static final int MM_STATE_SENT = 0x81; - public static final int MM_STATE_NEW = 0x82; - public static final int MM_STATE_RETRIEVED = 0x83; - public static final int MM_STATE_FORWARDED = 0x84; - - /** - * X-Mms-Recommended-Retrieval-Mode field types. - */ - public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80; - - /** - * X-Mms-Content-Class field types. - */ - public static final int CONTENT_CLASS_TEXT = 0x80; - public static final int CONTENT_CLASS_IMAGE_BASIC = 0x81; - public static final int CONTENT_CLASS_IMAGE_RICH = 0x82; - public static final int CONTENT_CLASS_VIDEO_BASIC = 0x83; - public static final int CONTENT_CLASS_VIDEO_RICH = 0x84; - public static final int CONTENT_CLASS_MEGAPIXEL = 0x85; - public static final int CONTENT_CLASS_CONTENT_BASIC = 0x86; - public static final int CONTENT_CLASS_CONTENT_RICH = 0x87; - - /** - * X-Mms-Store-Status field types. - */ - public static final int STORE_STATUS_SUCCESS = 0x80; - public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC1; - public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE3; - public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL = 0xE4; - public static final int STORE_STATUS_ERROR_END = 0xFF; - - /** - * The map contains the value of all headers. - */ - private HashMap mHeaderMap = null; - - /** - * Constructor of PduHeaders. - */ - public PduHeaders() { - mHeaderMap = new HashMap(); - } - - /** - * Get octet value by header field. - * - * @param field the field - * @return the octet value of the pdu header - * with specified header field. Return 0 if - * the value is not set. - */ - protected int getOctet(int field) { - Integer octet = (Integer) mHeaderMap.get(field); - if (null == octet) { - return 0; - } - - return octet; - } - - /** - * Set octet value to pdu header by header field. - * - * @param value the value - * @param field the field - * @throws InvalidHeaderValueException if the value is invalid. - */ - protected void setOctet(int value, int field) - throws InvalidHeaderValueException{ - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case REPORT_ALLOWED: - case ADAPTATION_ALLOWED: - case DELIVERY_REPORT: - case DRM_CONTENT: - case DISTRIBUTION_INDICATOR: - case QUOTAS: - case READ_REPORT: - case STORE: - case STORED: - case TOTALS: - case SENDER_VISIBILITY: - if ((VALUE_YES != value) && (VALUE_NO != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case READ_STATUS: - if ((READ_STATUS_READ != value) && - (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CANCEL_STATUS: - if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) && - (CANCEL_STATUS_REQUEST_CORRUPTED != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case PRIORITY: - if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case STATUS: - if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case REPLY_CHARGING: - if ((value < REPLY_CHARGING_REQUESTED) - || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case MM_STATE: - if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RECOMMENDED_RETRIEVAL_MODE: - if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CONTENT_CLASS: - if ((value < CONTENT_CLASS_TEXT) - || (value > CONTENT_CLASS_CONTENT_RICH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RETRIEVE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value. - if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) && - (value <= RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < RETRIEVE_STATUS_OK) || - ((value > RETRIEVE_STATUS_OK) && - (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case STORE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value. - if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = STORE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) && - (value <= STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < STORE_STATUS_SUCCESS) || - ((value > STORE_STATUS_SUCCESS) && - (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case RESPONSE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value. - if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) && - (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) && - (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) || - (value < RESPONSE_STATUS_OK) || - ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) && - (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) { - value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case MMS_VERSION: - if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) { - value = CURRENT_MMS_VERSION; // Current version is the default value. - } - break; - case MESSAGE_TYPE: - if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - default: - // This header value should not be Octect. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get TextString value by header field. - * - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - */ - protected byte[] getTextString(int field) { - return (byte[]) mHeaderMap.get(field); - } - - /** - * Set TextString value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setTextString(byte[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case TRANSACTION_ID: - case REPLY_CHARGING_ID: - case AUX_APPLIC_ID: - case APPLIC_ID: - case REPLY_APPLIC_ID: - case MESSAGE_ID: - case REPLACE_ID: - case CANCEL_ID: - case CONTENT_LOCATION: - case MESSAGE_CLASS: - case CONTENT_TYPE: - break; - default: - // This header value should not be Text-String. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get EncodedStringValue value by header field. - * - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - */ - protected EncodedStringValue getEncodedStringValue(int field) { - return (EncodedStringValue) mHeaderMap.get(field); - } - - /** - * Get TO, CC or BCC header value. - * - * @param field the field - * @return the EncodeStringValue array of the pdu header - * with specified header field - */ - protected EncodedStringValue[] getEncodedStringValues(int field) { - ArrayList list = - (ArrayList) mHeaderMap.get(field); - if (null == list) { - return null; - } - EncodedStringValue[] values = new EncodedStringValue[list.size()]; - return list.toArray(values); - } - - /** - * Set EncodedStringValue value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setEncodedStringValue(EncodedStringValue value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case SUBJECT: - case RECOMMENDED_RETRIEVAL_MODE_TEXT: - case RETRIEVE_TEXT: - case STATUS_TEXT: - case STORE_STATUS_TEXT: - case RESPONSE_TEXT: - case FROM: - case PREVIOUSLY_SENT_BY: - case MM_FLAGS: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - mHeaderMap.put(field, value); - } - - /** - * Set TO, CC or BCC header value. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value array of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setEncodedStringValues(EncodedStringValue[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - ArrayList list = new ArrayList(); - for (int i = 0; i < value.length; i++) { - list.add(value[i]); - } - mHeaderMap.put(field, list); - } - - /** - * Append one EncodedStringValue to another. - * - * @param value the EncodedStringValue to append - * @param field the field - * @throws NullPointerException if the value is null. - */ - protected void appendEncodedStringValue(EncodedStringValue value, - int field) { - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - throw new RuntimeException("Invalid header field!"); - } - - ArrayList list = - (ArrayList) mHeaderMap.get(field); - if (null == list) { - list = new ArrayList(); - } - list.add(value); - mHeaderMap.put(field, list); - } - - /** - * Get LongInteger value by header field. - * - * @param field the field - * @return the LongInteger value of the pdu header - * with specified header field. if return -1, the - * field is not existed in pdu header. - */ - protected long getLongInteger(int field) { - Long longInteger = (Long) mHeaderMap.get(field); - if (null == longInteger) { - return -1; - } - - return longInteger.longValue(); - } - - /** - * Set LongInteger value to pdu header by header field. - * - * @param value the value - * @param field the field - */ - protected void setLongInteger(long value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case DATE: - case REPLY_CHARGING_SIZE: - case MESSAGE_SIZE: - case MESSAGE_COUNT: - case START: - case LIMIT: - case DELIVERY_TIME: - case EXPIRY: - case REPLY_CHARGING_DEADLINE: - case PREVIOUSLY_SENT_DATE: - break; - default: - // This header value should not be LongInteger. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } -} diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java deleted file mode 100755 index 015d864a01ea..000000000000 --- a/core/java/com/google/android/mms/pdu/PduParser.java +++ /dev/null @@ -1,1912 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; - -import android.util.Log; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.HashMap; - -import android.content.res.Resources; - -public class PduParser { - /** - * The next are WAP values defined in WSP specification. - */ - private static final int QUOTE = 127; - private static final int LENGTH_QUOTE = 31; - private static final int TEXT_MIN = 32; - private static final int TEXT_MAX = 127; - private static final int SHORT_INTEGER_MAX = 127; - private static final int SHORT_LENGTH_MAX = 30; - private static final int LONG_INTEGER_LENGTH_MAX = 8; - private static final int QUOTED_STRING_FLAG = 34; - private static final int END_STRING_FLAG = 0x00; - //The next two are used by the interface "parseWapString" to - //distinguish Text-String and Quoted-String. - private static final int TYPE_TEXT_STRING = 0; - private static final int TYPE_QUOTED_STRING = 1; - private static final int TYPE_TOKEN_STRING = 2; - - /** - * Specify the part position. - */ - private static final int THE_FIRST_PART = 0; - private static final int THE_LAST_PART = 1; - - /** - * The pdu data. - */ - private ByteArrayInputStream mPduDataStream = null; - - /** - * Store pdu headers - */ - private PduHeaders mHeaders = null; - - /** - * Store pdu parts. - */ - private PduBody mBody = null; - - /** - * Store the "type" parameter in "Content-Type" header field. - */ - private static byte[] mTypeParam = null; - - /** - * Store the "start" parameter in "Content-Type" header field. - */ - private static byte[] mStartParam = null; - - /** - * The log tag. - */ - private static final String LOG_TAG = "PduParser"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - /** - * Constructor. - * - * @param pduDataStream pdu data to be parsed - */ - public PduParser(byte[] pduDataStream) { - mPduDataStream = new ByteArrayInputStream(pduDataStream); - } - - /** - * Parse the pdu. - * - * @return the pdu structure if parsing successfully. - * null if parsing error happened or mandatory fields are not set. - */ - public GenericPdu parse(){ - if (mPduDataStream == null) { - return null; - } - - /* parse headers */ - mHeaders = parseHeaders(mPduDataStream); - if (null == mHeaders) { - // Parse headers failed. - return null; - } - - /* get the message type */ - int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check mandatory header fields */ - if (false == checkMandatoryHeader(mHeaders)) { - log("check mandatory headers failed!"); - return null; - } - - if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) || - (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) { - /* need to parse the parts */ - mBody = parseParts(mPduDataStream); - if (null == mBody) { - // Parse parts failed. - return null; - } - } - - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - SendReq sendReq = new SendReq(mHeaders, mBody); - return sendReq; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - SendConf sendConf = new SendConf(mHeaders); - return sendConf; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - NotificationInd notificationInd = - new NotificationInd(mHeaders); - return notificationInd; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - NotifyRespInd notifyRespInd = - new NotifyRespInd(mHeaders); - return notifyRespInd; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - RetrieveConf retrieveConf = - new RetrieveConf(mHeaders, mBody); - - byte[] contentType = retrieveConf.getContentType(); - if (null == contentType) { - return null; - } - String ctTypeStr = new String(contentType); - if (ctTypeStr.equals(ContentType.MULTIPART_MIXED) - || ctTypeStr.equals(ContentType.MULTIPART_RELATED) - || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // The MMS content type must be "application/vnd.wap.multipart.mixed" - // or "application/vnd.wap.multipart.related" - // or "application/vnd.wap.multipart.alternative" - return retrieveConf; - } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // "application/vnd.wap.multipart.alternative" - // should take only the first part. - PduPart firstPart = mBody.getPart(0); - mBody.removeAll(); - mBody.addPart(0, firstPart); - return retrieveConf; - } - return null; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - DeliveryInd deliveryInd = - new DeliveryInd(mHeaders); - return deliveryInd; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - AcknowledgeInd acknowledgeInd = - new AcknowledgeInd(mHeaders); - return acknowledgeInd; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - ReadOrigInd readOrigInd = - new ReadOrigInd(mHeaders); - return readOrigInd; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - ReadRecInd readRecInd = - new ReadRecInd(mHeaders); - return readRecInd; - default: - log("Parser doesn't support this message type in this version!"); - return null; - } - } - - /** - * Parse pdu headers. - * - * @param pduDataStream pdu data input stream - * @return headers in PduHeaders structure, null when parse fail - */ - protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){ - if (pduDataStream == null) { - return null; - } - - boolean keepParsing = true; - PduHeaders headers = new PduHeaders(); - - while (keepParsing && (pduDataStream.available() > 0)) { - pduDataStream.mark(1); - int headerField = extractByteValue(pduDataStream); - /* parse custom text header */ - if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { - pduDataStream.reset(); - byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); - } - /* we should ignore it at the moment */ - continue; - } - switch (headerField) { - case PduHeaders.MESSAGE_TYPE: - { - int messageType = extractByteValue(pduDataStream); - switch (messageType) { - // We don't support these kind of messages now. - case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: - case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: - case PduHeaders.MESSAGE_TYPE_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: - case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: - return null; - } - try { - headers.setOctet(messageType, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + messageType + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - /* Octect value */ - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.ADAPTATION_ALLOWED: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.DRM_CONTENT: - case PduHeaders.DISTRIBUTION_INDICATOR: - case PduHeaders.QUOTAS: - case PduHeaders.READ_REPORT: - case PduHeaders.STORE: - case PduHeaders.STORED: - case PduHeaders.TOTALS: - case PduHeaders.SENDER_VISIBILITY: - case PduHeaders.READ_STATUS: - case PduHeaders.CANCEL_STATUS: - case PduHeaders.PRIORITY: - case PduHeaders.STATUS: - case PduHeaders.REPLY_CHARGING: - case PduHeaders.MM_STATE: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE: - case PduHeaders.CONTENT_CLASS: - case PduHeaders.RETRIEVE_STATUS: - case PduHeaders.STORE_STATUS: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.RESPONSE_STATUS: - { - int value = extractByteValue(pduDataStream); - - try { - headers.setOctet(value, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + value + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - /* Long-Integer */ - case PduHeaders.DATE: - case PduHeaders.REPLY_CHARGING_SIZE: - case PduHeaders.MESSAGE_SIZE: - { - try { - long value = parseLongInteger(pduDataStream); - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Integer-Value */ - case PduHeaders.MESSAGE_COUNT: - case PduHeaders.START: - case PduHeaders.LIMIT: - { - try { - long value = parseIntegerValue(pduDataStream); - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Text-String */ - case PduHeaders.TRANSACTION_ID: - case PduHeaders.REPLY_CHARGING_ID: - case PduHeaders.AUX_APPLIC_ID: - case PduHeaders.APPLIC_ID: - case PduHeaders.REPLY_APPLIC_ID: - /** - * The next three header fields are email addresses - * as defined in RFC2822, - * not including the characters "<" and ">" - */ - case PduHeaders.MESSAGE_ID: - case PduHeaders.REPLACE_ID: - case PduHeaders.CANCEL_ID: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.CONTENT_LOCATION: - { - byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != value) { - try { - headers.setTextString(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - break; - } - - /* Encoded-string-value */ - case PduHeaders.SUBJECT: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT: - case PduHeaders.RETRIEVE_TEXT: - case PduHeaders.STATUS_TEXT: - case PduHeaders.STORE_STATUS_TEXT: - /* the next one is not support - * M-Mbox-Delete.conf and M-Delete.conf now */ - case PduHeaders.RESPONSE_TEXT: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - try { - headers.setEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch (RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Addressing model */ - case PduHeaders.BCC: - case PduHeaders.CC: - case PduHeaders.TO: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - byte[] address = value.getTextString(); - if (null != address) { - String str = new String(address); - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - value.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - - try { - headers.appendEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) */ - case PduHeaders.DELIVERY_TIME: - case PduHeaders.EXPIRY: - case PduHeaders.REPLY_CHARGING_DEADLINE: - { - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Absolute-token or Relative-token */ - int token = extractByteValue(pduDataStream); - - /* Date-value or Delta-seconds-value */ - long timeValue; - try { - timeValue = parseLongInteger(pduDataStream); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - if (PduHeaders.VALUE_RELATIVE_TOKEN == token) { - /* need to convert the Delta-seconds-value - * into Date-value */ - timeValue = System.currentTimeMillis()/1000 + timeValue; - } - - try { - headers.setLongInteger(timeValue, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.FROM: { - /* From-value = - * Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - */ - EncodedStringValue from = null; - parseValueLength(pduDataStream); /* parse value-length */ - - /* Address-present-token or Insert-address-token */ - int fromToken = extractByteValue(pduDataStream); - - /* Address-present-token or Insert-address-token */ - if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) { - /* Encoded-string-value */ - from = parseEncodedStringValue(pduDataStream); - if (null != from) { - byte[] address = from.getTextString(); - if (null != address) { - String str = new String(address); - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - from.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - } - } else { - try { - from = new EncodedStringValue( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()); - } catch(NullPointerException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - - try { - headers.setEncodedStringValue(from, PduHeaders.FROM); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - break; - } - - case PduHeaders.MESSAGE_CLASS: { - /* Message-class-value = Class-identifier | Token-text */ - pduDataStream.mark(1); - int messageClass = extractByteValue(pduDataStream); - - if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { - /* Class-identifier */ - try { - if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } else { - /* Token-text */ - pduDataStream.reset(); - byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != messageClassString) { - try { - headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - } - break; - } - - case PduHeaders.MMS_VERSION: { - int version = parseShortInteger(pduDataStream); - - try { - headers.setOctet(version, PduHeaders.MMS_VERSION); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + version + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_BY: { - /* Previously-sent-by-value = - * Value-length Forwarded-count-value Encoded-string-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* parse Encoded-string-value */ - EncodedStringValue previouslySentBy = - parseEncodedStringValue(pduDataStream); - if (null != previouslySentBy) { - try { - headers.setEncodedStringValue(previouslySentBy, - PduHeaders.PREVIOUSLY_SENT_BY); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_DATE: { - /* Previously-sent-date-value = - * Value-length Forwarded-count-value Date-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* Date-value */ - try { - long perviouslySentDate = parseLongInteger(pduDataStream); - headers.setLongInteger(perviouslySentDate, - PduHeaders.PREVIOUSLY_SENT_DATE); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.MM_FLAGS: { - /* MM-flags-value = - * Value-length - * ( Add-token | Remove-token | Filter-token ) - * Encoded-string-value - */ - - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Add-token | Remove-token | Filter-token */ - extractByteValue(pduDataStream); - - /* Encoded-string-value */ - parseEncodedStringValue(pduDataStream); - - /* not store this header filed in "headers", - * because now PduHeaders doesn't support it */ - break; - } - - /* Value-length - * (Message-total-token | Size-total-token) Integer-Value */ - case PduHeaders.MBOX_TOTALS: - case PduHeaders.MBOX_QUOTAS: - { - /* Value-length */ - parseValueLength(pduDataStream); - - /* Message-total-token | Size-total-token */ - extractByteValue(pduDataStream); - - /*Integer-Value*/ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* not store these headers filed in "headers", - because now PduHeaders doesn't support them */ - break; - } - - case PduHeaders.ELEMENT_DESCRIPTOR: { - parseContentType(pduDataStream, null); - - /* not store this header filed in "headers", - because now PduHeaders doesn't support it */ - break; - } - - case PduHeaders.CONTENT_TYPE: { - HashMap map = - new HashMap(); - byte[] contentType = - parseContentType(pduDataStream, map); - - if (null != contentType) { - try { - headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - - /* get start parameter */ - mStartParam = (byte[]) map.get(PduPart.P_START); - - /* get charset parameter */ - mTypeParam= (byte[]) map.get(PduPart.P_TYPE); - - keepParsing = false; - break; - } - - case PduHeaders.CONTENT: - case PduHeaders.ADDITIONAL_HEADERS: - case PduHeaders.ATTRIBUTES: - default: { - log("Unknown header"); - } - } - } - - return headers; - } - - /** - * Parse pdu parts. - * - * @param pduDataStream pdu data input stream - * @return parts in PduBody structure - */ - protected static PduBody parseParts(ByteArrayInputStream pduDataStream) { - if (pduDataStream == null) { - return null; - } - - int count = parseUnsignedInt(pduDataStream); // get the number of parts - PduBody body = new PduBody(); - - for (int i = 0 ; i < count ; i++) { - int headerLength = parseUnsignedInt(pduDataStream); - int dataLength = parseUnsignedInt(pduDataStream); - PduPart part = new PduPart(); - int startPos = pduDataStream.available(); - if (startPos <= 0) { - // Invalid part. - return null; - } - - /* parse part's content-type */ - HashMap map = new HashMap(); - byte[] contentType = parseContentType(pduDataStream, map); - if (null != contentType) { - part.setContentType(contentType); - } else { - part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*" - } - - /* get name parameter */ - byte[] name = (byte[]) map.get(PduPart.P_NAME); - if (null != name) { - part.setName(name); - } - - /* get charset parameter */ - Integer charset = (Integer) map.get(PduPart.P_CHARSET); - if (null != charset) { - part.setCharset(charset); - } - - /* parse part's headers */ - int endPos = pduDataStream.available(); - int partHeaderLen = headerLength - (startPos - endPos); - if (partHeaderLen > 0) { - if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) { - // Parse part header faild. - return null; - } - } else if (partHeaderLen < 0) { - // Invalid length of content-type. - return null; - } - - /* FIXME: check content-id, name, filename and content location, - * if not set anyone of them, generate a default content-location - */ - if ((null == part.getContentLocation()) - && (null == part.getName()) - && (null == part.getFilename()) - && (null == part.getContentId())) { - part.setContentLocation(Long.toOctalString( - System.currentTimeMillis()).getBytes()); - } - - /* get part's data */ - if (dataLength > 0) { - byte[] partData = new byte[dataLength]; - String partContentType = new String(part.getContentType()); - pduDataStream.read(partData, 0, dataLength); - if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { - // parse "multipart/vnd.wap.multipart.alternative". - PduBody childBody = parseParts(new ByteArrayInputStream(partData)); - // take the first part of children. - part = childBody.getPart(0); - } else { - // Check Content-Transfer-Encoding. - byte[] partDataEncoding = part.getContentTransferEncoding(); - if (null != partDataEncoding) { - String encoding = new String(partDataEncoding); - if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { - // Decode "base64" into "binary". - partData = Base64.decodeBase64(partData); - } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { - // Decode "quoted-printable" into "binary". - partData = QuotedPrintable.decodeQuotedPrintable(partData); - } else { - // "binary" is the default encoding. - } - } - if (null == partData) { - log("Decode part data error!"); - return null; - } - part.setData(partData); - } - } - - /* add this part to body */ - if (THE_FIRST_PART == checkPartPosition(part)) { - /* this is the first part */ - body.addPart(0, part); - } else { - /* add the part to the end */ - body.addPart(part); - } - } - - return body; - } - - /** - * Log status. - * - * @param text log information - */ - private static void log(String text) { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, text); - } - } - - /** - * Parse unsigned integer. - * - * @param pduDataStream pdu data input stream - * @return the integer, -1 when failed - */ - protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - assert(null != pduDataStream); - int result = 0; - int temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - - while((temp & 0x80) != 0) { - result = result << 7; - result |= temp & 0x7F; - temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - } - - result = result << 7; - result |= temp & 0x7F; - - return result; - } - - /** - * Parse value length. - * - * @param pduDataStream pdu data input stream - * @return the integer - */ - protected static int parseValueLength(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Value-length = Short-length | (Length-quote Length) - * Short-length = - * Length-quote = - * Length = Uintvar-integer - * Uintvar-integer = 1*5 OCTET - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - - if (first <= SHORT_LENGTH_MAX) { - return first; - } else if (first == LENGTH_QUOTE) { - return parseUnsignedInt(pduDataStream); - } - - throw new RuntimeException ("Value length > LENGTH_QUOTE!"); - } - - /** - * Parse encoded string value. - * - * @param pduDataStream pdu data input stream - * @return the EncodedStringValue - */ - protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){ - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - EncodedStringValue returnValue = null; - int charset = 0; - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - if (first == 0) { - return null; // Blank subject, bail. - } - - pduDataStream.reset(); - if (first < TEXT_MIN) { - parseValueLength(pduDataStream); - - charset = parseShortInteger(pduDataStream); //get the "Charset" - } - - byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - try { - if (0 != charset) { - returnValue = new EncodedStringValue(charset, textString); - } else { - returnValue = new EncodedStringValue(textString); - } - } catch(Exception e) { - return null; - } - - return returnValue; - } - - /** - * Parse Text-String or Quoted-String. - * - * @param pduDataStream pdu data input stream - * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING - * @return the string without End-of-string in byte array - */ - protected static byte[] parseWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - /** - * From wap-230-wsp-20010705-a.pdf - * Text-string = [Quote] *TEXT End-of-string - * If the first character in the TEXT is in the range of 128-255, - * a Quote character must precede it. - * Otherwise the Quote character must be omitted. - * The Quote is not part of the contents. - * Quote = - * End-of-string = - * - * Quoted-string = *TEXT End-of-string - * - * Token-text = Token End-of-string - */ - - // Mark supposed beginning of Text-string - // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG - pduDataStream.mark(1); - - // Check first char - int temp = pduDataStream.read(); - assert(-1 != temp); - if ((TYPE_QUOTED_STRING == stringType) && - (QUOTED_STRING_FLAG == temp)) { - // Mark again if QUOTED_STRING_FLAG and ignore it - pduDataStream.mark(1); - } else if ((TYPE_TEXT_STRING == stringType) && - (QUOTE == temp)) { - // Mark again if QUOTE and ignore it - pduDataStream.mark(1); - } else { - // Otherwise go back to origin - pduDataStream.reset(); - } - - // We are now definitely at the beginning of string - /** - * Return *TOKEN or *TEXT (Text-String without QUOTE, - * Quoted-String without QUOTED_STRING_FLAG and without End-of-string) - */ - return getWapString(pduDataStream, stringType); - } - - /** - * Check TOKEN data defined in RFC2616. - * @param ch checking data - * @return true when ch is TOKEN, false when ch is not TOKEN - */ - protected static boolean isTokenCharacter(int ch) { - /** - * Token = 1* - * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64) - * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34) - * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61) - * | "{"(123) | "}"(125) | SP(32) | HT(9) - * CHAR = - * CTL = - * SP = - * HT = - */ - if((ch < 33) || (ch > 126)) { - return false; - } - - switch(ch) { - case '"': /* '"' */ - case '(': /* '(' */ - case ')': /* ')' */ - case ',': /* ',' */ - case '/': /* '/' */ - case ':': /* ':' */ - case ';': /* ';' */ - case '<': /* '<' */ - case '=': /* '=' */ - case '>': /* '>' */ - case '?': /* '?' */ - case '@': /* '@' */ - case '[': /* '[' */ - case '\\': /* '\' */ - case ']': /* ']' */ - case '{': /* '{' */ - case '}': /* '}' */ - return false; - } - - return true; - } - - /** - * Check TEXT data defined in RFC2616. - * @param ch checking data - * @return true when ch is TEXT, false when ch is not TEXT - */ - protected static boolean isText(int ch) { - /** - * TEXT = - * CTL = - * LWS = [CRLF] 1*( SP | HT ) - * CRLF = CR LF - * CR = - * LF = - */ - if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) { - return true; - } - - switch(ch) { - case '\t': /* '\t' */ - case '\n': /* '\n' */ - case '\r': /* '\r' */ - return true; - } - - return false; - } - - protected static byte[] getWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int temp = pduDataStream.read(); - assert(-1 != temp); - while((-1 != temp) && ('\0' != temp)) { - // check each of the character - if (stringType == TYPE_TOKEN_STRING) { - if (isTokenCharacter(temp)) { - out.write(temp); - } - } else { - if (isText(temp)) { - out.write(temp); - } - } - - temp = pduDataStream.read(); - assert(-1 != temp); - } - - if (out.size() > 0) { - return out.toByteArray(); - } - - return null; - } - - /** - * Extract a byte value from the input stream. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - protected static int extractByteValue(ByteArrayInputStream pduDataStream) { - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0xFF; - } - - /** - * Parse Short-Integer. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - protected static int parseShortInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Short-integer = OCTET - * Integers in range 0-127 shall be encoded as a one - * octet value with the most significant bit set to one (1xxx xxxx) - * and with the value in the remaining least significant bits. - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0x7F; - } - - /** - * Parse Long-Integer. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseLongInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Long-integer = Short-length Multi-octet-integer - * The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * The content octets shall be an unsigned integer value - * with the most significant octet encoded first (big-endian representation). - * The minimum number of octets must be used to encode the value. - * Short-length = - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int count = temp & 0xFF; - - if (count > LONG_INTEGER_LENGTH_MAX) { - throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); - } - - long result = 0; - - for (int i = 0 ; i < count ; i++) { - temp = pduDataStream.read(); - assert(-1 != temp); - result <<= 8; - result += (temp & 0xFF); - } - - return result; - } - - /** - * Parse Integer-Value. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Integer-Value = Short-integer | Long-integer - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - if (temp > SHORT_INTEGER_MAX) { - return parseShortInteger(pduDataStream); - } else { - return parseLongInteger(pduDataStream); - } - } - - /** - * To skip length of the wap value. - * - * @param pduDataStream pdu data input stream - * @param length area size - * @return the values in this area - */ - protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) { - assert(null != pduDataStream); - byte[] area = new byte[length]; - int readLen = pduDataStream.read(area, 0, length); - if (readLen < length) { //The actually read length is lower than the length - return -1; - } else { - return readLen; - } - } - - /** - * Parse content type parameters. For now we just support - * four parameters used in mms: "type", "start", "name", "charset". - * - * @param pduDataStream pdu data input stream - * @param map to store parameters of Content-Type field - * @param length length of all the parameters - */ - protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream, - HashMap map, Integer length) { - /** - * From wap-230-wsp-20010705-a.pdf - * Parameter = Typed-parameter | Untyped-parameter - * Typed-parameter = Well-known-parameter-token Typed-value - * the actual expected type of the value is implied by the well-known parameter - * Well-known-parameter-token = Integer-value - * the code values used for parameters are specified in the Assigned Numbers appendix - * Typed-value = Compact-value | Text-value - * In addition to the expected type, there may be no value. - * If the value cannot be encoded using the expected type, it shall be encoded as text. - * Compact-value = Integer-value | - * Date-value | Delta-seconds-value | Q-value | Version-value | - * Uri-value - * Untyped-parameter = Token-text Untyped-value - * the type of the value is unknown, but it shall be encoded as an integer, - * if that is possible. - * Untyped-value = Integer-value | Text-value - */ - assert(null != pduDataStream); - assert(length > 0); - - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int param = pduDataStream.read(); - assert(-1 != param); - lastLen--; - - switch (param) { - /** - * From rfc2387, chapter 3.1 - * The type parameter must be specified and its value is the MIME media - * type of the "root" body part. It permits a MIME user agent to - * determine the content-type without reference to the enclosed body - * part. If the value of the type parameter and the root body part's - * content-type differ then the User Agent's behavior is undefined. - * - * From wap-230-wsp-20010705-a.pdf - * type = Constrained-encoding - * Constrained-encoding = Extension-Media | Short-integer - * Extension-media = *TEXT End-of-string - */ - case PduPart.P_TYPE: - case PduPart.P_CT_MR_TYPE: - pduDataStream.mark(1); - int first = extractByteValue(pduDataStream); - pduDataStream.reset(); - if (first > TEXT_MAX) { - // Short-integer (well-known type) - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { - byte[] type = (PduContentTypes.contentTypes[index]).getBytes(); - map.put(PduPart.P_TYPE, type); - } else { - //not support this type, ignore it. - } - } else { - // Text-String (extension-media) - byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != type) && (null != map)) { - map.put(PduPart.P_TYPE, type); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3. - * Start Parameter Referring to Presentation - * - * From rfc2387, chapter 3.2 - * The start parameter, if given, is the content-ID of the compound - * object's "root". If not present the "root" is the first body part in - * the Multipart/Related entity. The "root" is the element the - * applications processes first. - * - * From wap-230-wsp-20010705-a.pdf - * start = Text-String - */ - case PduPart.P_START: - case PduPart.P_DEP_START: - byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != start) && (null != map)) { - map.put(PduPart.P_START, start); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * In creation, the character set SHALL be either us-ascii - * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode]. - * In retrieval, both us-ascii and utf-8 SHALL be supported. - * - * From wap-230-wsp-20010705-a.pdf - * charset = Well-known-charset|Text-String - * Well-known-charset = Any-charset | Integer-value - * Both are encoded using values from Character Set - * Assignments table in Assigned Numbers - * Any-charset = - * Equivalent to the special RFC2616 charset value "*" - */ - case PduPart.P_CHARSET: - pduDataStream.mark(1); - int firstValue = extractByteValue(pduDataStream); - pduDataStream.reset(); - //Check first char - if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) || - (END_STRING_FLAG == firstValue)) { - //Text-String (extension-charset) - byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING); - try { - int charsetInt = CharacterSets.getMibEnumValue( - new String(charsetStr)); - map.put(PduPart.P_CHARSET, charsetInt); - } catch (UnsupportedEncodingException e) { - // Not a well-known charset, use "*". - Log.e(LOG_TAG, Arrays.toString(charsetStr), e); - map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); - } - } else { - //Well-known-charset - int charset = (int) parseIntegerValue(pduDataStream); - if (map != null) { - map.put(PduPart.P_CHARSET, charset); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * - * From wap-230-wsp-20010705-a.pdf - * name = Text-String - */ - case PduPart.P_DEP_NAME: - case PduPart.P_NAME: - byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != name) && (null != map)) { - map.put(PduPart.P_NAME, name); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Content-Type parameter"); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } else { - lastLen = 0; - } - break; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } - } - - /** - * Parse content type. - * - * @param pduDataStream pdu data input stream - * @param map to store parameters in Content-Type header field - * @return Content-Type value - */ - protected static byte[] parseContentType(ByteArrayInputStream pduDataStream, - HashMap map) { - /** - * From wap-230-wsp-20010705-a.pdf - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - */ - assert(null != pduDataStream); - - byte[] contentType = null; - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - - int cur = (temp & 0xFF); - - if (cur < TEXT_MIN) { - int length = parseValueLength(pduDataStream); - int startPos = pduDataStream.available(); - pduDataStream.mark(1); - temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - int first = (temp & 0xFF); - - if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else if (first > TEXT_MAX) { - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { //well-known type - contentType = (PduContentTypes.contentTypes[index]).getBytes(); - } else { - pduDataStream.reset(); - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } - } else { - Log.e(LOG_TAG, "Corrupt content-type"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - - int endPos = pduDataStream.available(); - int parameterLen = length - (startPos - endPos); - if (parameterLen > 0) {//have parameters - parseContentTypeParams(pduDataStream, map, parameterLen); - } - - if (parameterLen < 0) { - Log.e(LOG_TAG, "Corrupt MMS message"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - } else if (cur <= TEXT_MAX) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else { - contentType = - (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes(); - } - - return contentType; - } - - /** - * Parse part's headers. - * - * @param pduDataStream pdu data input stream - * @param part to store the header informations of the part - * @param length length of the headers - * @return true if parse successfully, false otherwise - */ - protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream, - PduPart part, int length) { - assert(null != pduDataStream); - assert(null != part); - assert(length > 0); - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2. - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * In decoding, name-parameter of Content-Type SHALL be used if available. - * If name-parameter of Content-Type is not available, - * filename parameter of Content-Disposition header SHALL be used if available. - * If neither name-parameter of Content-Type header nor filename parameter - * of Content-Disposition header is available, - * Content-Location header SHALL be used if available. - * - * Within SMIL part the reference to the media object parts SHALL use - * either Content-ID or Content-Location mechanism [RFC2557] - * and the corresponding WSP part headers in media object parts - * contain the corresponding definitions. - */ - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int header = pduDataStream.read(); - assert(-1 != header); - lastLen--; - - if (header > TEXT_MAX) { - // Number assigned headers. - switch (header) { - case PduPart.P_CONTENT_LOCATION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-location-value = Uri-value - */ - byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != contentLocation) { - part.setContentLocation(contentLocation); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_CONTENT_ID: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-ID-value = Quoted-string - */ - byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING); - if (null != contentId) { - part.setContentId(contentId); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_DEP_CONTENT_DISPOSITION: - case PduPart.P_CONTENT_DISPOSITION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-disposition-value = Value-length Disposition *(Parameter) - * Disposition = Form-data | Attachment | Inline | Token-text - * Form-data = - * Attachment = - * Inline = - */ - - /* - * some carrier mmsc servers do not support content_disposition - * field correctly - */ - boolean contentDisposition = Resources.getSystem().getBoolean(com - .android.internal.R.bool.config_mms_content_disposition_support); - - if (contentDisposition) { - int len = parseValueLength(pduDataStream); - pduDataStream.mark(1); - int thisStartPos = pduDataStream.available(); - int thisEndPos = 0; - int value = pduDataStream.read(); - - if (value == PduPart.P_DISPOSITION_FROM_DATA ) { - part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA); - } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) { - part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT); - } else if (value == PduPart.P_DISPOSITION_INLINE) { - part.setContentDisposition(PduPart.DISPOSITION_INLINE); - } else { - pduDataStream.reset(); - /* Token-text */ - part.setContentDisposition(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* get filename parameter and skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - value = pduDataStream.read(); - if (value == PduPart.P_FILENAME) { //filename is text-string - part.setFilename(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - int last = len - (thisStartPos - thisEndPos); - byte[] temp = new byte[last]; - pduDataStream.read(temp, 0, last); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - break; - } - } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) { - // Not assigned header. - byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING); - byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - // Check the header whether it is "Content-Transfer-Encoding". - if (true == - PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) { - part.setContentTransferEncoding(tempValue); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } else { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - // Skip all headers of this part. - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - - return true; - } - - /** - * Check the position of a specified part. - * - * @param part the part to be checked - * @return part position, THE_FIRST_PART when it's the - * first one, THE_LAST_PART when it's the last one. - */ - private static int checkPartPosition(PduPart part) { - assert(null != part); - if ((null == mTypeParam) && - (null == mStartParam)) { - return THE_LAST_PART; - } - - /* check part's content-id */ - if (null != mStartParam) { - byte[] contentId = part.getContentId(); - if (null != contentId) { - if (true == Arrays.equals(mStartParam, contentId)) { - return THE_FIRST_PART; - } - } - } - - /* check part's content-type */ - if (null != mTypeParam) { - byte[] contentType = part.getContentType(); - if (null != contentType) { - if (true == Arrays.equals(mTypeParam, contentType)) { - return THE_FIRST_PART; - } - } - } - - return THE_LAST_PART; - } - - /** - * Check mandatory headers of a pdu. - * - * @param headers pdu headers - * @return true if the pdu has all of the mandatory headers, false otherwise. - */ - protected static boolean checkMandatoryHeader(PduHeaders headers) { - if (null == headers) { - return false; - } - - /* get message type */ - int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check Mms-Version field */ - int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION); - if (0 == mmsVersion) { - // Every message should have Mms-Version field. - return false; - } - - /* check mandatory header fields */ - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - // Content-Type field. - byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == srContentType) { - return false; - } - - // From field. - EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == srFrom) { - return false; - } - - // Transaction-Id field. - byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == srTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - // Response-Status field. - int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS); - if (0 == scResponseStatus) { - return false; - } - - // Transaction-Id field. - byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == scTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - // Content-Location field. - byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION); - if (null == niContentLocation) { - return false; - } - - // Expiry field. - long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY); - if (-1 == niExpiry) { - return false; - } - - // Message-Class field. - byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS); - if (null == niMessageClass) { - return false; - } - - // Message-Size field. - long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE); - if (-1 == niMessageSize) { - return false; - } - - // Transaction-Id field. - byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == niTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - // Status field. - int nriStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == nriStatus) { - return false; - } - - // Transaction-Id field. - byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == nriTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - // Content-Type field. - byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == rcContentType) { - return false; - } - - // Date field. - long rcDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == rcDate) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - // Date field. - long diDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == diDate) { - return false; - } - - // Message-Id field. - byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == diMessageId) { - return false; - } - - // Status field. - int diStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == diStatus) { - return false; - } - - // To field. - EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == diTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - // Transaction-Id field. - byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == aiTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - // Date field. - long roDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == roDate) { - return false; - } - - // From field. - EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == roFrom) { - return false; - } - - // Message-Id field. - byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == roMessageId) { - return false; - } - - // Read-Status field. - int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == roReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == roTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - // From field. - EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == rrFrom) { - return false; - } - - // Message-Id field. - byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == rrMessageId) { - return false; - } - - // Read-Status field. - int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == rrReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == rrTo) { - return false; - } - - break; - default: - // Parser doesn't support this message type in this version. - return false; - } - - return true; - } -} diff --git a/core/java/com/google/android/mms/pdu/PduPart.java b/core/java/com/google/android/mms/pdu/PduPart.java deleted file mode 100644 index b43e388b6517..000000000000 --- a/core/java/com/google/android/mms/pdu/PduPart.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import android.net.Uri; - -import java.util.HashMap; -import java.util.Map; - -/** - * The pdu part. - */ -public class PduPart { - /** - * Well-Known Parameters. - */ - public static final int P_Q = 0x80; - public static final int P_CHARSET = 0x81; - public static final int P_LEVEL = 0x82; - public static final int P_TYPE = 0x83; - public static final int P_DEP_NAME = 0x85; - public static final int P_DEP_FILENAME = 0x86; - public static final int P_DIFFERENCES = 0x87; - public static final int P_PADDING = 0x88; - // This value of "TYPE" s used with Content-Type: multipart/related - public static final int P_CT_MR_TYPE = 0x89; - public static final int P_DEP_START = 0x8A; - public static final int P_DEP_START_INFO = 0x8B; - public static final int P_DEP_COMMENT = 0x8C; - public static final int P_DEP_DOMAIN = 0x8D; - public static final int P_MAX_AGE = 0x8E; - public static final int P_DEP_PATH = 0x8F; - public static final int P_SECURE = 0x90; - public static final int P_SEC = 0x91; - public static final int P_MAC = 0x92; - public static final int P_CREATION_DATE = 0x93; - public static final int P_MODIFICATION_DATE = 0x94; - public static final int P_READ_DATE = 0x95; - public static final int P_SIZE = 0x96; - public static final int P_NAME = 0x97; - public static final int P_FILENAME = 0x98; - public static final int P_START = 0x99; - public static final int P_START_INFO = 0x9A; - public static final int P_COMMENT = 0x9B; - public static final int P_DOMAIN = 0x9C; - public static final int P_PATH = 0x9D; - - /** - * Header field names. - */ - public static final int P_CONTENT_TYPE = 0x91; - public static final int P_CONTENT_LOCATION = 0x8E; - public static final int P_CONTENT_ID = 0xC0; - public static final int P_DEP_CONTENT_DISPOSITION = 0xAE; - public static final int P_CONTENT_DISPOSITION = 0xC5; - // The next header is unassigned header, use reserved header(0x48) value. - public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8; - - /** - * Content=Transfer-Encoding string. - */ - public static final String CONTENT_TRANSFER_ENCODING = - "Content-Transfer-Encoding"; - - /** - * Value of Content-Transfer-Encoding. - */ - public static final String P_BINARY = "binary"; - public static final String P_7BIT = "7bit"; - public static final String P_8BIT = "8bit"; - public static final String P_BASE64 = "base64"; - public static final String P_QUOTED_PRINTABLE = "quoted-printable"; - - /** - * Value of disposition can be set to PduPart when the value is octet in - * the PDU. - * "from-data" instead of Form-data. - * "attachment" instead of Attachment. - * "inline" instead of Inline. - */ - static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes(); - static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes(); - static final byte[] DISPOSITION_INLINE = "inline".getBytes(); - - /** - * Content-Disposition value. - */ - public static final int P_DISPOSITION_FROM_DATA = 0x80; - public static final int P_DISPOSITION_ATTACHMENT = 0x81; - public static final int P_DISPOSITION_INLINE = 0x82; - - /** - * Header of part. - */ - private Map mPartHeader = null; - - /** - * Data uri. - */ - private Uri mUri = null; - - /** - * Part data. - */ - private byte[] mPartData = null; - - private static final String TAG = "PduPart"; - - /** - * Empty Constructor. - */ - public PduPart() { - mPartHeader = new HashMap(); - } - - /** - * Set part data. The data are stored as byte array. - * - * @param data the data - */ - public void setData(byte[] data) { - if(data == null) { - return; - } - - mPartData = new byte[data.length]; - System.arraycopy(data, 0, mPartData, 0, data.length); - } - - /** - * @return A copy of the part data or null if the data wasn't set or - * the data is stored as Uri. - * @see #getDataUri - */ - public byte[] getData() { - if(mPartData == null) { - return null; - } - - byte[] byteArray = new byte[mPartData.length]; - System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length); - return byteArray; - } - - /** - * Set data uri. The data are stored as Uri. - * - * @param uri the uri - */ - public void setDataUri(Uri uri) { - mUri = uri; - } - - /** - * @return The Uri of the part data or null if the data wasn't set or - * the data is stored as byte array. - * @see #getData - */ - public Uri getDataUri() { - return mUri; - } - - /** - * Set Content-id value - * - * @param contentId the content-id value - * @throws NullPointerException if the value is null. - */ - public void setContentId(byte[] contentId) { - if((contentId == null) || (contentId.length == 0)) { - throw new IllegalArgumentException( - "Content-Id may not be null or empty."); - } - - if ((contentId.length > 1) - && ((char) contentId[0] == '<') - && ((char) contentId[contentId.length - 1] == '>')) { - mPartHeader.put(P_CONTENT_ID, contentId); - return; - } - - // Insert beginning '<' and trailing '>' for Content-Id. - byte[] buffer = new byte[contentId.length + 2]; - buffer[0] = (byte) (0xff & '<'); - buffer[buffer.length - 1] = (byte) (0xff & '>'); - System.arraycopy(contentId, 0, buffer, 1, contentId.length); - mPartHeader.put(P_CONTENT_ID, buffer); - } - - /** - * Get Content-id value. - * - * @return the value - */ - public byte[] getContentId() { - return (byte[]) mPartHeader.get(P_CONTENT_ID); - } - - /** - * Set Char-set value. - * - * @param charset the value - */ - public void setCharset(int charset) { - mPartHeader.put(P_CHARSET, charset); - } - - /** - * Get Char-set value - * - * @return the charset value. Return 0 if charset was not set. - */ - public int getCharset() { - Integer charset = (Integer) mPartHeader.get(P_CHARSET); - if(charset == null) { - return 0; - } else { - return charset.intValue(); - } - } - - /** - * Set Content-Location value. - * - * @param contentLocation the value - * @throws NullPointerException if the value is null. - */ - public void setContentLocation(byte[] contentLocation) { - if(contentLocation == null) { - throw new NullPointerException("null content-location"); - } - - mPartHeader.put(P_CONTENT_LOCATION, contentLocation); - } - - /** - * Get Content-Location value. - * - * @return the value - * return PduPart.disposition[0] instead of (Form-data). - * return PduPart.disposition[1] instead of (Attachment). - * return PduPart.disposition[2] instead of (Inline). - */ - public byte[] getContentLocation() { - return (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - - /** - * Set Content-Disposition value. - * Use PduPart.disposition[0] instead of (Form-data). - * Use PduPart.disposition[1] instead of (Attachment). - * Use PduPart.disposition[2] instead of (Inline). - * - * @param contentDisposition the value - * @throws NullPointerException if the value is null. - */ - public void setContentDisposition(byte[] contentDisposition) { - if(contentDisposition == null) { - throw new NullPointerException("null content-disposition"); - } - - mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition); - } - - /** - * Get Content-Disposition value. - * - * @return the value - */ - public byte[] getContentDisposition() { - return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION); - } - - /** - * Set Content-Type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] contentType) { - if(contentType == null) { - throw new NullPointerException("null content-type"); - } - - mPartHeader.put(P_CONTENT_TYPE, contentType); - } - - /** - * Get Content-Type value of part. - * - * @return the value - */ - public byte[] getContentType() { - return (byte[]) mPartHeader.get(P_CONTENT_TYPE); - } - - /** - * Set Content-Transfer-Encoding value - * - * @param contentId the content-id value - * @throws NullPointerException if the value is null. - */ - public void setContentTransferEncoding(byte[] contentTransferEncoding) { - if(contentTransferEncoding == null) { - throw new NullPointerException("null content-transfer-encoding"); - } - - mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding); - } - - /** - * Get Content-Transfer-Encoding value. - * - * @return the value - */ - public byte[] getContentTransferEncoding() { - return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING); - } - - /** - * Set Content-type parameter: name. - * - * @param name the name value - * @throws NullPointerException if the value is null. - */ - public void setName(byte[] name) { - if(null == name) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_NAME, name); - } - - /** - * Get content-type parameter: name. - * - * @return the name - */ - public byte[] getName() { - return (byte[]) mPartHeader.get(P_NAME); - } - - /** - * Get Content-disposition parameter: filename - * - * @param fileName the filename value - * @throws NullPointerException if the value is null. - */ - public void setFilename(byte[] fileName) { - if(null == fileName) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_FILENAME, fileName); - } - - /** - * Set Content-disposition parameter: filename - * - * @return the filename - */ - public byte[] getFilename() { - return (byte[]) mPartHeader.get(P_FILENAME); - } - - public String generateLocation() { - // Assumption: At least one of the content-location / name / filename - // or content-id should be set. This is guaranteed by the PduParser - // for incoming messages and by MM composer for outgoing messages. - byte[] location = (byte[]) mPartHeader.get(P_NAME); - if(null == location) { - location = (byte[]) mPartHeader.get(P_FILENAME); - - if (null == location) { - location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - } - - if (null == location) { - byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID); - return "cid:" + new String(contentId); - } else { - return new String(location); - } - } -} - diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java deleted file mode 100644 index ee285aaba1c8..000000000000 --- a/core/java/com/google/android/mms/pdu/PduPersister.java +++ /dev/null @@ -1,1477 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.MmsException; -import com.google.android.mms.util.DownloadDrmHelper; -import com.google.android.mms.util.DrmConvertSession; -import com.google.android.mms.util.PduCache; -import com.google.android.mms.util.PduCacheEntry; -import com.google.android.mms.util.SqliteWrapper; - -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.sqlite.SQLiteException; -import android.drm.DrmManagerClient; -import android.net.Uri; -import android.os.FileUtils; -import android.provider.MediaStore; -import android.provider.Telephony; -import android.provider.Telephony.Mms; -import android.provider.Telephony.MmsSms; -import android.provider.Telephony.Threads; -import android.provider.Telephony.Mms.Addr; -import android.provider.Telephony.Mms.Part; -import android.provider.Telephony.MmsSms.PendingMessages; -import android.text.TextUtils; -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import com.google.android.mms.pdu.EncodedStringValue; - -/** - * This class is the high-level manager of PDU storage. - */ -public class PduPersister { - private static final String TAG = "PduPersister"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final long DUMMY_THREAD_ID = Long.MAX_VALUE; - - /** - * The uri of temporary drm objects. - */ - public static final String TEMPORARY_DRM_OBJECT_URI = - "content://mms/" + Long.MAX_VALUE + "/part"; - /** - * Indicate that we transiently failed to process a MM. - */ - public static final int PROC_STATUS_TRANSIENT_FAILURE = 1; - /** - * Indicate that we permanently failed to process a MM. - */ - public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2; - /** - * Indicate that we have successfully processed a MM. - */ - public static final int PROC_STATUS_COMPLETED = 3; - - private static PduPersister sPersister; - private static final PduCache PDU_CACHE_INSTANCE; - - private static final int[] ADDRESS_FIELDS = new int[] { - PduHeaders.BCC, - PduHeaders.CC, - PduHeaders.FROM, - PduHeaders.TO - }; - - private static final String[] PDU_PROJECTION = new String[] { - Mms._ID, - Mms.MESSAGE_BOX, - Mms.THREAD_ID, - Mms.RETRIEVE_TEXT, - Mms.SUBJECT, - Mms.CONTENT_LOCATION, - Mms.CONTENT_TYPE, - Mms.MESSAGE_CLASS, - Mms.MESSAGE_ID, - Mms.RESPONSE_TEXT, - Mms.TRANSACTION_ID, - Mms.CONTENT_CLASS, - Mms.DELIVERY_REPORT, - Mms.MESSAGE_TYPE, - Mms.MMS_VERSION, - Mms.PRIORITY, - Mms.READ_REPORT, - Mms.READ_STATUS, - Mms.REPORT_ALLOWED, - Mms.RETRIEVE_STATUS, - Mms.STATUS, - Mms.DATE, - Mms.DELIVERY_TIME, - Mms.EXPIRY, - Mms.MESSAGE_SIZE, - Mms.SUBJECT_CHARSET, - Mms.RETRIEVE_TEXT_CHARSET, - }; - - private static final int PDU_COLUMN_ID = 0; - private static final int PDU_COLUMN_MESSAGE_BOX = 1; - private static final int PDU_COLUMN_THREAD_ID = 2; - private static final int PDU_COLUMN_RETRIEVE_TEXT = 3; - private static final int PDU_COLUMN_SUBJECT = 4; - private static final int PDU_COLUMN_CONTENT_LOCATION = 5; - private static final int PDU_COLUMN_CONTENT_TYPE = 6; - private static final int PDU_COLUMN_MESSAGE_CLASS = 7; - private static final int PDU_COLUMN_MESSAGE_ID = 8; - private static final int PDU_COLUMN_RESPONSE_TEXT = 9; - private static final int PDU_COLUMN_TRANSACTION_ID = 10; - private static final int PDU_COLUMN_CONTENT_CLASS = 11; - private static final int PDU_COLUMN_DELIVERY_REPORT = 12; - private static final int PDU_COLUMN_MESSAGE_TYPE = 13; - private static final int PDU_COLUMN_MMS_VERSION = 14; - private static final int PDU_COLUMN_PRIORITY = 15; - private static final int PDU_COLUMN_READ_REPORT = 16; - private static final int PDU_COLUMN_READ_STATUS = 17; - private static final int PDU_COLUMN_REPORT_ALLOWED = 18; - private static final int PDU_COLUMN_RETRIEVE_STATUS = 19; - private static final int PDU_COLUMN_STATUS = 20; - private static final int PDU_COLUMN_DATE = 21; - private static final int PDU_COLUMN_DELIVERY_TIME = 22; - private static final int PDU_COLUMN_EXPIRY = 23; - private static final int PDU_COLUMN_MESSAGE_SIZE = 24; - private static final int PDU_COLUMN_SUBJECT_CHARSET = 25; - private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26; - - private static final String[] PART_PROJECTION = new String[] { - Part._ID, - Part.CHARSET, - Part.CONTENT_DISPOSITION, - Part.CONTENT_ID, - Part.CONTENT_LOCATION, - Part.CONTENT_TYPE, - Part.FILENAME, - Part.NAME, - Part.TEXT - }; - - private static final int PART_COLUMN_ID = 0; - private static final int PART_COLUMN_CHARSET = 1; - private static final int PART_COLUMN_CONTENT_DISPOSITION = 2; - private static final int PART_COLUMN_CONTENT_ID = 3; - private static final int PART_COLUMN_CONTENT_LOCATION = 4; - private static final int PART_COLUMN_CONTENT_TYPE = 5; - private static final int PART_COLUMN_FILENAME = 6; - private static final int PART_COLUMN_NAME = 7; - private static final int PART_COLUMN_TEXT = 8; - - private static final HashMap MESSAGE_BOX_MAP; - // These map are used for convenience in persist() and load(). - private static final HashMap CHARSET_COLUMN_INDEX_MAP; - private static final HashMap ENCODED_STRING_COLUMN_INDEX_MAP; - private static final HashMap TEXT_STRING_COLUMN_INDEX_MAP; - private static final HashMap OCTET_COLUMN_INDEX_MAP; - private static final HashMap LONG_COLUMN_INDEX_MAP; - private static final HashMap CHARSET_COLUMN_NAME_MAP; - private static final HashMap ENCODED_STRING_COLUMN_NAME_MAP; - private static final HashMap TEXT_STRING_COLUMN_NAME_MAP; - private static final HashMap OCTET_COLUMN_NAME_MAP; - private static final HashMap LONG_COLUMN_NAME_MAP; - - static { - MESSAGE_BOX_MAP = new HashMap(); - MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI, Mms.MESSAGE_BOX_INBOX); - MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI, Mms.MESSAGE_BOX_SENT); - MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI, Mms.MESSAGE_BOX_DRAFTS); - MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX); - - CHARSET_COLUMN_INDEX_MAP = new HashMap(); - CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET); - CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET); - - CHARSET_COLUMN_NAME_MAP = new HashMap(); - CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET); - CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET); - - // Encoded string field code -> column index/name map. - ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap(); - ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT); - ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT); - - ENCODED_STRING_COLUMN_NAME_MAP = new HashMap(); - ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT); - ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT); - - // Text string field code -> column index/name map. - TEXT_STRING_COLUMN_INDEX_MAP = new HashMap(); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID); - - TEXT_STRING_COLUMN_NAME_MAP = new HashMap(); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID); - - // Octet field code -> column index/name map. - OCTET_COLUMN_INDEX_MAP = new HashMap(); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS); - - OCTET_COLUMN_NAME_MAP = new HashMap(); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS); - - // Long field code -> column index/name map. - LONG_COLUMN_INDEX_MAP = new HashMap(); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE); - - LONG_COLUMN_NAME_MAP = new HashMap(); - LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE); - LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME); - LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY); - LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE); - - PDU_CACHE_INSTANCE = PduCache.getInstance(); - } - - private final Context mContext; - private final ContentResolver mContentResolver; - private final DrmManagerClient mDrmManagerClient; - - private PduPersister(Context context) { - mContext = context; - mContentResolver = context.getContentResolver(); - mDrmManagerClient = new DrmManagerClient(context); - } - - /** Get(or create if not exist) an instance of PduPersister */ - public static PduPersister getPduPersister(Context context) { - if ((sPersister == null) || !context.equals(sPersister.mContext)) { - sPersister = new PduPersister(context); - } - - return sPersister; - } - - private void setEncodedStringValueToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - String s = c.getString(columnIndex); - if ((s != null) && (s.length() > 0)) { - int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn); - int charset = c.getInt(charsetColumnIndex); - EncodedStringValue value = new EncodedStringValue( - charset, getBytes(s)); - headers.setEncodedStringValue(value, mapColumn); - } - } - - private void setTextStringToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - String s = c.getString(columnIndex); - if (s != null) { - headers.setTextString(getBytes(s), mapColumn); - } - } - - private void setOctetToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) throws InvalidHeaderValueException { - if (!c.isNull(columnIndex)) { - int b = c.getInt(columnIndex); - headers.setOctet(b, mapColumn); - } - } - - private void setLongToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - if (!c.isNull(columnIndex)) { - long l = c.getLong(columnIndex); - headers.setLongInteger(l, mapColumn); - } - } - - private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) { - if (!c.isNull(columnIndex)) { - return c.getInt(columnIndex); - } - return null; - } - - private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) { - if (!c.isNull(columnIndex)) { - return getBytes(c.getString(columnIndex)); - } - return null; - } - - private PduPart[] loadParts(long msgId) throws MmsException { - Cursor c = SqliteWrapper.query(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/part"), - PART_PROJECTION, null, null, null); - - PduPart[] parts = null; - - try { - if ((c == null) || (c.getCount() == 0)) { - if (LOCAL_LOGV) { - Log.v(TAG, "loadParts(" + msgId + "): no part to load."); - } - return null; - } - - int partCount = c.getCount(); - int partIdx = 0; - parts = new PduPart[partCount]; - while (c.moveToNext()) { - PduPart part = new PduPart(); - Integer charset = getIntegerFromPartColumn( - c, PART_COLUMN_CHARSET); - if (charset != null) { - part.setCharset(charset); - } - - byte[] contentDisposition = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_DISPOSITION); - if (contentDisposition != null) { - part.setContentDisposition(contentDisposition); - } - - byte[] contentId = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_ID); - if (contentId != null) { - part.setContentId(contentId); - } - - byte[] contentLocation = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_LOCATION); - if (contentLocation != null) { - part.setContentLocation(contentLocation); - } - - byte[] contentType = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_TYPE); - if (contentType != null) { - part.setContentType(contentType); - } else { - throw new MmsException("Content-Type must be set."); - } - - byte[] fileName = getByteArrayFromPartColumn( - c, PART_COLUMN_FILENAME); - if (fileName != null) { - part.setFilename(fileName); - } - - byte[] name = getByteArrayFromPartColumn( - c, PART_COLUMN_NAME); - if (name != null) { - part.setName(name); - } - - // Construct a Uri for this part. - long partId = c.getLong(PART_COLUMN_ID); - Uri partURI = Uri.parse("content://mms/part/" + partId); - part.setDataUri(partURI); - - // For images/audio/video, we won't keep their data in Part - // because their renderer accept Uri as source. - String type = toIsoString(contentType); - if (!ContentType.isImageType(type) - && !ContentType.isAudioType(type) - && !ContentType.isVideoType(type)) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - InputStream is = null; - - // Store simple string values directly in the database instead of an - // external file. This makes the text searchable and retrieval slightly - // faster. - if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type) - || ContentType.TEXT_HTML.equals(type)) { - String text = c.getString(PART_COLUMN_TEXT); - byte [] blob = new EncodedStringValue(text != null ? text : "") - .getTextString(); - baos.write(blob, 0, blob.length); - } else { - - try { - is = mContentResolver.openInputStream(partURI); - - byte[] buffer = new byte[256]; - int len = is.read(buffer); - while (len >= 0) { - baos.write(buffer, 0, len); - len = is.read(buffer); - } - } catch (IOException e) { - Log.e(TAG, "Failed to load part data", e); - c.close(); - throw new MmsException(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close stream", e); - } // Ignore - } - } - } - part.setData(baos.toByteArray()); - } - parts[partIdx++] = part; - } - } finally { - if (c != null) { - c.close(); - } - } - - return parts; - } - - private void loadAddress(long msgId, PduHeaders headers) { - Cursor c = SqliteWrapper.query(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/addr"), - new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE }, - null, null, null); - - if (c != null) { - try { - while (c.moveToNext()) { - String addr = c.getString(0); - if (!TextUtils.isEmpty(addr)) { - int addrType = c.getInt(2); - switch (addrType) { - case PduHeaders.FROM: - headers.setEncodedStringValue( - new EncodedStringValue(c.getInt(1), getBytes(addr)), - addrType); - break; - case PduHeaders.TO: - case PduHeaders.CC: - case PduHeaders.BCC: - headers.appendEncodedStringValue( - new EncodedStringValue(c.getInt(1), getBytes(addr)), - addrType); - break; - default: - Log.e(TAG, "Unknown address type: " + addrType); - break; - } - } - } - } finally { - c.close(); - } - } - } - - /** - * Load a PDU from storage by given Uri. - * - * @param uri The Uri of the PDU to be loaded. - * @return A generic PDU object, it may be cast to dedicated PDU. - * @throws MmsException Failed to load some fields of a PDU. - */ - public GenericPdu load(Uri uri) throws MmsException { - GenericPdu pdu = null; - PduCacheEntry cacheEntry = null; - int msgBox = 0; - long threadId = -1; - try { - synchronized(PDU_CACHE_INSTANCE) { - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "load: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "load: ", e); - } - cacheEntry = PDU_CACHE_INSTANCE.get(uri); - if (cacheEntry != null) { - return cacheEntry.getPdu(); - } - } - // Tell the cache to indicate to other callers that this item - // is currently being updated. - PDU_CACHE_INSTANCE.setUpdating(uri, true); - } - - Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri, - PDU_PROJECTION, null, null, null); - PduHeaders headers = new PduHeaders(); - Set> set; - long msgId = ContentUris.parseId(uri); - - try { - if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) { - throw new MmsException("Bad uri: " + uri); - } - - msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX); - threadId = c.getLong(PDU_COLUMN_THREAD_ID); - - set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet(); - for (Entry e : set) { - setEncodedStringValueToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet(); - for (Entry e : set) { - setTextStringToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = OCTET_COLUMN_INDEX_MAP.entrySet(); - for (Entry e : set) { - setOctetToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = LONG_COLUMN_INDEX_MAP.entrySet(); - for (Entry e : set) { - setLongToHeaders( - c, e.getValue(), headers, e.getKey()); - } - } finally { - if (c != null) { - c.close(); - } - } - - // Check whether 'msgId' has been assigned a valid value. - if (msgId == -1L) { - throw new MmsException("Error! ID of the message: -1."); - } - - // Load address information of the MM. - loadAddress(msgId, headers); - - int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE); - PduBody body = new PduBody(); - - // For PDU which type is M_retrieve.conf or Send.req, we should - // load multiparts and put them into the body of the PDU. - if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) - || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { - PduPart[] parts = loadParts(msgId); - if (parts != null) { - int partsNum = parts.length; - for (int i = 0; i < partsNum; i++) { - body.addPart(parts[i]); - } - } - } - - switch (msgType) { - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - pdu = new NotificationInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - pdu = new DeliveryInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - pdu = new ReadOrigInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - pdu = new RetrieveConf(headers, body); - break; - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - pdu = new SendReq(headers, body); - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - pdu = new AcknowledgeInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - pdu = new NotifyRespInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - pdu = new ReadRecInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: - case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: - case PduHeaders.MESSAGE_TYPE_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: - case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: - throw new MmsException( - "Unsupported PDU type: " + Integer.toHexString(msgType)); - - default: - throw new MmsException( - "Unrecognized PDU type: " + Integer.toHexString(msgType)); - } - } finally { - synchronized(PDU_CACHE_INSTANCE) { - if (pdu != null) { - assert(PDU_CACHE_INSTANCE.get(uri) == null); - // Update the cache entry with the real info - cacheEntry = new PduCacheEntry(pdu, msgBox, threadId); - PDU_CACHE_INSTANCE.put(uri, cacheEntry); - } - PDU_CACHE_INSTANCE.setUpdating(uri, false); - PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead - } - } - return pdu; - } - - private void persistAddress( - long msgId, int type, EncodedStringValue[] array) { - ContentValues values = new ContentValues(3); - - for (EncodedStringValue addr : array) { - values.clear(); // Clear all values first. - values.put(Addr.ADDRESS, toIsoString(addr.getTextString())); - values.put(Addr.CHARSET, addr.getCharacterSet()); - values.put(Addr.TYPE, type); - - Uri uri = Uri.parse("content://mms/" + msgId + "/addr"); - SqliteWrapper.insert(mContext, mContentResolver, uri, values); - } - } - - public Uri persistPart(PduPart part, long msgId) - throws MmsException { - Uri uri = Uri.parse("content://mms/" + msgId + "/part"); - ContentValues values = new ContentValues(8); - - int charset = part.getCharset(); - if (charset != 0 ) { - values.put(Part.CHARSET, charset); - } - - String contentType = null; - if (part.getContentType() != null) { - contentType = toIsoString(part.getContentType()); - - // There is no "image/jpg" in Android (and it's an invalid mimetype). - // Change it to "image/jpeg" - if (ContentType.IMAGE_JPG.equals(contentType)) { - contentType = ContentType.IMAGE_JPEG; - } - - values.put(Part.CONTENT_TYPE, contentType); - // To ensure the SMIL part is always the first part. - if (ContentType.APP_SMIL.equals(contentType)) { - values.put(Part.SEQ, -1); - } - } else { - throw new MmsException("MIME type of the part must be set."); - } - - if (part.getFilename() != null) { - String fileName = new String(part.getFilename()); - values.put(Part.FILENAME, fileName); - } - - if (part.getName() != null) { - String name = new String(part.getName()); - values.put(Part.NAME, name); - } - - Object value = null; - if (part.getContentDisposition() != null) { - value = toIsoString(part.getContentDisposition()); - values.put(Part.CONTENT_DISPOSITION, (String) value); - } - - if (part.getContentId() != null) { - value = toIsoString(part.getContentId()); - values.put(Part.CONTENT_ID, (String) value); - } - - if (part.getContentLocation() != null) { - value = toIsoString(part.getContentLocation()); - values.put(Part.CONTENT_LOCATION, (String) value); - } - - Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); - if (res == null) { - throw new MmsException("Failed to persist part, return null."); - } - - persistData(part, res, contentType); - // After successfully store the data, we should update - // the dataUri of the part. - part.setDataUri(res); - - return res; - } - - /** - * Save data of the part into storage. The source data may be given - * by a byte[] or a Uri. If it's a byte[], directly save it - * into storage, otherwise load source data from the dataUri and then - * save it. If the data is an image, we may scale down it according - * to user preference. - * - * @param part The PDU part which contains data to be saved. - * @param uri The URI of the part. - * @param contentType The MIME type of the part. - * @throws MmsException Cannot find source data or error occurred - * while saving the data. - */ - private void persistData(PduPart part, Uri uri, - String contentType) - throws MmsException { - OutputStream os = null; - InputStream is = null; - DrmConvertSession drmConvertSession = null; - Uri dataUri = null; - String path = null; - - try { - byte[] data = part.getData(); - if (ContentType.TEXT_PLAIN.equals(contentType) - || ContentType.APP_SMIL.equals(contentType) - || ContentType.TEXT_HTML.equals(contentType)) { - ContentValues cv = new ContentValues(); - cv.put(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString()); - if (mContentResolver.update(uri, cv, null, null) != 1) { - throw new MmsException("unable to update " + uri.toString()); - } - } else { - boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType); - if (isDrm) { - if (uri != null) { - try { - path = convertUriToPath(mContext, uri); - if (LOCAL_LOGV) { - Log.v(TAG, "drm uri: " + uri + " path: " + path); - } - File f = new File(path); - long len = f.length(); - if (LOCAL_LOGV) { - Log.v(TAG, "drm path: " + path + " len: " + len); - } - if (len > 0) { - // we're not going to re-persist and re-encrypt an already - // converted drm file - return; - } - } catch (Exception e) { - Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e); - } - } - // We haven't converted the file yet, start the conversion - drmConvertSession = DrmConvertSession.open(mContext, contentType); - if (drmConvertSession == null) { - throw new MmsException("Mimetype " + contentType + - " can not be converted."); - } - } - os = mContentResolver.openOutputStream(uri); - if (data == null) { - dataUri = part.getDataUri(); - if ((dataUri == null) || (dataUri == uri)) { - Log.w(TAG, "Can't find data for this part."); - return; - } - is = mContentResolver.openInputStream(dataUri); - - if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); - } - - byte[] buffer = new byte[8192]; - for (int len = 0; (len = is.read(buffer)) != -1; ) { - if (!isDrm) { - os.write(buffer, 0, len); - } else { - byte[] convertedData = drmConvertSession.convert(buffer, len); - if (convertedData != null) { - os.write(convertedData, 0, convertedData.length); - } else { - throw new MmsException("Error converting drm data."); - } - } - } - } else { - if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); - } - if (!isDrm) { - os.write(data); - } else { - dataUri = uri; - byte[] convertedData = drmConvertSession.convert(data, data.length); - if (convertedData != null) { - os.write(convertedData, 0, convertedData.length); - } else { - throw new MmsException("Error converting drm data."); - } - } - } - } - } catch (FileNotFoundException e) { - Log.e(TAG, "Failed to open Input/Output stream.", e); - throw new MmsException(e); - } catch (IOException e) { - Log.e(TAG, "Failed to read/write data.", e); - throw new MmsException(e); - } finally { - if (os != null) { - try { - os.close(); - } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + os, e); - } // Ignore - } - if (is != null) { - try { - is.close(); - } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + is, e); - } // Ignore - } - if (drmConvertSession != null) { - drmConvertSession.close(path); - - // Reset the permissions on the encrypted part file so everyone has only read - // permission. - File f = new File(path); - ContentValues values = new ContentValues(0); - SqliteWrapper.update(mContext, mContentResolver, - Uri.parse("content://mms/resetFilePerm/" + f.getName()), - values, null, null); - } - } - } - - /** - * This method expects uri in the following format - * content://media// (or) - * file://sdcard/test.mp4 - * http://test.com/test.mp4 - * - * Here shall be "video" or "audio" or "images" - * the index of the content in given table - */ - static public String convertUriToPath(Context context, Uri uri) { - String path = null; - if (null != uri) { - String scheme = uri.getScheme(); - if (null == scheme || scheme.equals("") || - scheme.equals(ContentResolver.SCHEME_FILE)) { - path = uri.getPath(); - - } else if (scheme.equals("http")) { - path = uri.toString(); - - } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { - String[] projection = new String[] {MediaStore.MediaColumns.DATA}; - Cursor cursor = null; - try { - cursor = context.getContentResolver().query(uri, projection, null, - null, null); - if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) { - throw new IllegalArgumentException("Given Uri could not be found" + - " in media store"); - } - int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); - path = cursor.getString(pathIndex); - } catch (SQLiteException e) { - throw new IllegalArgumentException("Given Uri is not formatted in a way " + - "so that it can be found in media store."); - } finally { - if (null != cursor) { - cursor.close(); - } - } - } else { - throw new IllegalArgumentException("Given Uri scheme is not supported"); - } - } - return path; - } - - private void updateAddress( - long msgId, int type, EncodedStringValue[] array) { - // Delete old address information and then insert new ones. - SqliteWrapper.delete(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/addr"), - Addr.TYPE + "=" + type, null); - - persistAddress(msgId, type, array); - } - - /** - * Update headers of a SendReq. - * - * @param uri The PDU which need to be updated. - * @param pdu New headers. - * @throws MmsException Bad URI or updating failed. - */ - public void updateHeaders(Uri uri, SendReq sendReq) { - synchronized(PDU_CACHE_INSTANCE) { - // If the cache item is getting updated, wait until it's done updating before - // purging it. - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "updateHeaders: ", e); - } - } - } - PDU_CACHE_INSTANCE.purge(uri); - - ContentValues values = new ContentValues(10); - byte[] contentType = sendReq.getContentType(); - if (contentType != null) { - values.put(Mms.CONTENT_TYPE, toIsoString(contentType)); - } - - long date = sendReq.getDate(); - if (date != -1) { - values.put(Mms.DATE, date); - } - - int deliveryReport = sendReq.getDeliveryReport(); - if (deliveryReport != 0) { - values.put(Mms.DELIVERY_REPORT, deliveryReport); - } - - long expiry = sendReq.getExpiry(); - if (expiry != -1) { - values.put(Mms.EXPIRY, expiry); - } - - byte[] msgClass = sendReq.getMessageClass(); - if (msgClass != null) { - values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass)); - } - - int priority = sendReq.getPriority(); - if (priority != 0) { - values.put(Mms.PRIORITY, priority); - } - - int readReport = sendReq.getReadReport(); - if (readReport != 0) { - values.put(Mms.READ_REPORT, readReport); - } - - byte[] transId = sendReq.getTransactionId(); - if (transId != null) { - values.put(Mms.TRANSACTION_ID, toIsoString(transId)); - } - - EncodedStringValue subject = sendReq.getSubject(); - if (subject != null) { - values.put(Mms.SUBJECT, toIsoString(subject.getTextString())); - values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet()); - } else { - values.put(Mms.SUBJECT, ""); - } - - long messageSize = sendReq.getMessageSize(); - if (messageSize > 0) { - values.put(Mms.MESSAGE_SIZE, messageSize); - } - - PduHeaders headers = sendReq.getPduHeaders(); - HashSet recipients = new HashSet(); - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = null; - if (addrType == PduHeaders.FROM) { - EncodedStringValue v = headers.getEncodedStringValue(addrType); - if (v != null) { - array = new EncodedStringValue[1]; - array[0] = v; - } - } else { - array = headers.getEncodedStringValues(addrType); - } - - if (array != null) { - long msgId = ContentUris.parseId(uri); - updateAddress(msgId, addrType, array); - if (addrType == PduHeaders.TO) { - for (EncodedStringValue v : array) { - if (v != null) { - recipients.add(v.getString()); - } - } - } - } - } - if (!recipients.isEmpty()) { - long threadId = Threads.getOrCreateThreadId(mContext, recipients); - values.put(Mms.THREAD_ID, threadId); - } - - SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); - } - - private void updatePart(Uri uri, PduPart part) throws MmsException { - ContentValues values = new ContentValues(7); - - int charset = part.getCharset(); - if (charset != 0 ) { - values.put(Part.CHARSET, charset); - } - - String contentType = null; - if (part.getContentType() != null) { - contentType = toIsoString(part.getContentType()); - values.put(Part.CONTENT_TYPE, contentType); - } else { - throw new MmsException("MIME type of the part must be set."); - } - - if (part.getFilename() != null) { - String fileName = new String(part.getFilename()); - values.put(Part.FILENAME, fileName); - } - - if (part.getName() != null) { - String name = new String(part.getName()); - values.put(Part.NAME, name); - } - - Object value = null; - if (part.getContentDisposition() != null) { - value = toIsoString(part.getContentDisposition()); - values.put(Part.CONTENT_DISPOSITION, (String) value); - } - - if (part.getContentId() != null) { - value = toIsoString(part.getContentId()); - values.put(Part.CONTENT_ID, (String) value); - } - - if (part.getContentLocation() != null) { - value = toIsoString(part.getContentLocation()); - values.put(Part.CONTENT_LOCATION, (String) value); - } - - SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); - - // Only update the data when: - // 1. New binary data supplied or - // 2. The Uri of the part is different from the current one. - if ((part.getData() != null) - || (uri != part.getDataUri())) { - persistData(part, uri, contentType); - } - } - - /** - * Update all parts of a PDU. - * - * @param uri The PDU which need to be updated. - * @param body New message body of the PDU. - * @throws MmsException Bad URI or updating failed. - */ - public void updateParts(Uri uri, PduBody body) - throws MmsException { - try { - PduCacheEntry cacheEntry; - synchronized(PDU_CACHE_INSTANCE) { - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "updateParts: ", e); - } - cacheEntry = PDU_CACHE_INSTANCE.get(uri); - if (cacheEntry != null) { - ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body); - } - } - // Tell the cache to indicate to other callers that this item - // is currently being updated. - PDU_CACHE_INSTANCE.setUpdating(uri, true); - } - - ArrayList toBeCreated = new ArrayList(); - HashMap toBeUpdated = new HashMap(); - - int partsNum = body.getPartsNum(); - StringBuilder filter = new StringBuilder().append('('); - for (int i = 0; i < partsNum; i++) { - PduPart part = body.getPart(i); - Uri partUri = part.getDataUri(); - if ((partUri == null) || !partUri.getAuthority().startsWith("mms")) { - toBeCreated.add(part); - } else { - toBeUpdated.put(partUri, part); - - // Don't use 'i > 0' to determine whether we should append - // 'AND' since 'i = 0' may be skipped in another branch. - if (filter.length() > 1) { - filter.append(" AND "); - } - - filter.append(Part._ID); - filter.append("!="); - DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment()); - } - } - filter.append(')'); - - long msgId = ContentUris.parseId(uri); - - // Remove the parts which doesn't exist anymore. - SqliteWrapper.delete(mContext, mContentResolver, - Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"), - filter.length() > 2 ? filter.toString() : null, null); - - // Create new parts which didn't exist before. - for (PduPart part : toBeCreated) { - persistPart(part, msgId); - } - - // Update the modified parts. - for (Map.Entry e : toBeUpdated.entrySet()) { - updatePart(e.getKey(), e.getValue()); - } - } finally { - synchronized(PDU_CACHE_INSTANCE) { - PDU_CACHE_INSTANCE.setUpdating(uri, false); - PDU_CACHE_INSTANCE.notifyAll(); - } - } - } - - /** - * Persist a PDU object to specific location in the storage. - * - * @param pdu The PDU object to be stored. - * @param uri Where to store the given PDU object. - * @return A Uri which can be used to access the stored PDU. - */ - public Uri persist(GenericPdu pdu, Uri uri) throws MmsException { - if (uri == null) { - throw new MmsException("Uri may not be null."); - } - long msgId = -1; - try { - msgId = ContentUris.parseId(uri); - } catch (NumberFormatException e) { - // the uri ends with "inbox" or something else like that - } - boolean existingUri = msgId != -1; - - if (!existingUri && MESSAGE_BOX_MAP.get(uri) == null) { - throw new MmsException( - "Bad destination, must be one of " - + "content://mms/inbox, content://mms/sent, " - + "content://mms/drafts, content://mms/outbox, " - + "content://mms/temp."); - } - synchronized(PDU_CACHE_INSTANCE) { - // If the cache item is getting updated, wait until it's done updating before - // purging it. - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "persist: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "persist1: ", e); - } - } - } - PDU_CACHE_INSTANCE.purge(uri); - - PduHeaders header = pdu.getPduHeaders(); - PduBody body = null; - ContentValues values = new ContentValues(); - Set> set; - - set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet(); - for (Entry e : set) { - int field = e.getKey(); - EncodedStringValue encodedString = header.getEncodedStringValue(field); - if (encodedString != null) { - String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field); - values.put(e.getValue(), toIsoString(encodedString.getTextString())); - values.put(charsetColumn, encodedString.getCharacterSet()); - } - } - - set = TEXT_STRING_COLUMN_NAME_MAP.entrySet(); - for (Entry e : set){ - byte[] text = header.getTextString(e.getKey()); - if (text != null) { - values.put(e.getValue(), toIsoString(text)); - } - } - - set = OCTET_COLUMN_NAME_MAP.entrySet(); - for (Entry e : set){ - int b = header.getOctet(e.getKey()); - if (b != 0) { - values.put(e.getValue(), b); - } - } - - set = LONG_COLUMN_NAME_MAP.entrySet(); - for (Entry e : set){ - long l = header.getLongInteger(e.getKey()); - if (l != -1L) { - values.put(e.getValue(), l); - } - } - - HashMap addressMap = - new HashMap(ADDRESS_FIELDS.length); - // Save address information. - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = null; - if (addrType == PduHeaders.FROM) { - EncodedStringValue v = header.getEncodedStringValue(addrType); - if (v != null) { - array = new EncodedStringValue[1]; - array[0] = v; - } - } else { - array = header.getEncodedStringValues(addrType); - } - addressMap.put(addrType, array); - } - - HashSet recipients = new HashSet(); - int msgType = pdu.getMessageType(); - // Here we only allocate thread ID for M-Notification.ind, - // M-Retrieve.conf and M-Send.req. - // Some of other PDU types may be allocated a thread ID outside - // this scope. - if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) - || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) - || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { - EncodedStringValue[] array = null; - switch (msgType) { - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - array = addressMap.get(PduHeaders.FROM); - break; - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - array = addressMap.get(PduHeaders.TO); - break; - } - - if (array != null) { - for (EncodedStringValue v : array) { - if (v != null) { - recipients.add(v.getString()); - } - } - } - if (!recipients.isEmpty()) { - long threadId = Threads.getOrCreateThreadId(mContext, recipients); - values.put(Mms.THREAD_ID, threadId); - } - } - - // Save parts first to avoid inconsistent message is loaded - // while saving the parts. - long dummyId = System.currentTimeMillis(); // Dummy ID of the msg. - // Get body if the PDU is a RetrieveConf or SendReq. - if (pdu instanceof MultimediaMessagePdu) { - body = ((MultimediaMessagePdu) pdu).getBody(); - // Start saving parts if necessary. - if (body != null) { - int partsNum = body.getPartsNum(); - for (int i = 0; i < partsNum; i++) { - PduPart part = body.getPart(i); - persistPart(part, dummyId); - } - } - } - - Uri res = null; - if (existingUri) { - res = uri; - SqliteWrapper.update(mContext, mContentResolver, res, values, null, null); - } else { - res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); - if (res == null) { - throw new MmsException("persist() failed: return null."); - } - // Get the real ID of the PDU and update all parts which were - // saved with the dummy ID. - msgId = ContentUris.parseId(res); - } - - values = new ContentValues(1); - values.put(Part.MSG_ID, msgId); - SqliteWrapper.update(mContext, mContentResolver, - Uri.parse("content://mms/" + dummyId + "/part"), - values, null, null); - // We should return the longest URI of the persisted PDU, for - // example, if input URI is "content://mms/inbox" and the _ID of - // persisted PDU is '8', we should return "content://mms/inbox/8" - // instead of "content://mms/8". - // FIXME: Should the MmsProvider be responsible for this??? - if (!existingUri) { - res = Uri.parse(uri + "/" + msgId); - } - - // Save address information. - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = addressMap.get(addrType); - if (array != null) { - persistAddress(msgId, addrType, array); - } - } - - return res; - } - - /** - * Move a PDU object from one location to another. - * - * @param from Specify the PDU object to be moved. - * @param to The destination location, should be one of the following: - * "content://mms/inbox", "content://mms/sent", - * "content://mms/drafts", "content://mms/outbox", - * "content://mms/trash". - * @return New Uri of the moved PDU. - * @throws MmsException Error occurred while moving the message. - */ - public Uri move(Uri from, Uri to) throws MmsException { - // Check whether the 'msgId' has been assigned a valid value. - long msgId = ContentUris.parseId(from); - if (msgId == -1L) { - throw new MmsException("Error! ID of the message: -1."); - } - - // Get corresponding int value of destination box. - Integer msgBox = MESSAGE_BOX_MAP.get(to); - if (msgBox == null) { - throw new MmsException( - "Bad destination, must be one of " - + "content://mms/inbox, content://mms/sent, " - + "content://mms/drafts, content://mms/outbox, " - + "content://mms/temp."); - } - - ContentValues values = new ContentValues(1); - values.put(Mms.MESSAGE_BOX, msgBox); - SqliteWrapper.update(mContext, mContentResolver, from, values, null, null); - return ContentUris.withAppendedId(to, msgId); - } - - /** - * Wrap a byte[] into a String. - */ - public static String toIsoString(byte[] bytes) { - try { - return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); - return ""; - } - } - - /** - * Unpack a given String into a byte[]. - */ - public static byte[] getBytes(String data) { - try { - return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); - return new byte[0]; - } - } - - /** - * Remove all objects in the temporary path. - */ - public void release() { - Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI); - SqliteWrapper.delete(mContext, mContentResolver, uri, null, null); - } - - /** - * Find all messages to be sent or downloaded before certain time. - */ - public Cursor getPendingMessages(long dueTime) { - Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); - uriBuilder.appendQueryParameter("protocol", "mms"); - - String selection = PendingMessages.ERROR_TYPE + " < ?" - + " AND " + PendingMessages.DUE_TIME + " <= ?"; - - String[] selectionArgs = new String[] { - String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT), - String.valueOf(dueTime) - }; - - return SqliteWrapper.query(mContext, mContentResolver, - uriBuilder.build(), null, selection, selectionArgs, - PendingMessages.DUE_TIME); - } -} diff --git a/core/java/com/google/android/mms/pdu/QuotedPrintable.java b/core/java/com/google/android/mms/pdu/QuotedPrintable.java deleted file mode 100644 index a34ed1263891..000000000000 --- a/core/java/com/google/android/mms/pdu/QuotedPrintable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import java.io.ByteArrayOutputStream; - -public class QuotedPrintable { - private static byte ESCAPE_CHAR = '='; - - /** - * Decodes an array quoted-printable characters into an array of original bytes. - * Escaped characters are converted back to their original representation. - * - *

- * This function implements a subset of - * quoted-printable encoding specification (rule #1 and rule #2) - * as defined in RFC 1521. - *

- * - * @param bytes array of quoted-printable characters - * @return array of original bytes, - * null if quoted-printable decoding is unsuccessful. - */ - public static final byte[] decodeQuotedPrintable(byte[] bytes) { - if (bytes == null) { - return null; - } - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - for (int i = 0; i < bytes.length; i++) { - int b = bytes[i]; - if (b == ESCAPE_CHAR) { - try { - if('\r' == (char)bytes[i + 1] && - '\n' == (char)bytes[i + 2]) { - i += 2; - continue; - } - int u = Character.digit((char) bytes[++i], 16); - int l = Character.digit((char) bytes[++i], 16); - if (u == -1 || l == -1) { - return null; - } - buffer.write((char) ((u << 4) + l)); - } catch (ArrayIndexOutOfBoundsException e) { - return null; - } - } else { - buffer.write(b); - } - } - return buffer.toByteArray(); - } -} diff --git a/core/java/com/google/android/mms/pdu/ReadOrigInd.java b/core/java/com/google/android/mms/pdu/ReadOrigInd.java deleted file mode 100644 index 1bfc0bb3e258..000000000000 --- a/core/java/com/google/android/mms/pdu/ReadOrigInd.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -public class ReadOrigInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public ReadOrigInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - ReadOrigInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/ReadRecInd.java b/core/java/com/google/android/mms/pdu/ReadRecInd.java deleted file mode 100644 index 880e3ac3ddd4..000000000000 --- a/core/java/com/google/android/mms/pdu/ReadRecInd.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -public class ReadRecInd extends GenericPdu { - /** - * Constructor, used when composing a M-ReadRec.ind pdu. - * - * @param from the from value - * @param messageId the message ID value - * @param mmsVersion current viersion of mms - * @param readStatus the read status value - * @param to the to value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if messageId or to is null. - */ - public ReadRecInd(EncodedStringValue from, - byte[] messageId, - int mmsVersion, - int readStatus, - EncodedStringValue[] to) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - setFrom(from); - setMessageId(messageId); - setMmsVersion(mmsVersion); - setTo(to); - setReadStatus(readStatus); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - ReadRecInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/RetrieveConf.java b/core/java/com/google/android/mms/pdu/RetrieveConf.java deleted file mode 100644 index 98e67c068d98..000000000000 --- a/core/java/com/google/android/mms/pdu/RetrieveConf.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Retrive.conf Pdu. - */ -public class RetrieveConf extends MultimediaMessagePdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public RetrieveConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - RetrieveConf(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - RetrieveConf(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get CC value. - * - * @return the value - */ - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Get X-Mms-Retrieve-Status value. - * - * @return the value - */ - public int getRetrieveStatus() { - return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS); - } - - /** - * Set X-Mms-Retrieve-Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setRetrieveStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS); - } - - /** - * Get X-Mms-Retrieve-Text value. - * - * @return the value - */ - public EncodedStringValue getRetrieveText() { - return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT); - } - - /** - * Set X-Mms-Retrieve-Text value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setRetrieveText(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public PreviouslySentByValue getPreviouslySentBy() {return null;} - * public void setPreviouslySentBy(PreviouslySentByValue value) {} - * - * public PreviouslySentDateValue getPreviouslySentDate() {} - * public void setPreviouslySentDate(PreviouslySentDateValue value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/SendConf.java b/core/java/com/google/android/mms/pdu/SendConf.java deleted file mode 100644 index 0568fe79c5ff..000000000000 --- a/core/java/com/google/android/mms/pdu/SendConf.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * 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.google.android.mms.pdu; - -import com.google.android.mms.InvalidHeaderValueException; - -public class SendConf extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public SendConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - SendConf(PduHeaders headers) { - super(headers); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Response-Status. - * - * @return the value - */ - public int getResponseStatus() { - return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS); - } - - /** - * Set X-Mms-Response-Status. - * - * @param value the values - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setResponseStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getContentLocation() {return null;} - * public void setContentLocation(byte[] value) {} - * - * public EncodedStringValue getResponseText() {return null;} - * public void setResponseText(EncodedStringValue value) {} - * - * public byte getStoreStatus() {return 0x00;} - * public void setStoreStatus(byte value) {} - * - * public byte[] getStoreStatusText() {return null;} - * public void setStoreStatusText(byte[] value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java deleted file mode 100644 index 597cd00b9961..000000000000 --- a/core/java/com/google/android/mms/pdu/SendReq.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-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.google.android.mms.pdu; - -import android.util.Log; - -import com.google.android.mms.InvalidHeaderValueException; - -public class SendReq extends MultimediaMessagePdu { - private static final String TAG = "SendReq"; - - public SendReq() { - super(); - - try { - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setMmsVersion(PduHeaders.CURRENT_MMS_VERSION); - // FIXME: Content-type must be decided according to whether - // SMIL part present. - setContentType("application/vnd.wap.multipart.related".getBytes()); - setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes())); - setTransactionId(generateTransactionId()); - } catch (InvalidHeaderValueException e) { - // Impossible to reach here since all headers we set above are valid. - Log.e(TAG, "Unexpected InvalidHeaderValueException.", e); - throw new RuntimeException(e); - } - } - - private byte[] generateTransactionId() { - String transactionId = "T" + Long.toHexString(System.currentTimeMillis()); - return transactionId.getBytes(); - } - - /** - * Constructor, used when composing a M-Send.req pdu. - * - * @param contentType the content type value - * @param from the from value - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if contentType, form or transactionId is null. - */ - public SendReq(byte[] contentType, - EncodedStringValue from, - int mmsVersion, - byte[] transactionId) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setContentType(contentType); - setFrom(from); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - SendReq(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - SendReq(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get Bcc value. - * - * @return the value - */ - public EncodedStringValue[] getBcc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.BCC); - } - - /** - * Add a "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addBcc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC); - } - - /** - * Set "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setBcc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC); - } - - /** - * Get CC value. - * - * @return the value - */ - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Set "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setCc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - */ - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get X-Mms-MessageSize value. - * - * Expiry-value = size of message - * - * @return the value - */ - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-MessageSize value. - * - * @param value the value - */ - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Set "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte getAdaptationAllowed() {return 0}; - * public void setAdaptationAllowed(btye value) {}; - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public long getDeliveryTime() {return 0}; - * public void setDeliveryTime(long value) {}; - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getStore() {return 0x00;} - * public void setStore(byte value) {} - */ -} diff --git a/core/java/com/google/android/mms/pdu/package.html b/core/java/com/google/android/mms/pdu/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/core/java/com/google/android/mms/pdu/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - - diff --git a/core/java/com/google/android/mms/util/AbstractCache.java b/core/java/com/google/android/mms/util/AbstractCache.java deleted file mode 100644 index 39b2abf15a64..000000000000 --- a/core/java/com/google/android/mms/util/AbstractCache.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * 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.google.android.mms.util; - -import android.util.Log; - -import java.util.HashMap; - -public abstract class AbstractCache { - private static final String TAG = "AbstractCache"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final int MAX_CACHED_ITEMS = 500; - - private final HashMap> mCacheMap; - - protected AbstractCache() { - mCacheMap = new HashMap>(); - } - - public boolean put(K key, V value) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to put " + key + " into cache."); - } - - if (mCacheMap.size() >= MAX_CACHED_ITEMS) { - // TODO Should remove the oldest or least hit cached entry - // and then cache the new one. - if (LOCAL_LOGV) { - Log.v(TAG, "Failed! size limitation reached."); - } - return false; - } - - if (key != null) { - CacheEntry cacheEntry = new CacheEntry(); - cacheEntry.value = value; - mCacheMap.put(key, cacheEntry); - - if (LOCAL_LOGV) { - Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total."); - } - return true; - } - return false; - } - - public V get(K key) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to get " + key + " from cache."); - } - - if (key != null) { - CacheEntry cacheEntry = mCacheMap.get(key); - if (cacheEntry != null) { - cacheEntry.hit++; - if (LOCAL_LOGV) { - Log.v(TAG, key + " hit " + cacheEntry.hit + " times."); - } - return cacheEntry.value; - } - } - return null; - } - - public V purge(K key) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to purge " + key); - } - - CacheEntry v = mCacheMap.remove(key); - - if (LOCAL_LOGV) { - Log.v(TAG, mCacheMap.size() + " items cached."); - } - - return v != null ? v.value : null; - } - - public void purgeAll() { - if (LOCAL_LOGV) { - Log.v(TAG, "Purging cache, " + mCacheMap.size() - + " items dropped."); - } - mCacheMap.clear(); - } - - public int size() { - return mCacheMap.size(); - } - - private static class CacheEntry { - int hit; - V value; - } -} diff --git a/core/java/com/google/android/mms/util/DownloadDrmHelper.java b/core/java/com/google/android/mms/util/DownloadDrmHelper.java deleted file mode 100644 index 6852eca4890d..000000000000 --- a/core/java/com/google/android/mms/util/DownloadDrmHelper.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2012 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.google.android.mms.util; - -import android.content.Context; -import android.drm.DrmManagerClient; -import android.util.Log; - -public class DownloadDrmHelper { - private static final String TAG = "DownloadDrmHelper"; - - /** The MIME type of special DRM files */ - public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message"; - - /** The extensions of special DRM files */ - public static final String EXTENSION_DRM_MESSAGE = ".dm"; - - public static final String EXTENSION_INTERNAL_FWDL = ".fl"; - - /** - * Checks if the Media Type is a DRM Media Type - * - * @param drmManagerClient A DrmManagerClient - * @param mimetype Media Type to check - * @return True if the Media Type is DRM else false - */ - public static boolean isDrmMimeType(Context context, String mimetype) { - boolean result = false; - if (context != null) { - try { - DrmManagerClient drmClient = new DrmManagerClient(context); - if (drmClient != null && mimetype != null && mimetype.length() > 0) { - result = drmClient.canHandle("", mimetype); - } - } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); - } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - } - return result; - } - - /** - * Checks if the Media Type needs to be DRM converted - * - * @param mimetype Media type of the content - * @return True if convert is needed else false - */ - public static boolean isDrmConvertNeeded(String mimetype) { - return MIMETYPE_DRM_MESSAGE.equals(mimetype); - } - - /** - * Modifies the file extension for a DRM Forward Lock file NOTE: This - * function shouldn't be called if the file shouldn't be DRM converted - */ - public static String modifyDrmFwLockFileExtension(String filename) { - if (filename != null) { - int extensionIndex; - extensionIndex = filename.lastIndexOf("."); - if (extensionIndex != -1) { - filename = filename.substring(0, extensionIndex); - } - filename = filename.concat(EXTENSION_INTERNAL_FWDL); - } - return filename; - } - - /** - * Gets the original mime type of DRM protected content. - * - * @param context The context - * @param path Path to the file - * @param containingMime The current mime type of of the file i.e. the - * containing mime type - * @return The original mime type of the file if DRM protected else the - * currentMime - */ - public static String getOriginalMimeType(Context context, String path, String containingMime) { - String result = containingMime; - DrmManagerClient drmClient = new DrmManagerClient(context); - try { - if (drmClient.canHandle(path, null)) { - result = drmClient.getOriginalMimeType(path); - } - } catch (IllegalArgumentException ex) { - Log.w(TAG, - "Can't get original mime type since path is null or empty string."); - } catch (IllegalStateException ex) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - return result; - } -} diff --git a/core/java/com/google/android/mms/util/DrmConvertSession.java b/core/java/com/google/android/mms/util/DrmConvertSession.java deleted file mode 100644 index 2d8f274f2bd4..000000000000 --- a/core/java/com/google/android/mms/util/DrmConvertSession.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2012 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.google.android.mms.util; - -import android.content.Context; -import android.drm.DrmConvertedStatus; -import android.drm.DrmManagerClient; -import android.util.Log; -import android.provider.Downloads; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; - - -public class DrmConvertSession { - private DrmManagerClient mDrmClient; - private int mConvertSessionId; - private static final String TAG = "DrmConvertSession"; - - private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) { - mDrmClient = drmClient; - mConvertSessionId = convertSessionId; - } - - /** - * Start of converting a file. - * - * @param context The context of the application running the convert session. - * @param mimeType Mimetype of content that shall be converted. - * @return A convert session or null in case an error occurs. - */ - public static DrmConvertSession open(Context context, String mimeType) { - DrmManagerClient drmClient = null; - int convertSessionId = -1; - if (context != null && mimeType != null && !mimeType.equals("")) { - try { - drmClient = new DrmManagerClient(context); - try { - convertSessionId = drmClient.openConvertSession(mimeType); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Conversion of Mimetype: " + mimeType - + " is not supported.", e); - } catch (IllegalStateException e) { - Log.w(TAG, "Could not access Open DrmFramework.", e); - } - } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); - } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - } - - if (drmClient == null || convertSessionId < 0) { - return null; - } else { - return new DrmConvertSession(drmClient, convertSessionId); - } - } - /** - * Convert a buffer of data to protected format. - * - * @param buffer Buffer filled with data to convert. - * @param size The number of bytes that shall be converted. - * @return A Buffer filled with converted data, if execution is ok, in all - * other case null. - */ - public byte [] convert(byte[] inBuffer, int size) { - byte[] result = null; - if (inBuffer != null) { - DrmConvertedStatus convertedStatus = null; - try { - if (size != inBuffer.length) { - byte[] buf = new byte[size]; - System.arraycopy(inBuffer, 0, buf, 0, size); - convertedStatus = mDrmClient.convertData(mConvertSessionId, buf); - } else { - convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer); - } - - if (convertedStatus != null && - convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK && - convertedStatus.convertedData != null) { - result = convertedStatus.convertedData; - } - } catch (IllegalArgumentException e) { - Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: " - + mConvertSessionId, e); - } catch (IllegalStateException e) { - Log.w(TAG, "Could not convert data. Convertsession: " + - mConvertSessionId, e); - } - } else { - throw new IllegalArgumentException("Parameter inBuffer is null"); - } - return result; - } - - /** - * Ends a conversion session of a file. - * - * @param fileName The filename of the converted file. - * @return Downloads.Impl.STATUS_SUCCESS if execution is ok. - * Downloads.Impl.STATUS_FILE_ERROR in case converted file can not - * be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem - * occurs when accessing drm framework. - * Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred. - */ - public int close(String filename) { - DrmConvertedStatus convertedStatus = null; - int result = Downloads.Impl.STATUS_UNKNOWN_ERROR; - if (mDrmClient != null && mConvertSessionId >= 0) { - try { - convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId); - if (convertedStatus == null || - convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK || - convertedStatus.convertedData == null) { - result = Downloads.Impl.STATUS_NOT_ACCEPTABLE; - } else { - RandomAccessFile rndAccessFile = null; - try { - rndAccessFile = new RandomAccessFile(filename, "rw"); - rndAccessFile.seek(convertedStatus.offset); - rndAccessFile.write(convertedStatus.convertedData); - result = Downloads.Impl.STATUS_SUCCESS; - } catch (FileNotFoundException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "File: " + filename + " could not be found.", e); - } catch (IOException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Could not access File: " + filename + " .", e); - } catch (IllegalArgumentException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Could not open file in mode: rw", e); - } catch (SecurityException e) { - Log.w(TAG, "Access to File: " + filename + - " was denied denied by SecurityManager.", e); - } finally { - if (rndAccessFile != null) { - try { - rndAccessFile.close(); - } catch (IOException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Failed to close File:" + filename - + ".", e); - } - } - } - } - } catch (IllegalStateException e) { - Log.w(TAG, "Could not close convertsession. Convertsession: " + - mConvertSessionId, e); - } - } - return result; - } -} diff --git a/core/java/com/google/android/mms/util/PduCache.java b/core/java/com/google/android/mms/util/PduCache.java deleted file mode 100644 index de83124bad7b..000000000000 --- a/core/java/com/google/android/mms/util/PduCache.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * 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.google.android.mms.util; - -import android.content.ContentUris; -import android.content.UriMatcher; -import android.net.Uri; -import android.provider.Telephony.Mms; -import android.util.Log; - -import java.util.HashMap; -import java.util.HashSet; - -public final class PduCache extends AbstractCache { - private static final String TAG = "PduCache"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final int MMS_ALL = 0; - private static final int MMS_ALL_ID = 1; - private static final int MMS_INBOX = 2; - private static final int MMS_INBOX_ID = 3; - private static final int MMS_SENT = 4; - private static final int MMS_SENT_ID = 5; - private static final int MMS_DRAFTS = 6; - private static final int MMS_DRAFTS_ID = 7; - private static final int MMS_OUTBOX = 8; - private static final int MMS_OUTBOX_ID = 9; - private static final int MMS_CONVERSATION = 10; - private static final int MMS_CONVERSATION_ID = 11; - - private static final UriMatcher URI_MATCHER; - private static final HashMap MATCH_TO_MSGBOX_ID_MAP; - - private static PduCache sInstance; - - static { - URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); - URI_MATCHER.addURI("mms", null, MMS_ALL); - URI_MATCHER.addURI("mms", "#", MMS_ALL_ID); - URI_MATCHER.addURI("mms", "inbox", MMS_INBOX); - URI_MATCHER.addURI("mms", "inbox/#", MMS_INBOX_ID); - URI_MATCHER.addURI("mms", "sent", MMS_SENT); - URI_MATCHER.addURI("mms", "sent/#", MMS_SENT_ID); - URI_MATCHER.addURI("mms", "drafts", MMS_DRAFTS); - URI_MATCHER.addURI("mms", "drafts/#", MMS_DRAFTS_ID); - URI_MATCHER.addURI("mms", "outbox", MMS_OUTBOX); - URI_MATCHER.addURI("mms", "outbox/#", MMS_OUTBOX_ID); - URI_MATCHER.addURI("mms-sms", "conversations", MMS_CONVERSATION); - URI_MATCHER.addURI("mms-sms", "conversations/#", MMS_CONVERSATION_ID); - - MATCH_TO_MSGBOX_ID_MAP = new HashMap(); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_INBOX, Mms.MESSAGE_BOX_INBOX); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_SENT, Mms.MESSAGE_BOX_SENT); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_DRAFTS, Mms.MESSAGE_BOX_DRAFTS); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_OUTBOX, Mms.MESSAGE_BOX_OUTBOX); - } - - private final HashMap> mMessageBoxes; - private final HashMap> mThreads; - private final HashSet mUpdating; - - private PduCache() { - mMessageBoxes = new HashMap>(); - mThreads = new HashMap>(); - mUpdating = new HashSet(); - } - - synchronized public static final PduCache getInstance() { - if (sInstance == null) { - if (LOCAL_LOGV) { - Log.v(TAG, "Constructing new PduCache instance."); - } - sInstance = new PduCache(); - } - return sInstance; - } - - @Override - synchronized public boolean put(Uri uri, PduCacheEntry entry) { - int msgBoxId = entry.getMessageBox(); - HashSet msgBox = mMessageBoxes.get(msgBoxId); - if (msgBox == null) { - msgBox = new HashSet(); - mMessageBoxes.put(msgBoxId, msgBox); - } - - long threadId = entry.getThreadId(); - HashSet thread = mThreads.get(threadId); - if (thread == null) { - thread = new HashSet(); - mThreads.put(threadId, thread); - } - - Uri finalKey = normalizeKey(uri); - boolean result = super.put(finalKey, entry); - if (result) { - msgBox.add(finalKey); - thread.add(finalKey); - } - setUpdating(uri, false); - return result; - } - - synchronized public void setUpdating(Uri uri, boolean updating) { - if (updating) { - mUpdating.add(uri); - } else { - mUpdating.remove(uri); - } - } - - synchronized public boolean isUpdating(Uri uri) { - return mUpdating.contains(uri); - } - - @Override - synchronized public PduCacheEntry purge(Uri uri) { - int match = URI_MATCHER.match(uri); - switch (match) { - case MMS_ALL_ID: - return purgeSingleEntry(uri); - case MMS_INBOX_ID: - case MMS_SENT_ID: - case MMS_DRAFTS_ID: - case MMS_OUTBOX_ID: - String msgId = uri.getLastPathSegment(); - return purgeSingleEntry(Uri.withAppendedPath(Mms.CONTENT_URI, msgId)); - // Implicit batch of purge, return null. - case MMS_ALL: - case MMS_CONVERSATION: - purgeAll(); - return null; - case MMS_INBOX: - case MMS_SENT: - case MMS_DRAFTS: - case MMS_OUTBOX: - purgeByMessageBox(MATCH_TO_MSGBOX_ID_MAP.get(match)); - return null; - case MMS_CONVERSATION_ID: - purgeByThreadId(ContentUris.parseId(uri)); - return null; - default: - return null; - } - } - - private PduCacheEntry purgeSingleEntry(Uri key) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromThreads(key, entry); - removeFromMessageBoxes(key, entry); - return entry; - } - return null; - } - - @Override - synchronized public void purgeAll() { - super.purgeAll(); - - mMessageBoxes.clear(); - mThreads.clear(); - mUpdating.clear(); - } - - /** - * @param uri The Uri to be normalized. - * @return Uri The normalized key of cached entry. - */ - private Uri normalizeKey(Uri uri) { - int match = URI_MATCHER.match(uri); - Uri normalizedKey = null; - - switch (match) { - case MMS_ALL_ID: - normalizedKey = uri; - break; - case MMS_INBOX_ID: - case MMS_SENT_ID: - case MMS_DRAFTS_ID: - case MMS_OUTBOX_ID: - String msgId = uri.getLastPathSegment(); - normalizedKey = Uri.withAppendedPath(Mms.CONTENT_URI, msgId); - break; - default: - return null; - } - - if (LOCAL_LOGV) { - Log.v(TAG, uri + " -> " + normalizedKey); - } - return normalizedKey; - } - - private void purgeByMessageBox(Integer msgBoxId) { - if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in message box: " + msgBoxId); - } - - if (msgBoxId != null) { - HashSet msgBox = mMessageBoxes.remove(msgBoxId); - if (msgBox != null) { - for (Uri key : msgBox) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromThreads(key, entry); - } - } - } - } - } - - private void removeFromThreads(Uri key, PduCacheEntry entry) { - HashSet thread = mThreads.get(entry.getThreadId()); - if (thread != null) { - thread.remove(key); - } - } - - private void purgeByThreadId(long threadId) { - if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in thread: " + threadId); - } - - HashSet thread = mThreads.remove(threadId); - if (thread != null) { - for (Uri key : thread) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromMessageBoxes(key, entry); - } - } - } - } - - private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) { - HashSet msgBox = mThreads.get(Long.valueOf(entry.getMessageBox())); - if (msgBox != null) { - msgBox.remove(key); - } - } -} diff --git a/core/java/com/google/android/mms/util/PduCacheEntry.java b/core/java/com/google/android/mms/util/PduCacheEntry.java deleted file mode 100644 index 8b4138628113..000000000000 --- a/core/java/com/google/android/mms/util/PduCacheEntry.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * 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.google.android.mms.util; - -import com.google.android.mms.pdu.GenericPdu; - -public final class PduCacheEntry { - private final GenericPdu mPdu; - private final int mMessageBox; - private final long mThreadId; - - public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) { - mPdu = pdu; - mMessageBox = msgBox; - mThreadId = threadId; - } - - public GenericPdu getPdu() { - return mPdu; - } - - public int getMessageBox() { - return mMessageBox; - } - - public long getThreadId() { - return mThreadId; - } -} diff --git a/core/java/com/google/android/mms/util/SqliteWrapper.java b/core/java/com/google/android/mms/util/SqliteWrapper.java deleted file mode 100644 index bcdac22ce142..000000000000 --- a/core/java/com/google/android/mms/util/SqliteWrapper.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * 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.google.android.mms.util; - -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteException; -import android.net.Uri; -import android.util.Log; -import android.widget.Toast; - -public final class SqliteWrapper { - private static final String TAG = "SqliteWrapper"; - private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE - = "unable to open database file"; - - private SqliteWrapper() { - // Forbidden being instantiated. - } - - // FIXME: It looks like outInfo.lowMemory does not work well as we expected. - // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false. - private static boolean isLowMemory(Context context) { - if (null == context) { - return false; - } - - ActivityManager am = (ActivityManager) - context.getSystemService(Context.ACTIVITY_SERVICE); - ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); - am.getMemoryInfo(outInfo); - - return outInfo.lowMemory; - } - - // FIXME: need to optimize this method. - private static boolean isLowMemory(SQLiteException e) { - return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE); - } - - public static void checkSQLiteException(Context context, SQLiteException e) { - if (isLowMemory(e)) { - Toast.makeText(context, com.android.internal.R.string.low_memory, - Toast.LENGTH_SHORT).show(); - } else { - throw e; - } - } - - public static Cursor query(Context context, ContentResolver resolver, Uri uri, - String[] projection, String selection, String[] selectionArgs, String sortOrder) { - try { - return resolver.query(uri, projection, selection, selectionArgs, sortOrder); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when query: ", e); - checkSQLiteException(context, e); - return null; - } - } - - public static boolean requery(Context context, Cursor cursor) { - try { - return cursor.requery(); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when requery: ", e); - checkSQLiteException(context, e); - return false; - } - } - public static int update(Context context, ContentResolver resolver, Uri uri, - ContentValues values, String where, String[] selectionArgs) { - try { - return resolver.update(uri, values, where, selectionArgs); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when update: ", e); - checkSQLiteException(context, e); - return -1; - } - } - - public static int delete(Context context, ContentResolver resolver, Uri uri, - String where, String[] selectionArgs) { - try { - return resolver.delete(uri, where, selectionArgs); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when delete: ", e); - checkSQLiteException(context, e); - return -1; - } - } - - public static Uri insert(Context context, ContentResolver resolver, - Uri uri, ContentValues values) { - try { - return resolver.insert(uri, values); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when insert: ", e); - checkSQLiteException(context, e); - return null; - } - } -} diff --git a/core/java/com/google/android/mms/util/package.html b/core/java/com/google/android/mms/util/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/core/java/com/google/android/mms/util/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - - diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk index 88f3f348e76b..b6b15c46fb5e 100644 --- a/core/tests/coretests/Android.mk +++ b/core/tests/coretests/Android.mk @@ -23,7 +23,7 @@ LOCAL_SRC_FILES := \ LOCAL_DX_FLAGS := --core-library LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock -LOCAL_JAVA_LIBRARIES := android.test.runner +LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common LOCAL_PACKAGE_NAME := FrameworksCoreTests LOCAL_CERTIFICATE := platform diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk index bf4ab1b70aeb..a2ea55465239 100644 --- a/packages/SettingsProvider/Android.mk +++ b/packages/SettingsProvider/Android.mk @@ -5,7 +5,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_JAVA_LIBRARIES := +LOCAL_JAVA_LIBRARIES := telephony-common LOCAL_PACKAGE_NAME := SettingsProvider LOCAL_CERTIFICATE := platform diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 423c802f2881..de078d2039d3 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -33,12 +33,14 @@ import android.net.ConnectivityManager; import android.os.SystemProperties; import android.provider.Settings; import android.provider.Settings.Secure; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import com.android.internal.content.PackageHelper; import com.android.internal.telephony.BaseCommands; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.util.XmlUtils; import com.android.internal.widget.LockPatternUtils; @@ -1590,7 +1592,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // Set the preferred network mode to 0 = Global, CDMA default int type; - if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) { + if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { type = Phone.NT_MODE_GLOBAL; } else { type = SystemProperties.getInt("ro.telephony.default_network", diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk index c23a8a1d37ac..6026258d4382 100644 --- a/packages/SystemUI/Android.mk +++ b/packages/SystemUI/Android.mk @@ -6,7 +6,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) \ ../../../ex/carousel/java/com/android/ex/carousel/carousel.rs -LOCAL_JAVA_LIBRARIES := services +LOCAL_JAVA_LIBRARIES := services telephony-common LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java index 491fad11fad6..66494e459482 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java @@ -20,13 +20,14 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.provider.Telephony; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Slog; import android.view.View; import android.widget.TextView; +import com.android.internal.telephony.TelephonyIntents; + import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimeZone; @@ -60,7 +61,7 @@ public class CarrierLabel extends TextView { if (!mAttached) { mAttached = true; IntentFilter filter = new IntentFilter(); - filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION); + filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION); getContext().registerReceiver(mIntentReceiver, filter, null, getHandler()); } } @@ -78,11 +79,11 @@ public class CarrierLabel extends TextView { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { - updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), - intent.getStringExtra(Telephony.Intents.EXTRA_SPN), - intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false), - intent.getStringExtra(Telephony.Intents.EXTRA_PLMN)); + if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { + updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false), + intent.getStringExtra(TelephonyIntents.EXTRA_SPN), + intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false), + intent.getStringExtra(TelephonyIntents.EXTRA_PLMN)); } } }; @@ -108,7 +109,7 @@ public class CarrierLabel extends TextView { setText(str); } - + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 374226d3a536..9b8bd224e7fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -39,6 +39,7 @@ import android.telephony.TelephonyManager; import android.util.Slog; import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.internal.telephony.cdma.TtyIntent; @@ -76,7 +77,7 @@ public class PhoneStatusBarPolicy { // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. - IccCard.State mSimState = IccCard.State.READY; + IccCardConstants.State mSimState = IccCardConstants.State.READY; // ringer volume private boolean mVolumeVisible; @@ -205,26 +206,27 @@ public class PhoneStatusBarPolicy { } private final void updateSimState(Intent intent) { - String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); - if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - mSimState = IccCard.State.ABSENT; + String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); + if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { + mSimState = IccCardConstants.State.ABSENT; } - else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { - mSimState = IccCard.State.READY; + else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { + mSimState = IccCardConstants.State.READY; } - else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { - final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - mSimState = IccCard.State.PIN_REQUIRED; + else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { + final String lockedReason = + intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); + if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { + mSimState = IccCardConstants.State.PIN_REQUIRED; } - else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - mSimState = IccCard.State.PUK_REQUIRED; + else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { + mSimState = IccCardConstants.State.PUK_REQUIRED; } else { - mSimState = IccCard.State.NETWORK_LOCKED; + mSimState = IccCardConstants.State.NETWORK_LOCKED; } } else { - mSimState = IccCard.State.UNKNOWN; + mSimState = IccCardConstants.State.UNKNOWN; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 106826701348..4d22f3304f35 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -51,6 +51,7 @@ import android.widget.TextView; import com.android.internal.app.IBatteryStats; import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.server.am.BatteryStatsService; @@ -68,7 +69,7 @@ public class NetworkController extends BroadcastReceiver { boolean mHspaDataDistinguishable; final TelephonyManager mPhone; boolean mDataConnected; - IccCard.State mSimState = IccCard.State.READY; + IccCardConstants.State mSimState = IccCardConstants.State.READY; int mPhoneState = TelephonyManager.CALL_STATE_IDLE; int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN; int mDataState = TelephonyManager.DATA_DISCONNECTED; @@ -220,7 +221,7 @@ public class NetworkController extends BroadcastReceiver { filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION); + filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); @@ -335,11 +336,11 @@ public class NetworkController extends BroadcastReceiver { updateSimState(intent); updateDataIcon(); refreshViews(); - } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) { - updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), - intent.getStringExtra(Telephony.Intents.EXTRA_SPN), - intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false), - intent.getStringExtra(Telephony.Intents.EXTRA_PLMN)); + } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) { + updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false), + intent.getStringExtra(TelephonyIntents.EXTRA_SPN), + intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false), + intent.getStringExtra(TelephonyIntents.EXTRA_PLMN)); refreshViews(); } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || action.equals(ConnectivityManager.INET_CONDITION_ACTION)) { @@ -422,26 +423,27 @@ public class NetworkController extends BroadcastReceiver { }; private final void updateSimState(Intent intent) { - String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); - if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - mSimState = IccCard.State.ABSENT; + String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); + if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { + mSimState = IccCardConstants.State.ABSENT; } - else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { - mSimState = IccCard.State.READY; + else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { + mSimState = IccCardConstants.State.READY; } - else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { - final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - mSimState = IccCard.State.PIN_REQUIRED; + else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { + final String lockedReason = + intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); + if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { + mSimState = IccCardConstants.State.PIN_REQUIRED; } - else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - mSimState = IccCard.State.PUK_REQUIRED; + else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { + mSimState = IccCardConstants.State.PUK_REQUIRED; } else { - mSimState = IccCard.State.NETWORK_LOCKED; + mSimState = IccCardConstants.State.NETWORK_LOCKED; } } else { - mSimState = IccCard.State.UNKNOWN; + mSimState = IccCardConstants.State.UNKNOWN; } } @@ -638,7 +640,8 @@ public class NetworkController extends BroadcastReceiver { if (!isCdma()) { // GSM case, we have to check also the sim state - if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) { + if (mSimState == IccCardConstants.State.READY || + mSimState == IccCardConstants.State.UNKNOWN) { if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { switch (mDataActivity) { case TelephonyManager.DATA_ACTIVITY_IN: diff --git a/packages/WAPPushManager/Android.mk b/packages/WAPPushManager/Android.mk index c1d8f4b6cdc9..35ec647f332d 100644 --- a/packages/WAPPushManager/Android.mk +++ b/packages/WAPPushManager/Android.mk @@ -10,6 +10,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := WAPPushManager +LOCAL_JAVA_LIBRARIES += telephony-common LOCAL_STATIC_JAVA_LIBRARIES += android-common LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk index 0a95b526cf1d..7128b0ddf1bd 100644 --- a/packages/WAPPushManager/tests/Android.mk +++ b/packages/WAPPushManager/tests/Android.mk @@ -18,7 +18,7 @@ include $(CLEAR_VARS) # We only want this apk build for tests. LOCAL_MODULE_TAGS := tests -LOCAL_JAVA_LIBRARIES := android.test.runner +LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common # Include all test java files. LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java index d0fe42d74dfa..c1fd51563a6f 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java @@ -17,8 +17,7 @@ package com.android.internal.policy.impl; import com.android.internal.R; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccCard.State; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.DigitalClock; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.TransportControlView; @@ -88,7 +87,7 @@ class KeyguardStatusViewManager implements OnClickListener { private int mBatteryLevel = 100; // last known SIM state - protected State mSimState; + protected IccCardConstants.State mSimState; private LockPatternUtils mLockPatternUtils; private KeyguardUpdateMonitor mUpdateMonitor; @@ -435,17 +434,18 @@ class KeyguardStatusViewManager implements OnClickListener { /** * Determine the current status of the lock screen given the sim state and other stuff. */ - public StatusMode getStatusForIccState(IccCard.State simState) { + public StatusMode getStatusForIccState(IccCardConstants.State simState) { // Since reading the SIM may take a while, we assume it is present until told otherwise. if (simState == null) { return StatusMode.Normal; } final boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() - && (simState == IccCard.State.ABSENT || simState == IccCard.State.PERM_DISABLED)); + && (simState == IccCardConstants.State.ABSENT || + simState == IccCardConstants.State.PERM_DISABLED)); // Assume we're NETWORK_LOCKED if not provisioned - simState = missingAndNotProvisioned ? State.NETWORK_LOCKED : simState; + simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState; switch (simState) { case ABSENT: return StatusMode.SimMissing; @@ -477,7 +477,7 @@ class KeyguardStatusViewManager implements OnClickListener { * * @param simState */ - private void updateCarrierStateWithSimStatus(State simState) { + private void updateCarrierStateWithSimStatus(IccCardConstants.State simState) { if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState); CharSequence carrierText = null; @@ -663,7 +663,7 @@ class KeyguardStatusViewManager implements OnClickListener { private SimStateCallback mSimStateCallback = new SimStateCallback() { - public void onSimStateChanged(State simState) { + public void onSimStateChanged(IccCardConstants.State simState) { updateCarrierStateWithSimStatus(simState); } }; diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index dfe9134d28cb..5cd0349c20a7 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -34,14 +34,8 @@ import android.os.BatteryManager; import android.os.Handler; import android.os.Message; import android.provider.Settings; -import android.provider.Telephony; -import static android.provider.Telephony.Intents.EXTRA_PLMN; -import static android.provider.Telephony.Intents.EXTRA_SHOW_PLMN; -import static android.provider.Telephony.Intents.EXTRA_SHOW_SPN; -import static android.provider.Telephony.Intents.EXTRA_SPN; -import static android.provider.Telephony.Intents.SPN_STRINGS_UPDATED_ACTION; - -import com.android.internal.telephony.IccCard; + +import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import android.telephony.TelephonyManager; @@ -70,7 +64,7 @@ public class KeyguardUpdateMonitor { private final Context mContext; - private IccCard.State mSimState = IccCard.State.READY; + private IccCardConstants.State mSimState = IccCardConstants.State.READY; private boolean mDeviceProvisioned; @@ -115,44 +109,44 @@ public class KeyguardUpdateMonitor { * the intent and provide a {@link SimCard.State} result. */ private static class SimArgs { - public final IccCard.State simState; + public final IccCardConstants.State simState; - SimArgs(IccCard.State state) { + SimArgs(IccCardConstants.State state) { simState = state; } static SimArgs fromIntent(Intent intent) { - IccCard.State state; + IccCardConstants.State state; if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED"); } - String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); - if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { + String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); + if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { final String absentReason = intent - .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); + .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( + if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals( absentReason)) { - state = IccCard.State.PERM_DISABLED; + state = IccCardConstants.State.PERM_DISABLED; } else { - state = IccCard.State.ABSENT; + state = IccCardConstants.State.ABSENT; } - } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { - state = IccCard.State.READY; - } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { + } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) { + state = IccCardConstants.State.READY; + } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { final String lockedReason = intent - .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - state = IccCard.State.PIN_REQUIRED; - } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - state = IccCard.State.PUK_REQUIRED; + .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON); + if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { + state = IccCardConstants.State.PIN_REQUIRED; + } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { + state = IccCardConstants.State.PUK_REQUIRED; } else { - state = IccCard.State.UNKNOWN; + state = IccCardConstants.State.UNKNOWN; } - } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { - state = IccCard.State.NETWORK_LOCKED; + } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { + state = IccCardConstants.State.NETWORK_LOCKED; } else { - state = IccCard.State.UNKNOWN; + state = IccCardConstants.State.UNKNOWN; } return new SimArgs(state); } @@ -253,7 +247,7 @@ public class KeyguardUpdateMonitor { } // take a guess to start - mSimState = IccCard.State.READY; + mSimState = IccCardConstants.State.READY; mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0); mTelephonyPlmn = getDefaultPlmn(); @@ -266,7 +260,7 @@ public class KeyguardUpdateMonitor { filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - filter.addAction(SPN_STRINGS_UPDATED_ACTION); + filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); filter.addAction(Intent.ACTION_USER_SWITCHED); @@ -281,7 +275,7 @@ public class KeyguardUpdateMonitor { || Intent.ACTION_TIME_CHANGED.equals(action) || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE)); - } else if (SPN_STRINGS_UPDATED_ACTION.equals(action)) { + } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { mTelephonyPlmn = getTelephonyPlmnFrom(intent); mTelephonySpn = getTelephonySpnFrom(intent); mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE)); @@ -296,7 +290,7 @@ public class KeyguardUpdateMonitor { } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { if (DEBUG_SIM_STATES) { Log.v(TAG, "action " + action + " state" + - intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE)); + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)); } mHandler.sendMessage(mHandler.obtainMessage( MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent))); @@ -405,15 +399,14 @@ public class KeyguardUpdateMonitor { * Handle {@link #MSG_SIM_STATE_CHANGE} */ private void handleSimStateChange(SimArgs simArgs) { - final IccCard.State state = simArgs.simState; + final IccCardConstants.State state = simArgs.simState; if (DEBUG) { Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " " + "state resolved to " + state.toString()); } - if (state != IccCard.State.UNKNOWN && state != mSimState) { - if (DEBUG_SIM_STATES) Log.v(TAG, "dispatching state: " + state); + if (state != IccCardConstants.State.UNKNOWN && state != mSimState) { mSimState = state; for (int i = 0; i < mSimStateCallbacks.size(); i++) { mSimStateCallbacks.get(i).onSimStateChanged(state); @@ -466,12 +459,12 @@ public class KeyguardUpdateMonitor { } /** - * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION} + * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION} * @return The string to use for the plmn, or null if it should not be shown. */ private CharSequence getTelephonyPlmnFrom(Intent intent) { - if (intent.getBooleanExtra(EXTRA_SHOW_PLMN, false)) { - final String plmn = intent.getStringExtra(EXTRA_PLMN); + if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) { + final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN); if (plmn != null) { return plmn; } else { @@ -494,8 +487,8 @@ public class KeyguardUpdateMonitor { * @return The string to use for the plmn, or null if it should not be shown. */ private CharSequence getTelephonySpnFrom(Intent intent) { - if (intent.getBooleanExtra(EXTRA_SHOW_SPN, false)) { - final String spn = intent.getStringExtra(EXTRA_SPN); + if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) { + final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN); if (spn != null) { return spn; } @@ -601,7 +594,7 @@ public class KeyguardUpdateMonitor { * Callback to notify of sim state change. */ interface SimStateCallback { - void onSimStateChanged(IccCard.State simState); + void onSimStateChanged(IccCardConstants.State simState); } /** @@ -646,7 +639,7 @@ public class KeyguardUpdateMonitor { mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget(); } - public IccCard.State getSimState() { + public IccCardConstants.State getSimState() { return mSimState; } @@ -659,7 +652,7 @@ public class KeyguardUpdateMonitor { * through mHandler, this *must* be called from the UI thread. */ public void reportSimUnlocked() { - handleSimStateChange(new SimArgs(IccCard.State.READY)); + handleSimStateChange(new SimArgs(IccCardConstants.State.READY)); } public boolean isDevicePluggedIn() { @@ -725,8 +718,8 @@ public class KeyguardUpdateMonitor { } public boolean isSimLocked() { - return mSimState == IccCard.State.PIN_REQUIRED - || mSimState == IccCard.State.PUK_REQUIRED - || mSimState == IccCard.State.PERM_DISABLED; + return mSimState == IccCardConstants.State.PIN_REQUIRED + || mSimState == IccCardConstants.State.PUK_REQUIRED + || mSimState == IccCardConstants.State.PERM_DISABLED; } } diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java index e84e912227c8..02eeedfd94cc 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java @@ -19,7 +19,7 @@ package com.android.internal.policy.impl; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl; -import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.LockPatternUtils; import android.app.ActivityManagerNative; @@ -621,10 +621,10 @@ public class KeyguardViewMediator implements KeyguardViewCallback, final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false); final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); - final IccCard.State state = mUpdateMonitor.getSimState(); + final IccCardConstants.State state = mUpdateMonitor.getSimState(); final boolean lockedOrMissing = state.isPinLocked() - || ((state == IccCard.State.ABSENT - || state == IccCard.State.PERM_DISABLED) + || ((state == IccCardConstants.State.ABSENT + || state == IccCardConstants.State.PERM_DISABLED) && requireSim); if (!lockedOrMissing && !provisioned) { @@ -727,7 +727,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback, } /** {@inheritDoc} */ - public void onSimStateChanged(IccCard.State simState) { + public void onSimStateChanged(IccCardConstants.State simState) { if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState); switch (simState) { diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 35e782082eba..041211c70c5c 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -20,7 +20,7 @@ import com.android.internal.R; import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback; import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl; import com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode; -import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockScreenWidgetCallback; import com.android.internal.widget.LockScreenWidgetInterface; @@ -267,8 +267,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase { private boolean stuckOnLockScreenBecauseSimMissing() { return mRequiresSim && (!mUpdateMonitor.isDeviceProvisioned()) - && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT || - mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED); + && (mUpdateMonitor.getSimState() == IccCardConstants.State.ABSENT || + mUpdateMonitor.getSimState() == IccCardConstants.State.PERM_DISABLED); } /** @@ -289,9 +289,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase { } public void goToUnlockScreen() { - final IccCard.State simState = mUpdateMonitor.getSimState(); + final IccCardConstants.State simState = mUpdateMonitor.getSimState(); if (stuckOnLockScreenBecauseSimMissing() - || (simState == IccCard.State.PUK_REQUIRED + || (simState == IccCardConstants.State.PUK_REQUIRED && !mLockPatternUtils.isPukUnlockScreenEnable())){ // stuck on lock screen when sim missing or // puk'd but puk unlock screen is disabled @@ -757,7 +757,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase { public void wakeWhenReadyTq(int keyCode) { if (DEBUG) Log.d(TAG, "onWakeKey"); if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen) - && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) { + && (mUpdateMonitor.getSimState() != IccCardConstants.State.PUK_REQUIRED)) { if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU"); updateScreen(Mode.UnlockScreen, false); getCallback().pokeWakelock(); @@ -811,10 +811,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase { secure = mLockPatternUtils.isLockPatternEnabled(); break; case SimPin: - secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED; + secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PIN_REQUIRED; break; case SimPuk: - secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; + secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PUK_REQUIRED; break; case Account: secure = true; @@ -1044,9 +1044,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase { * the lock screen (lock or unlock). */ private Mode getInitialMode() { - final IccCard.State simState = mUpdateMonitor.getSimState(); + final IccCardConstants.State simState = mUpdateMonitor.getSimState(); if (stuckOnLockScreenBecauseSimMissing() || - (simState == IccCard.State.PUK_REQUIRED && + (simState == IccCardConstants.State.PUK_REQUIRED && !mLockPatternUtils.isPukUnlockScreenEnable())) { return Mode.LockScreen; } else { @@ -1062,11 +1062,11 @@ public class LockPatternKeyguardView extends KeyguardViewBase { * Given the current state of things, what should the unlock screen be? */ private UnlockMode getUnlockMode() { - final IccCard.State simState = mUpdateMonitor.getSimState(); + final IccCardConstants.State simState = mUpdateMonitor.getSimState(); UnlockMode currentMode; - if (simState == IccCard.State.PIN_REQUIRED) { + if (simState == IccCardConstants.State.PIN_REQUIRED) { currentMode = UnlockMode.SimPin; - } else if (simState == IccCard.State.PUK_REQUIRED) { + } else if (simState == IccCardConstants.State.PUK_REQUIRED) { currentMode = UnlockMode.SimPuk; } else { final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality(); diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java index 58d14eddb79a..6d3c20a6b2f7 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java @@ -19,7 +19,7 @@ package com.android.internal.policy.impl; import com.android.internal.widget.LockPatternUtils; import android.content.Context; -import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; /** * Knows how to create a lock pattern keyguard view, and answer questions about @@ -55,10 +55,11 @@ public class LockPatternKeyguardViewProperties implements KeyguardViewProperties } private boolean isSimPinSecure() { - final IccCard.State simState = mUpdateMonitor.getSimState(); - return (simState == IccCard.State.PIN_REQUIRED - || simState == IccCard.State.PUK_REQUIRED - || simState == IccCard.State.PERM_DISABLED); + final IccCardConstants.State simState = mUpdateMonitor.getSimState(); + return (simState == IccCardConstants.State.PIN_REQUIRED + || simState == IccCardConstants.State.PUK_REQUIRED + || simState == IccCardConstants.State.ABSENT + || simState == IccCardConstants.State.PERM_DISABLED); } } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index ec954fefbb70..26078ec8aefd 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -19,7 +19,7 @@ package com.android.internal.policy.impl; import com.android.internal.R; import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl; import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback; -import com.android.internal.telephony.IccCard.State; +import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.SlidingTab; import com.android.internal.widget.WaveView; @@ -105,7 +105,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen { }; SimStateCallback mSimStateCallback = new SimStateCallback() { - public void onSimStateChanged(State simState) { + public void onSimStateChanged(IccCardConstants.State simState) { updateTargets(); } }; diff --git a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java index db71e2b2b2d9..862e6831e5e8 100644 --- a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java +++ b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java @@ -18,7 +18,7 @@ package com.android.internal.policy.impl; import android.content.Context; import com.android.internal.policy.impl.KeyguardViewCallback; -import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardConstants; import android.content.res.Configuration; import android.test.AndroidTestCase; import android.view.View; @@ -40,14 +40,14 @@ public class LockPatternKeyguardViewTest extends AndroidTestCase { private static class MockUpdateMonitor extends KeyguardUpdateMonitor { - public IccCard.State simState = IccCard.State.READY; + public IccCardConstants.State simState = IccCardConstants.State.READY; private MockUpdateMonitor(Context context) { super(context); } @Override - public IccCard.State getSimState() { + public IccCardConstants.State getSimState() { return simState; } } @@ -318,7 +318,7 @@ public class LockPatternKeyguardViewTest extends AndroidTestCase { public void testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked() { // PUK locked - mUpdateMonitor.simState = IccCard.State.PUK_REQUIRED; + mUpdateMonitor.simState = IccCardConstants.State.PUK_REQUIRED; // wake by menu mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU); diff --git a/services/java/Android.mk b/services/java/Android.mk index c756d29f104e..e70a6c96bece 100644 --- a/services/java/Android.mk +++ b/services/java/Android.mk @@ -11,7 +11,7 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE:= services -LOCAL_JAVA_LIBRARIES := android.policy +LOCAL_JAVA_LIBRARIES := android.policy telephony-common LOCAL_NO_EMMA_INSTRUMENT := true LOCAL_NO_EMMA_COMPILE := true diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 7bbc8b5209ac..230f07bb5baf 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -77,6 +77,7 @@ import android.util.SparseIntArray; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; @@ -1008,7 +1009,7 @@ private NetworkStateTracker makeWimaxStateTracker() { try { if (!ConnectivityManager.isNetworkTypeValid(networkType) || mNetConfigs[networkType] == null) { - return Phone.APN_REQUEST_FAILED; + return PhoneConstants.APN_REQUEST_FAILED; } FeatureUser f = new FeatureUser(networkType, feature, binder); @@ -1027,7 +1028,7 @@ private NetworkStateTracker makeWimaxStateTracker() { uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL); } if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) { - return Phone.APN_REQUEST_FAILED; + return PhoneConstants.APN_REQUEST_FAILED; } NetworkStateTracker network = mNetTrackers[usedNetworkType]; @@ -1039,7 +1040,7 @@ private NetworkStateTracker makeWimaxStateTracker() { if (ni.isAvailable() == false) { if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) { if (DBG) log("special network not available ni=" + ni.getTypeName()); - return Phone.APN_TYPE_NOT_AVAILABLE; + return PhoneConstants.APN_TYPE_NOT_AVAILABLE; } else { // else make the attempt anyway - probably giving REQUEST_STARTED below if (DBG) { @@ -1088,10 +1089,10 @@ private NetworkStateTracker makeWimaxStateTracker() { } finally { Binder.restoreCallingIdentity(token); } - return Phone.APN_ALREADY_ACTIVE; + return PhoneConstants.APN_ALREADY_ACTIVE; } if (VDBG) log("special network already connecting"); - return Phone.APN_REQUEST_STARTED; + return PhoneConstants.APN_REQUEST_STARTED; } // check if the radio in play can make another contact @@ -1102,7 +1103,7 @@ private NetworkStateTracker makeWimaxStateTracker() { feature); } network.reconnect(); - return Phone.APN_REQUEST_STARTED; + return PhoneConstants.APN_REQUEST_STARTED; } else { // need to remember this unsupported request so we respond appropriately on stop synchronized(this) { @@ -1115,7 +1116,7 @@ private NetworkStateTracker makeWimaxStateTracker() { return -1; } } - return Phone.APN_TYPE_NOT_AVAILABLE; + return PhoneConstants.APN_TYPE_NOT_AVAILABLE; } finally { if (DBG) { final long execTime = SystemClock.elapsedRealtime() - startTime; @@ -2037,7 +2038,7 @@ private NetworkStateTracker makeWimaxStateTracker() { // @see bug/4455071 /** Notify TetheringService if interface name has been changed. */ if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(), - Phone.REASON_LINK_PROPERTIES_CHANGED)) { + PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) { if (isTetheringSupported()) { mTethering.handleTetherIfaceChange(); } diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java index 1b1638a52e97..c23a1d9c10ec 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/java/com/android/server/TelephonyRegistry.java @@ -44,6 +44,7 @@ import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.DefaultPhoneNotifier; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.ServiceStateTracker; import com.android.internal.telephony.TelephonyIntents; import com.android.server.am.BatteryStatsService; @@ -622,7 +623,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString()); + intent.putExtra(PhoneConstants.STATE_KEY, + DefaultPhoneNotifier.convertCallState(state).toString()); if (!TextUtils.isEmpty(incomingNumber)) { intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); } @@ -637,34 +639,35 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { // status bar takes care of that after taking into account all of the // required info. Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); - intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString()); + intent.putExtra(PhoneConstants.STATE_KEY, + DefaultPhoneNotifier.convertDataState(state).toString()); if (!isDataConnectivityPossible) { - intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true); + intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); } if (reason != null) { - intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason); + intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); } if (linkProperties != null) { - intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties); + intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); String iface = linkProperties.getInterfaceName(); if (iface != null) { - intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface); + intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); } } if (linkCapabilities != null) { - intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities); + intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities); } - if (roaming) intent.putExtra(Phone.DATA_NETWORK_ROAMING_KEY, true); + if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); - intent.putExtra(Phone.DATA_APN_KEY, apn); - intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); + intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); + intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); mContext.sendStickyBroadcast(intent); } private void broadcastDataConnectionFailed(String reason, String apnType) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); - intent.putExtra(Phone.FAILURE_REASON_KEY, reason); - intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); + intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); + intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); mContext.sendStickyBroadcast(intent); } diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 88a0ccbe702d..682ecf86124f 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -47,6 +47,7 @@ import android.provider.Settings; import android.util.Log; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.IState; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -1190,7 +1191,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean retValue = true; if (apnType == ConnectivityManager.TYPE_NONE) return false; if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection(); - int result = Phone.APN_REQUEST_FAILED; + int result = PhoneConstants.APN_REQUEST_FAILED; String enableString = enableString(apnType); if (enableString == null) return false; try { @@ -1199,14 +1200,14 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } catch (Exception e) { } switch (result) { - case Phone.APN_ALREADY_ACTIVE: - case Phone.APN_REQUEST_STARTED: + case PhoneConstants.APN_ALREADY_ACTIVE: + case PhoneConstants.APN_REQUEST_STARTED: mMobileApnReserved = apnType; Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW); m.arg1 = ++mCurrentConnectionSequence; sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS); break; - case Phone.APN_REQUEST_FAILED: + case PhoneConstants.APN_REQUEST_FAILED: default: retValue = false; break; diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java index ce534992bb41..4ad6140d1471 100755 --- a/services/java/com/android/server/location/GpsLocationProvider.java +++ b/services/java/com/android/server/location/GpsLocationProvider.java @@ -60,6 +60,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; import java.io.File; import java.io.FileInputStream; @@ -1285,8 +1286,8 @@ public class GpsLocationProvider implements LocationProviderInterface { int result = mConnMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); mAGpsDataConnectionIpAddr = ipaddr; - if (result == Phone.APN_ALREADY_ACTIVE) { - if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE"); + if (result == PhoneConstants.APN_ALREADY_ACTIVE) { + if (DEBUG) Log.d(TAG, "PhoneConstants.APN_ALREADY_ACTIVE"); if (mAGpsApn != null) { Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr); if (mAGpsDataConnectionIpAddr != 0xffffffff) { @@ -1300,12 +1301,12 @@ public class GpsLocationProvider implements LocationProviderInterface { native_agps_data_conn_open(mAGpsApn); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } else { - Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); + Log.e(TAG, "mAGpsApn not set when receiving PhoneConstants.APN_ALREADY_ACTIVE"); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; native_agps_data_conn_failed(); } - } else if (result == Phone.APN_REQUEST_STARTED) { - if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED"); + } else if (result == PhoneConstants.APN_REQUEST_STARTED) { + if (DEBUG) Log.d(TAG, "PhoneConstants.APN_REQUEST_STARTED"); // Nothing to do here } else { if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed"); diff --git a/telephony/java/android/telephony/CellBroadcastMessage.java b/telephony/java/android/telephony/CellBroadcastMessage.java deleted file mode 100644 index 36c238d8acd2..000000000000 --- a/telephony/java/android/telephony/CellBroadcastMessage.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (C) 2011 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.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.graphics.Typeface; -import android.os.Parcel; -import android.os.Parcelable; -import android.provider.Telephony; -import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbEtwsInfo; -import android.telephony.SmsCbLocation; -import android.telephony.SmsCbMessage; -import android.text.Spannable; -import android.text.SpannableStringBuilder; -import android.text.format.DateUtils; -import android.text.style.StyleSpan; - -/** - * Application wrapper for {@link SmsCbMessage}. This is Parcelable so that - * decoded broadcast message objects can be passed between running Services. - * New broadcasts are received by the CellBroadcastReceiver app, which exports - * the database of previously received broadcasts at "content://cellbroadcasts/". - * The "android.permission.READ_CELL_BROADCASTS" permission is required to read - * from the ContentProvider, and writes to the database are not allowed.

- * - * Use {@link #createFromCursor} to create CellBroadcastMessage objects from rows - * in the database cursor returned by the ContentProvider. - * - * {@hide} - */ -public class CellBroadcastMessage implements Parcelable { - - /** Identifier for getExtra() when adding this object to an Intent. */ - public static final String SMS_CB_MESSAGE_EXTRA = - "com.android.cellbroadcastreceiver.SMS_CB_MESSAGE"; - - /** SmsCbMessage. */ - private final SmsCbMessage mSmsCbMessage; - - private final long mDeliveryTime; - private boolean mIsRead; - - public CellBroadcastMessage(SmsCbMessage message) { - mSmsCbMessage = message; - mDeliveryTime = System.currentTimeMillis(); - mIsRead = false; - } - - private CellBroadcastMessage(SmsCbMessage message, long deliveryTime, boolean isRead) { - mSmsCbMessage = message; - mDeliveryTime = deliveryTime; - mIsRead = isRead; - } - - private CellBroadcastMessage(Parcel in) { - mSmsCbMessage = new SmsCbMessage(in); - mDeliveryTime = in.readLong(); - mIsRead = (in.readInt() != 0); - } - - /** Parcelable: no special flags. */ - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel out, int flags) { - mSmsCbMessage.writeToParcel(out, flags); - out.writeLong(mDeliveryTime); - out.writeInt(mIsRead ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public CellBroadcastMessage createFromParcel(Parcel in) { - return new CellBroadcastMessage(in); - } - - public CellBroadcastMessage[] newArray(int size) { - return new CellBroadcastMessage[size]; - } - }; - - /** - * Create a CellBroadcastMessage from a row in the database. - * @param cursor an open SQLite cursor pointing to the row to read - * @return the new CellBroadcastMessage - * @throws IllegalArgumentException if one of the required columns is missing - */ - public static CellBroadcastMessage createFromCursor(Cursor cursor) { - int geoScope = cursor.getInt( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE)); - int serialNum = cursor.getInt( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER)); - int category = cursor.getInt( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY)); - String language = cursor.getString( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE)); - String body = cursor.getString( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY)); - int format = cursor.getInt( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT)); - int priority = cursor.getInt( - cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY)); - - String plmn; - int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN); - if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) { - plmn = cursor.getString(plmnColumn); - } else { - plmn = null; - } - - int lac; - int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC); - if (lacColumn != -1 && !cursor.isNull(lacColumn)) { - lac = cursor.getInt(lacColumn); - } else { - lac = -1; - } - - int cid; - int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID); - if (cidColumn != -1 && !cursor.isNull(cidColumn)) { - cid = cursor.getInt(cidColumn); - } else { - cid = -1; - } - - SmsCbLocation location = new SmsCbLocation(plmn, lac, cid); - - SmsCbEtwsInfo etwsInfo; - int etwsWarningTypeColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.ETWS_WARNING_TYPE); - if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) { - int warningType = cursor.getInt(etwsWarningTypeColumn); - etwsInfo = new SmsCbEtwsInfo(warningType, false, false, null); - } else { - etwsInfo = null; - } - - SmsCbCmasInfo cmasInfo; - int cmasMessageClassColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS); - if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) { - int messageClass = cursor.getInt(cmasMessageClassColumn); - - int cmasCategory; - int cmasCategoryColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_CATEGORY); - if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) { - cmasCategory = cursor.getInt(cmasCategoryColumn); - } else { - cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN; - } - - int responseType; - int cmasResponseTypeColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE); - if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) { - responseType = cursor.getInt(cmasResponseTypeColumn); - } else { - responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN; - } - - int severity; - int cmasSeverityColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_SEVERITY); - if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) { - severity = cursor.getInt(cmasSeverityColumn); - } else { - severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; - } - - int urgency; - int cmasUrgencyColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_URGENCY); - if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) { - urgency = cursor.getInt(cmasUrgencyColumn); - } else { - urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; - } - - int certainty; - int cmasCertaintyColumn = cursor.getColumnIndex( - Telephony.CellBroadcasts.CMAS_CERTAINTY); - if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) { - certainty = cursor.getInt(cmasCertaintyColumn); - } else { - certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; - } - - cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity, - urgency, certainty); - } else { - cmasInfo = null; - } - - SmsCbMessage msg = new SmsCbMessage(format, geoScope, serialNum, location, category, - language, body, priority, etwsInfo, cmasInfo); - - long deliveryTime = cursor.getLong(cursor.getColumnIndexOrThrow( - Telephony.CellBroadcasts.DELIVERY_TIME)); - boolean isRead = (cursor.getInt(cursor.getColumnIndexOrThrow( - Telephony.CellBroadcasts.MESSAGE_READ)) != 0); - - return new CellBroadcastMessage(msg, deliveryTime, isRead); - } - - /** - * Return a ContentValues object for insertion into the database. - * @return a new ContentValues object containing this object's data - */ - public ContentValues getContentValues() { - ContentValues cv = new ContentValues(16); - SmsCbMessage msg = mSmsCbMessage; - cv.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, msg.getGeographicalScope()); - SmsCbLocation location = msg.getLocation(); - if (location.getPlmn() != null) { - cv.put(Telephony.CellBroadcasts.PLMN, location.getPlmn()); - } - if (location.getLac() != -1) { - cv.put(Telephony.CellBroadcasts.LAC, location.getLac()); - } - if (location.getCid() != -1) { - cv.put(Telephony.CellBroadcasts.CID, location.getCid()); - } - cv.put(Telephony.CellBroadcasts.SERIAL_NUMBER, msg.getSerialNumber()); - cv.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, msg.getServiceCategory()); - cv.put(Telephony.CellBroadcasts.LANGUAGE_CODE, msg.getLanguageCode()); - cv.put(Telephony.CellBroadcasts.MESSAGE_BODY, msg.getMessageBody()); - cv.put(Telephony.CellBroadcasts.DELIVERY_TIME, mDeliveryTime); - cv.put(Telephony.CellBroadcasts.MESSAGE_READ, mIsRead); - cv.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, msg.getMessageFormat()); - cv.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, msg.getMessagePriority()); - - SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo(); - if (etwsInfo != null) { - cv.put(Telephony.CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType()); - } - - SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo(); - if (cmasInfo != null) { - cv.put(Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass()); - cv.put(Telephony.CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory()); - cv.put(Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType()); - cv.put(Telephony.CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity()); - cv.put(Telephony.CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency()); - cv.put(Telephony.CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty()); - } - - return cv; - } - - /** - * Set or clear the "read message" flag. - * @param isRead true if the message has been read; false if not - */ - public void setIsRead(boolean isRead) { - mIsRead = isRead; - } - - public String getLanguageCode() { - return mSmsCbMessage.getLanguageCode(); - } - - public int getServiceCategory() { - return mSmsCbMessage.getServiceCategory(); - } - - public long getDeliveryTime() { - return mDeliveryTime; - } - - public String getMessageBody() { - return mSmsCbMessage.getMessageBody(); - } - - public boolean isRead() { - return mIsRead; - } - - public int getSerialNumber() { - return mSmsCbMessage.getSerialNumber(); - } - - public SmsCbCmasInfo getCmasWarningInfo() { - return mSmsCbMessage.getCmasWarningInfo(); - } - - public SmsCbEtwsInfo getEtwsWarningInfo() { - return mSmsCbMessage.getEtwsWarningInfo(); - } - - /** - * Return whether the broadcast is an emergency (PWS) message type. - * This includes lower priority test messages and Amber alerts. - * - * All public alerts show the flashing warning icon in the dialog, - * but only emergency alerts play the alert sound and speak the message. - * - * @return true if the message is PWS type; false otherwise - */ - public boolean isPublicAlertMessage() { - return mSmsCbMessage.isEmergencyMessage(); - } - - /** - * Returns whether the broadcast is an emergency (PWS) message type, - * including test messages, but excluding lower priority Amber alert broadcasts. - * - * @return true if the message is PWS type, excluding Amber alerts - */ - public boolean isEmergencyAlertMessage() { - if (!mSmsCbMessage.isEmergencyMessage()) { - return false; - } - SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo(); - if (cmasInfo != null && - cmasInfo.getMessageClass() == SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY) { - return false; - } - return true; - } - - /** - * Return whether the broadcast is an ETWS emergency message type. - * @return true if the message is ETWS emergency type; false otherwise - */ - public boolean isEtwsMessage() { - return mSmsCbMessage.isEtwsMessage(); - } - - /** - * Return whether the broadcast is a CMAS emergency message type. - * @return true if the message is CMAS emergency type; false otherwise - */ - public boolean isCmasMessage() { - return mSmsCbMessage.isCmasMessage(); - } - - /** - * Return the CMAS message class. - * @return the CMAS message class, e.g. {@link SmsCbCmasInfo#CMAS_CLASS_SEVERE_THREAT}, or - * {@link SmsCbCmasInfo#CMAS_CLASS_UNKNOWN} if this is not a CMAS alert - */ - public int getCmasMessageClass() { - if (mSmsCbMessage.isCmasMessage()) { - return mSmsCbMessage.getCmasWarningInfo().getMessageClass(); - } else { - return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN; - } - } - - /** - * Return whether the broadcast is an ETWS popup alert. - * This method checks the message ID and the message code. - * @return true if the message indicates an ETWS popup alert - */ - public boolean isEtwsPopupAlert() { - SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo(); - return etwsInfo != null && etwsInfo.isPopupAlert(); - } - - /** - * Return whether the broadcast is an ETWS emergency user alert. - * This method checks the message ID and the message code. - * @return true if the message indicates an ETWS emergency user alert - */ - public boolean isEtwsEmergencyUserAlert() { - SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo(); - return etwsInfo != null && etwsInfo.isEmergencyUserAlert(); - } - - /** - * Return whether the broadcast is an ETWS test message. - * @return true if the message is an ETWS test message; false otherwise - */ - public boolean isEtwsTestMessage() { - SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo(); - return etwsInfo != null && - etwsInfo.getWarningType() == SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE; - } - - /** - * Return the abbreviated date string for the message delivery time. - * @param context the context object - * @return a String to use in the broadcast list UI - */ - public String getDateString(Context context) { - int flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT | DateUtils.FORMAT_SHOW_TIME | - DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE | - DateUtils.FORMAT_CAP_AMPM; - return DateUtils.formatDateTime(context, mDeliveryTime, flags); - } - - /** - * Return the date string for the message delivery time, suitable for text-to-speech. - * @param context the context object - * @return a String for populating the list item AccessibilityEvent for TTS - */ - public String getSpokenDateString(Context context) { - int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE; - return DateUtils.formatDateTime(context, mDeliveryTime, flags); - } -} diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index 5eaa5a074114..42c2aff03060 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -26,7 +26,7 @@ import android.provider.Settings; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; import com.android.internal.telephony.ITelephony; -import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneConstants; /** * Abstract class that represents the location of the device. {@more} @@ -64,9 +64,9 @@ public abstract class CellLocation { // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when // ITelephony interface is not up yet. switch(TelephonyManager.getDefault().getCurrentPhoneType()) { - case Phone.PHONE_TYPE_CDMA: + case PhoneConstants.PHONE_TYPE_CDMA: return new CdmaCellLocation(bundle); - case Phone.PHONE_TYPE_GSM: + case PhoneConstants.PHONE_TYPE_GSM: return new GsmCellLocation(bundle); default: return null; @@ -92,9 +92,9 @@ public abstract class CellLocation { // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when // ITelephony interface is not up yet. switch(TelephonyManager.getDefault().getCurrentPhoneType()) { - case Phone.PHONE_TYPE_CDMA: + case PhoneConstants.PHONE_TYPE_CDMA: return new CdmaCellLocation(); - case Phone.PHONE_TYPE_GSM: + case PhoneConstants.PHONE_TYPE_GSM: return new GsmCellLocation(); default: return null; diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 698206c6de85..def6939aef28 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -26,7 +26,6 @@ import android.telephony.CellInfo; import android.util.Log; import com.android.internal.telephony.IPhoneStateListener; -import com.android.internal.telephony.Phone; /** * A listener class for monitoring changes in specific telephony states diff --git a/telephony/java/android/telephony/SmsCbCmasInfo.java b/telephony/java/android/telephony/SmsCbCmasInfo.java deleted file mode 100644 index 7a89d94ab2ef..000000000000 --- a/telephony/java/android/telephony/SmsCbCmasInfo.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2012 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 android.os.Parcelable; - -/** - * Contains CMAS warning notification Type 1 elements for a {@link SmsCbMessage}. - * Supported values for each element are defined in TIA-1149-0-1 (CMAS over CDMA) and - * 3GPP TS 23.041 (for GSM/UMTS). - * - * {@hide} - */ -public class SmsCbCmasInfo implements Parcelable { - - // CMAS message class (in GSM/UMTS message identifier or CDMA service category). - - /** Presidential-level alert (Korean Public Alert System Class 0 message). */ - public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00; - - /** Extreme threat to life and property (Korean Public Alert System Class 1 message). */ - public static final int CMAS_CLASS_EXTREME_THREAT = 0x01; - - /** Severe threat to life and property (Korean Public Alert System Class 1 message). */ - public static final int CMAS_CLASS_SEVERE_THREAT = 0x02; - - /** Child abduction emergency (AMBER Alert). */ - public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03; - - /** CMAS test message. */ - public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04; - - /** CMAS exercise. */ - public static final int CMAS_CLASS_CMAS_EXERCISE = 0x05; - - /** CMAS category for operator defined use. */ - public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06; - - /** CMAS category for warning types that are reserved for future extension. */ - public static final int CMAS_CLASS_UNKNOWN = -1; - - // CMAS alert category (in CDMA type 1 elements record). - - /** CMAS alert category: Geophysical including landslide. */ - public static final int CMAS_CATEGORY_GEO = 0x00; - - /** CMAS alert category: Meteorological including flood. */ - public static final int CMAS_CATEGORY_MET = 0x01; - - /** CMAS alert category: General emergency and public safety. */ - public static final int CMAS_CATEGORY_SAFETY = 0x02; - - /** CMAS alert category: Law enforcement, military, homeland/local/private security. */ - public static final int CMAS_CATEGORY_SECURITY = 0x03; - - /** CMAS alert category: Rescue and recovery. */ - public static final int CMAS_CATEGORY_RESCUE = 0x04; - - /** CMAS alert category: Fire suppression and rescue. */ - public static final int CMAS_CATEGORY_FIRE = 0x05; - - /** CMAS alert category: Medical and public health. */ - public static final int CMAS_CATEGORY_HEALTH = 0x06; - - /** CMAS alert category: Pollution and other environmental. */ - public static final int CMAS_CATEGORY_ENV = 0x07; - - /** CMAS alert category: Public and private transportation. */ - public static final int CMAS_CATEGORY_TRANSPORT = 0x08; - - /** CMAS alert category: Utility, telecom, other non-transport infrastructure. */ - public static final int CMAS_CATEGORY_INFRA = 0x09; - - /** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */ - public static final int CMAS_CATEGORY_CBRNE = 0x0a; - - /** CMAS alert category: Other events. */ - public static final int CMAS_CATEGORY_OTHER = 0x0b; - - /** - * CMAS alert category is unknown. The category is only available for CDMA broadcasts - * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown. - */ - public static final int CMAS_CATEGORY_UNKNOWN = -1; - - // CMAS response type (in CDMA type 1 elements record). - - /** CMAS response type: Take shelter in place. */ - public static final int CMAS_RESPONSE_TYPE_SHELTER = 0x00; - - /** CMAS response type: Evacuate (Relocate). */ - public static final int CMAS_RESPONSE_TYPE_EVACUATE = 0x01; - - /** CMAS response type: Make preparations. */ - public static final int CMAS_RESPONSE_TYPE_PREPARE = 0x02; - - /** CMAS response type: Execute a pre-planned activity. */ - public static final int CMAS_RESPONSE_TYPE_EXECUTE = 0x03; - - /** CMAS response type: Attend to information sources. */ - public static final int CMAS_RESPONSE_TYPE_MONITOR = 0x04; - - /** CMAS response type: Avoid hazard. */ - public static final int CMAS_RESPONSE_TYPE_AVOID = 0x05; - - /** CMAS response type: Evaluate the information in this message (not for public warnings). */ - public static final int CMAS_RESPONSE_TYPE_ASSESS = 0x06; - - /** CMAS response type: No action recommended. */ - public static final int CMAS_RESPONSE_TYPE_NONE = 0x07; - - /** - * CMAS response type is unknown. The response type is only available for CDMA broadcasts - * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown. - */ - public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; - - // 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS severity type: Extraordinary threat to life or property. */ - public static final int CMAS_SEVERITY_EXTREME = 0x0; - - /** CMAS severity type: Significant threat to life or property. */ - public static final int CMAS_SEVERITY_SEVERE = 0x1; - - /** - * CMAS alert severity is unknown. The severity is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_SEVERITY_UNKNOWN = -1; - - // CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS urgency type: Responsive action should be taken immediately. */ - public static final int CMAS_URGENCY_IMMEDIATE = 0x0; - - /** CMAS urgency type: Responsive action should be taken within the next hour. */ - public static final int CMAS_URGENCY_EXPECTED = 0x1; - - /** - * CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_URGENCY_UNKNOWN = -1; - - // CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS certainty type: Determined to have occurred or to be ongoing. */ - public static final int CMAS_CERTAINTY_OBSERVED = 0x0; - - /** CMAS certainty type: Likely (probability > ~50%). */ - public static final int CMAS_CERTAINTY_LIKELY = 0x1; - - /** - * CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_CERTAINTY_UNKNOWN = -1; - - /** CMAS message class. */ - private final int mMessageClass; - - /** CMAS category. */ - private final int mCategory; - - /** CMAS response type. */ - private final int mResponseType; - - /** CMAS severity. */ - private final int mSeverity; - - /** CMAS urgency. */ - private final int mUrgency; - - /** CMAS certainty. */ - private final int mCertainty; - - /** Create a new SmsCbCmasInfo object with the specified values. */ - public SmsCbCmasInfo(int messageClass, int category, int responseType, int severity, - int urgency, int certainty) { - mMessageClass = messageClass; - mCategory = category; - mResponseType = responseType; - mSeverity = severity; - mUrgency = urgency; - mCertainty = certainty; - } - - /** Create a new SmsCbCmasInfo object from a Parcel. */ - SmsCbCmasInfo(Parcel in) { - mMessageClass = in.readInt(); - mCategory = in.readInt(); - mResponseType = in.readInt(); - mSeverity = in.readInt(); - mUrgency = in.readInt(); - mCertainty = in.readInt(); - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mMessageClass); - dest.writeInt(mCategory); - dest.writeInt(mResponseType); - dest.writeInt(mSeverity); - dest.writeInt(mUrgency); - dest.writeInt(mCertainty); - } - - /** - * Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}. - * @return one of the {@code CMAS_CLASS} values - */ - public int getMessageClass() { - return mMessageClass; - } - - /** - * Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}. - * @return one of the {@code CMAS_CATEGORY} values - */ - public int getCategory() { - return mCategory; - } - - /** - * Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}. - * @return one of the {@code CMAS_RESPONSE_TYPE} values - */ - public int getResponseType() { - return mResponseType; - } - - /** - * Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}. - * @return one of the {@code CMAS_SEVERITY} values - */ - public int getSeverity() { - return mSeverity; - } - - /** - * Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}. - * @return one of the {@code CMAS_URGENCY} values - */ - public int getUrgency() { - return mUrgency; - } - - /** - * Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}. - * @return one of the {@code CMAS_CERTAINTY} values - */ - public int getCertainty() { - return mCertainty; - } - - @Override - public String toString() { - return "SmsCbCmasInfo{messageClass=" + mMessageClass + ", category=" + mCategory - + ", responseType=" + mResponseType + ", severity=" + mSeverity - + ", urgency=" + mUrgency + ", certainty=" + mCertainty + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } - - /** Creator for unparcelling objects. */ - public static final Parcelable.Creator - CREATOR = new Parcelable.Creator() { - public SmsCbCmasInfo createFromParcel(Parcel in) { - return new SmsCbCmasInfo(in); - } - - public SmsCbCmasInfo[] newArray(int size) { - return new SmsCbCmasInfo[size]; - } - }; -} diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java deleted file mode 100644 index 0890d528f866..000000000000 --- a/telephony/java/android/telephony/SmsCbEtwsInfo.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2012 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 android.os.Parcelable; -import android.text.format.Time; - -import com.android.internal.telephony.IccUtils; - -import java.util.Arrays; - -/** - * Contains information elements for a GSM or UMTS ETWS warning notification. - * Supported values for each element are defined in 3GPP TS 23.041. - * - * {@hide} - */ -public class SmsCbEtwsInfo implements Parcelable { - - /** ETWS warning type for earthquake. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; - - /** ETWS warning type for tsunami. */ - public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; - - /** ETWS warning type for earthquake and tsunami. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; - - /** ETWS warning type for test messages. */ - public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03; - - /** ETWS warning type for other emergency types. */ - public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04; - - /** Unknown ETWS warning type. */ - public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; - - /** One of the ETWS warning type constants defined in this class. */ - private final int mWarningType; - - /** Whether or not to activate the emergency user alert tone and vibration. */ - private final boolean mEmergencyUserAlert; - - /** Whether or not to activate a popup alert. */ - private final boolean mActivatePopup; - - /** - * 50-byte security information (ETWS primary notification for GSM only). As of Release 10, - * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp - * and digital signature if received. Therefore it is treated as a raw byte array and - * parceled with the broadcast intent if present, but the timestamp is only computed if an - * application asks for the individual components. - */ - private final byte[] mWarningSecurityInformation; - - /** Create a new SmsCbEtwsInfo object with the specified values. */ - public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup, - byte[] warningSecurityInformation) { - mWarningType = warningType; - mEmergencyUserAlert = emergencyUserAlert; - mActivatePopup = activatePopup; - mWarningSecurityInformation = warningSecurityInformation; - } - - /** Create a new SmsCbEtwsInfo object from a Parcel. */ - SmsCbEtwsInfo(Parcel in) { - mWarningType = in.readInt(); - mEmergencyUserAlert = (in.readInt() != 0); - mActivatePopup = (in.readInt() != 0); - mWarningSecurityInformation = in.createByteArray(); - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mWarningType); - dest.writeInt(mEmergencyUserAlert ? 1 : 0); - dest.writeInt(mActivatePopup ? 1 : 0); - dest.writeByteArray(mWarningSecurityInformation); - } - - /** - * Returns the ETWS warning type. - * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE} - */ - public int getWarningType() { - return mWarningType; - } - - /** - * Returns the ETWS emergency user alert flag. - * @return true to notify terminal to activate emergency user alert; false otherwise - */ - public boolean isEmergencyUserAlert() { - return mEmergencyUserAlert; - } - - /** - * Returns the ETWS activate popup flag. - * @return true to notify terminal to activate display popup; false otherwise - */ - public boolean isPopupAlert() { - return mActivatePopup; - } - - /** - * Returns the Warning-Security-Information timestamp (GSM primary notifications only). - * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. - * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present - */ - public long getPrimaryNotificationTimestamp() { - if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { - return 0; - } - - int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]); - int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]); - int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]); - int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]); - int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]); - int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]); - - // For the timezone, the most significant bit of the - // least significant nibble is the sign byte - // (meaning the max range of this field is 79 quarter-hours, - // which is more than enough) - - byte tzByte = mWarningSecurityInformation[6]; - - // Mask out sign bit. - int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); - - timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; - - Time time = new Time(Time.TIMEZONE_UTC); - - // We only need to support years above 2000. - time.year = 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) - (long) (timezoneOffset * 15 * 60 * 1000); - } - - /** - * Returns the digital signature (GSM primary notifications only). As of Release 10, - * 3GPP TS 23.041 states that the UE shall ignore this value if received. - * @return a byte array containing a copy of the primary notification digital signature - */ - public byte[] getPrimaryNotificationSignature() { - if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) { - return null; - } - return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50); - } - - @Override - public String toString() { - return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert=" - + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } - - /** Creator for unparcelling objects. */ - public static final Creator CREATOR = new Creator() { - public SmsCbEtwsInfo createFromParcel(Parcel in) { - return new SmsCbEtwsInfo(in); - } - - public SmsCbEtwsInfo[] newArray(int size) { - return new SmsCbEtwsInfo[size]; - } - }; -} diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java deleted file mode 100644 index 7b5bd0d4bb71..000000000000 --- a/telephony/java/android/telephony/SmsCbLocation.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.telephony.gsm.GsmCellLocation; - -/** - * Represents the location and geographical scope of a cell broadcast message. - * For GSM/UMTS, the Location Area and Cell ID are set when the broadcast - * geographical scope is cell wide or Location Area wide. For CDMA, the - * broadcast geographical scope is always PLMN wide. - * - * @hide - */ -public class SmsCbLocation implements Parcelable { - - /** The PLMN. Note that this field may be an empty string, but isn't allowed to be null. */ - private final String mPlmn; - - private final int mLac; - private final int mCid; - - /** - * Construct an empty location object. This is used for some test cases, and for - * cell broadcasts saved in older versions of the database without location info. - */ - public SmsCbLocation() { - mPlmn = ""; - mLac = -1; - mCid = -1; - } - - /** - * Construct a location object for the PLMN. This class is immutable, so - * the same object can be reused for multiple broadcasts. - */ - public SmsCbLocation(String plmn) { - mPlmn = plmn; - mLac = -1; - mCid = -1; - } - - /** - * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so - * the same object can be reused for multiple broadcasts. - */ - public SmsCbLocation(String plmn, int lac, int cid) { - mPlmn = plmn; - mLac = lac; - mCid = cid; - } - - /** - * Initialize the object from a Parcel. - */ - public SmsCbLocation(Parcel in) { - mPlmn = in.readString(); - mLac = in.readInt(); - mCid = in.readInt(); - } - - /** - * Returns the MCC/MNC of the network as a String. - * @return the PLMN identifier (MCC+MNC) as a String - */ - public String getPlmn() { - return mPlmn; - } - - /** - * Returns the GSM location area code, or UMTS service area code. - * @return location area code, -1 if unknown, 0xffff max legal value - */ - public int getLac() { - return mLac; - } - - /** - * Returns the GSM or UMTS cell ID. - * @return gsm cell id, -1 if unknown, 0xffff max legal value - */ - public int getCid() { - return mCid; - } - - @Override - public int hashCode() { - int hash = mPlmn.hashCode(); - hash = hash * 31 + mLac; - hash = hash * 31 + mCid; - return hash; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o == null || !(o instanceof SmsCbLocation)) { - return false; - } - SmsCbLocation other = (SmsCbLocation) o; - return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid; - } - - @Override - public String toString() { - return '[' + mPlmn + ',' + mLac + ',' + mCid + ']'; - } - - /** - * Test whether this location is within the location area of the specified object. - * - * @param area the location area to compare with this location - * @return true if this location is contained within the specified location area - */ - public boolean isInLocationArea(SmsCbLocation area) { - if (mCid != -1 && mCid != area.mCid) { - return false; - } - if (mLac != -1 && mLac != area.mLac) { - return false; - } - return mPlmn.equals(area.mPlmn); - } - - /** - * Test whether this location is within the location area of the CellLocation. - * - * @param plmn the PLMN to use for comparison - * @param lac the Location Area (GSM) or Service Area (UMTS) to compare with - * @param cid the Cell ID to compare with - * @return true if this location is contained within the specified PLMN, LAC, and Cell ID - */ - public boolean isInLocationArea(String plmn, int lac, int cid) { - if (!mPlmn.equals(plmn)) { - return false; - } - - if (mLac != -1 && mLac != lac) { - return false; - } - - if (mCid != -1 && mCid != cid) { - return false; - } - - return true; - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mPlmn); - dest.writeInt(mLac); - dest.writeInt(mCid); - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - @Override - public SmsCbLocation createFromParcel(Parcel in) { - return new SmsCbLocation(in); - } - - @Override - public SmsCbLocation[] newArray(int size) { - return new SmsCbLocation[size]; - } - }; - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } -} diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java deleted file mode 100644 index 046bf8c700eb..000000000000 --- a/telephony/java/android/telephony/SmsCbMessage.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Parcelable object containing a received cell broadcast message. There are four different types - * of Cell Broadcast messages: - * - *

    - *
  • opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores
  • - *
  • cell information messages, broadcast on channel 50, indicating the current cell name for - * roaming purposes (required to display on the idle screen in Brazil)
  • - *
  • emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)
  • - *
  • emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)
  • - *
- * - *

There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only), - * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were - * unified under a common name, avoiding some names, such as "Message Identifier", that refer to - * two completely different concepts in 3GPP and CDMA. - * - *

The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name - * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP - * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the - * application should - * - *

The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used - * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is - * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit - * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number - * are considered unique to the PLMN, to the current cell, or to the current Location Area (or - * Service Area in UMTS). The relevant values are concatenated into a single String which will be - * unique if the messages are not duplicates. - * - *

The SMS dispatcher does not detect duplicate messages. However, it does concatenate the - * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object. - * - *

Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive - * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts. - * Only system applications such as the CellBroadcastReceiver may receive notifications for - * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or - * interference with the immediate display of the alert message and playing of the alert sound and - * vibration pattern, which could be caused by poorly written or malicious non-system code. - * - * @hide - */ -public class SmsCbMessage implements Parcelable { - - protected static final String LOG_TAG = "SMSCB"; - - /** Cell wide geographical scope with immediate display (GSM/UMTS only). */ - public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; - - /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */ - public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; - - /** Location / service area wide geographical scope (GSM/UMTS only). */ - public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2; - - /** Cell wide geographical scope (GSM/UMTS only). */ - public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; - - /** GSM or UMTS format cell broadcast. */ - public static final int MESSAGE_FORMAT_3GPP = 1; - - /** CDMA format cell broadcast. */ - public static final int MESSAGE_FORMAT_3GPP2 = 2; - - /** Normal message priority. */ - public static final int MESSAGE_PRIORITY_NORMAL = 0; - - /** Interactive message priority. */ - public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; - - /** Urgent message priority. */ - public static final int MESSAGE_PRIORITY_URGENT = 2; - - /** Emergency message priority. */ - public static final int MESSAGE_PRIORITY_EMERGENCY = 3; - - /** Format of this message (for interpretation of service category values). */ - private final int mMessageFormat; - - /** Geographical scope of broadcast. */ - private final int mGeographicalScope; - - /** - * Serial number of broadcast (message identifier for CDMA, geographical scope + message code + - * update number for GSM/UMTS). The serial number plus the location code uniquely identify - * a cell broadcast for duplicate detection. - */ - private final int mSerialNumber; - - /** - * Location identifier for this message. It consists of the current operator MCC/MNC as a - * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the - * message is not binary 01, the Location Area is included for comparison. If the GS is - * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified. - */ - private final SmsCbLocation mLocation; - - /** - * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings, - * the information provided by the category is also available via {@link #getEtwsWarningInfo()} - * or {@link #getCmasWarningInfo()}. - */ - private final int mServiceCategory; - - /** Message language, as a two-character string, e.g. "en". */ - private final String mLanguage; - - /** Message body, as a String. */ - private final String mBody; - - /** Message priority (including emergency priority). */ - private final int mPriority; - - /** ETWS warning notification information (ETWS warnings only). */ - private final SmsCbEtwsInfo mEtwsWarningInfo; - - /** CMAS warning notification information (CMAS warnings only). */ - private final SmsCbCmasInfo mCmasWarningInfo; - - /** - * Create a new SmsCbMessage with the specified data. - */ - public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, - SmsCbLocation location, int serviceCategory, String language, String body, - int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) { - mMessageFormat = messageFormat; - mGeographicalScope = geographicalScope; - mSerialNumber = serialNumber; - mLocation = location; - mServiceCategory = serviceCategory; - mLanguage = language; - mBody = body; - mPriority = priority; - mEtwsWarningInfo = etwsWarningInfo; - mCmasWarningInfo = cmasWarningInfo; - } - - /** Create a new SmsCbMessage object from a Parcel. */ - public SmsCbMessage(Parcel in) { - mMessageFormat = in.readInt(); - mGeographicalScope = in.readInt(); - mSerialNumber = in.readInt(); - mLocation = new SmsCbLocation(in); - mServiceCategory = in.readInt(); - mLanguage = in.readString(); - mBody = in.readString(); - mPriority = in.readInt(); - int type = in.readInt(); - switch (type) { - case 'E': - // unparcel ETWS warning information - mEtwsWarningInfo = new SmsCbEtwsInfo(in); - mCmasWarningInfo = null; - break; - - case 'C': - // unparcel CMAS warning information - mEtwsWarningInfo = null; - mCmasWarningInfo = new SmsCbCmasInfo(in); - break; - - default: - mEtwsWarningInfo = null; - mCmasWarningInfo = null; - } - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mMessageFormat); - dest.writeInt(mGeographicalScope); - dest.writeInt(mSerialNumber); - mLocation.writeToParcel(dest, flags); - dest.writeInt(mServiceCategory); - dest.writeString(mLanguage); - dest.writeString(mBody); - dest.writeInt(mPriority); - if (mEtwsWarningInfo != null) { - // parcel ETWS warning information - dest.writeInt('E'); - mEtwsWarningInfo.writeToParcel(dest, flags); - } else if (mCmasWarningInfo != null) { - // parcel CMAS warning information - dest.writeInt('C'); - mCmasWarningInfo.writeToParcel(dest, flags); - } else { - // no ETWS or CMAS warning information - dest.writeInt('0'); - } - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - @Override - public SmsCbMessage createFromParcel(Parcel in) { - return new SmsCbMessage(in); - } - - @Override - public SmsCbMessage[] newArray(int size) { - return new SmsCbMessage[size]; - } - }; - - /** - * Return the geographical scope of this message (GSM/UMTS only). - * - * @return Geographical scope - */ - public int getGeographicalScope() { - return mGeographicalScope; - } - - /** - * Return the broadcast serial number of broadcast (message identifier for CDMA, or - * geographical scope + message code + update number for GSM/UMTS). The serial number plus - * the location code uniquely identify a cell broadcast for duplicate detection. - * - * @return the 16-bit CDMA message identifier or GSM/UMTS serial number - */ - public int getSerialNumber() { - return mSerialNumber; - } - - /** - * Return the location identifier for this message, consisting of the MCC/MNC as a - * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the - * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the - * cell ID is also included. The {@link SmsCbLocation} object includes a method to test - * if the location is included within another location area or within a PLMN and CellLocation. - * - * @return the geographical location code for duplicate message detection - */ - public SmsCbLocation getLocation() { - return mLocation; - } - - /** - * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation - * of the category is radio technology specific. For ETWS and CMAS warnings, the information - * provided by the category is available via {@link #getEtwsWarningInfo()} or - * {@link #getCmasWarningInfo()} in a radio technology independent format. - * - * @return the radio technology specific service category - */ - public int getServiceCategory() { - return mServiceCategory; - } - - /** - * Get the ISO-639-1 language code for this message, or null if unspecified - * - * @return Language code - */ - public String getLanguageCode() { - return mLanguage; - } - - /** - * Get the body of this message, or null if no body available - * - * @return Body, or null - */ - public String getMessageBody() { - return mBody; - } - - /** - * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}). - * @return an integer representing 3GPP or 3GPP2 message format - */ - public int getMessageFormat() { - return mMessageFormat; - } - - /** - * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL} - * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return - * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}. - * @return an integer representing the message priority - */ - public int getMessagePriority() { - return mPriority; - } - - /** - * If this is an ETWS warning notification then this method will return an object containing - * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an - * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte - * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the - * ETWS primary notification timestamp and digital signature if received. - * - * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification - */ - public SmsCbEtwsInfo getEtwsWarningInfo() { - return mEtwsWarningInfo; - } - - /** - * If this is a CMAS warning notification then this method will return an object containing - * the CMAS message class, category, response type, severity, urgency and certainty. - * The message class is always present. Severity, urgency and certainty are present for CDMA - * warning notifications containing a type 1 elements record and for GSM and UMTS warnings - * except for the Presidential-level alert category. Category and response type are only - * available for CDMA notifications containing a type 1 elements record. - * - * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification - */ - public SmsCbCmasInfo getCmasWarningInfo() { - return mCmasWarningInfo; - } - - /** - * Return whether this message is an emergency (PWS) message type. - * @return true if the message is a public warning notification; false otherwise - */ - public boolean isEmergencyMessage() { - return mPriority == MESSAGE_PRIORITY_EMERGENCY; - } - - /** - * Return whether this message is an ETWS warning alert. - * @return true if the message is an ETWS warning notification; false otherwise - */ - public boolean isEtwsMessage() { - return mEtwsWarningInfo != null; - } - - /** - * Return whether this message is a CMAS warning alert. - * @return true if the message is a CMAS warning notification; false otherwise - */ - public boolean isCmasMessage() { - return mCmasWarningInfo != null; - } - - @Override - public String toString() { - return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber=" - + mSerialNumber + ", location=" + mLocation + ", serviceCategory=" - + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody - + ", priority=" + mPriority - + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "") - + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } -} diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java deleted file mode 100644 index 44bdaeb7876e..000000000000 --- a/telephony/java/android/telephony/SmsManager.java +++ /dev/null @@ -1,522 +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 android.telephony; - -import android.app.PendingIntent; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.text.TextUtils; - -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; - -/* - * TODO(code review): Curious question... Why are a lot of these - * methods not declared as static, since they do not seem to require - * any local object state? Presumably this cannot be changed without - * interfering with the API... - */ - -/** - * 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 { - /** Singleton object constructed during class initialization. */ - private static final SmsManager sInstance = new SmsManager(); - - /** - * 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 PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent 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"); - } - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Divide a message text into several fragments, none bigger than - * the maximum SMS message size. - * - * @param text the original message. Must not be null. - * @return an ArrayList of strings that, in order, - * comprise the original message - */ - public ArrayList divideMessage(String text) { - return SmsMessage.fragmentText(text); - } - - /** - * Send a multi-part text based SMS. The callee should have already - * divided the message into correctly sized parts by calling - * divideMessage. - * - * @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 ArrayList of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an ArrayList of - * PendingIntents (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE each sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 deliveryIntents if not null, an ArrayList of - * PendingIntents (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 parts, - ArrayList sentIntents, ArrayList 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 PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent 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"); - } - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF, - data, 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() { - return sInstance; - } - - private SmsManager() { - //nothing - } - - /** - * Copy a raw SMS PDU to the ICC. - * ICC (Integrated Circuit Card) is the card of the device. - * For example, this can be the SIM or USIM for GSM. - * - * @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. - * ICC (Integrated Circuit Card) is the card of the device. - * For example, this can be the SIM or USIM for GSM. - * - * @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. - * ICC (Integrated Circuit Card) is the card of the device. - * For example, this can be the SIM or USIM for GSM. - * - * @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. - * ICC (Integrated Circuit Card) is the card of the device. - * For example, this can be the SIM or USIM for GSM. - * - * @return ArrayList of SmsMessage objects - * - * {@hide} - */ - public static ArrayList getAllMessagesFromIcc() { - List 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); - } - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. All received messages will be broadcast in an - * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * @param messageIdentifier Message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * @see #disableCellBroadcast(int) - * - * {@hide} - */ - public boolean enableCellBroadcast(int messageIdentifier) { - boolean success = false; - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - success = iccISms.enableCellBroadcast(messageIdentifier); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * @param messageIdentifier Message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #enableCellBroadcast(int) - * - * {@hide} - */ - public boolean disableCellBroadcast(int messageIdentifier) { - boolean success = false; - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - success = iccISms.disableCellBroadcast(messageIdentifier); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. All received messages will be broadcast in an - * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * @param startMessageId first message identifier as specified in TS 23.041 - * @param endMessageId last message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * @see #disableCellBroadcastRange(int, int) - * - * {@hide} - */ - public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { - boolean success = false; - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - success = iccISms.enableCellBroadcastRange(startMessageId, endMessageId); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * @param startMessageId first message identifier as specified in TS 23.041 - * @param endMessageId last message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #enableCellBroadcastRange(int, int) - * - * {@hide} - */ - public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { - boolean success = false; - - try { - ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - if (iccISms != null) { - success = iccISms.disableCellBroadcastRange(startMessageId, endMessageId); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Create a list of SmsMessages from a list of RawSmsData - * records returned by getAllMessagesFromIcc() - * - * @param records SMS EF records, returned by - * getAllMessagesFromIcc - * @return ArrayList of SmsMessage objects. - */ - private static ArrayList createMessageListFromRawRecords(List records) { - ArrayList messages = new ArrayList(); - if (records != null) { - int count = records.size(); - for (int i = 0; i < count; i++) { - SmsRawData data = records.get(i); - // List contains all records, including "free" records (null) - if (data != null) { - SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes()); - if (sms != null) { - 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; - /** Failed because we reached the sending queue limit. {@hide} */ - static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5; - /** Failed because FDN is enabled. {@hide} */ - static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; -} diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java deleted file mode 100644 index 141074717c21..000000000000 --- a/telephony/java/android/telephony/SmsMessage.java +++ /dev/null @@ -1,680 +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 android.telephony; - -import android.os.Parcel; -import android.util.Log; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.SmsMessageBase.SubmitPduBase; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; - -import java.lang.Math; -import java.util.ArrayList; -import java.util.Arrays; - -import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; - - -/** - * A Short Message Service message. - */ -public class SmsMessage { - 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; - } - - /** User data text encoding code unit size */ - public static final int ENCODING_UNKNOWN = 0; - public static final int ENCODING_7BIT = 1; - public static final int ENCODING_8BIT = 2; - public static final int ENCODING_16BIT = 3; - /** - * @hide This value is not defined in global standard. Only in Korea, this is used. - */ - public static final int ENCODING_KSC5601 = 4; - - /** The maximum number of payload bytes per message */ - public static final int MAX_USER_DATA_BYTES = 140; - - /** - * 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. - */ - 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; - - /** - * Indicates a 3GPP format SMS message. - * @hide pending API council approval - */ - public static final String FORMAT_3GPP = "3gpp"; - - /** - * Indicates a 3GPP2 format SMS message. - * @hide pending API council approval - */ - public static final String FORMAT_3GPP2 = "3gpp2"; - - /** Contains actual SmsMessage. Only public for debugging and for framework layer. - * - * @hide - */ - public SmsMessageBase mWrappedSmsMessage; - - public static class SubmitPdu { - - public byte[] encodedScAddress; // Null if not applicable. - public byte[] encodedMessage; - - public String toString() { - return "SubmitPdu: encodedScAddress = " - + Arrays.toString(encodedScAddress) - + ", encodedMessage = " - + Arrays.toString(encodedMessage); - } - - /** - * @hide - */ - protected SubmitPdu(SubmitPduBase spb) { - this.encodedMessage = spb.encodedMessage; - this.encodedScAddress = spb.encodedScAddress; - } - - } - - private SmsMessage(SmsMessageBase smb) { - mWrappedSmsMessage = smb; - } - - /** - * Create an SmsMessage from a raw PDU. - * - *

This method will soon be deprecated and all applications which handle - * incoming SMS messages by processing the {@code SMS_RECEIVED_ACTION} broadcast - * intent must now pass the new {@code format} String extra from the intent - * into the new method {@code createFromPdu(byte[], String)} which takes an - * extra format parameter. This is required in order to correctly decode the PDU on - * devices that require support for both 3GPP and 3GPP2 formats at the same time, - * such as dual-mode GSM/CDMA and CDMA/LTE phones. - */ - public static SmsMessage createFromPdu(byte[] pdu) { - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - String format = (PHONE_TYPE_CDMA == activePhone) ? FORMAT_3GPP2 : FORMAT_3GPP; - return createFromPdu(pdu, format); - } - - /** - * Create an SmsMessage from a raw PDU with the specified message format. The - * message format is passed in the {@code SMS_RECEIVED_ACTION} as the {@code format} - * String extra, and will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format - * or "3gpp2" for CDMA/LTE messages in 3GPP2 format. - * - * @param pdu the message PDU from the SMS_RECEIVED_ACTION intent - * @param format the format extra from the SMS_RECEIVED_ACTION intent - * @hide pending API council approval - */ - public static SmsMessage createFromPdu(byte[] pdu, String format) { - SmsMessageBase wrappedMessage; - - if (FORMAT_3GPP2.equals(format)) { - wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu); - } else if (FORMAT_3GPP.equals(format)) { - wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu); - } else { - Log.e(LOG_TAG, "createFromPdu(): unsupported message format " + format); - return null; - } - - 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: [<alpha>], - * - * Only public for debugging and for RIL - * - * {@hide} - */ - public static SmsMessage newFromCMT(String[] lines) { - // received SMS in 3GPP format - SmsMessageBase wrappedMessage = - com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines); - - return new SmsMessage(wrappedMessage); - } - - /** @hide */ - public static SmsMessage newFromParcel(Parcel p) { - // received SMS in 3GPP2 format - SmsMessageBase wrappedMessage = - com.android.internal.telephony.cdma.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().getCurrentPhoneType(); - - 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 wrappedMessage != null ? new SmsMessage(wrappedMessage) : null; - } - - /** - * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the - * length in bytes (not hex chars) less the SMSC header - * - * FIXME: This method is only used by a CTS test case that isn't run on CDMA devices. - * We should probably deprecate it and remove the obsolete test case. - */ - public static int getTPLayerLengthForPDU(String pdu) { - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - - if (PHONE_TYPE_CDMA == activePhone) { - return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu); - } else { - return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu); - } - } - - /* - * TODO(cleanup): It would make some sense if the result of - * preprocessing a message to determine the proper encoding (i.e. - * the resulting data structure from calculateLength) could be - * passed as an argument to the actual final encoding function. - * This would better ensure that the logic behind size calculation - * actually matched the encoding. - */ - - /** - * Calculates the number of SMS's required to encode the message body and - * the number of characters remaining until the next message. - * - * @param msgBody the message to encode - * @param use7bitOnly if true, characters that are not part of the - * radio-specific 7-bit encoding are counted as single - * space chars. If false, and if the messageBody contains - * non-7-bit encodable characters, length is calculated - * using a 16-bit encoding. - * @return an int[4] with int[0] being the number of SMS's - * required, int[1] the number of code units used, and - * int[2] is the number of code units remaining until the - * next message. int[3] is an indicator of the encoding - * code unit size (see the ENCODING_* definitions in this - * class). - */ - public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) { - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ? - com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly) : - com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly); - int ret[] = new int[4]; - ret[0] = ted.msgCount; - ret[1] = ted.codeUnitCount; - ret[2] = ted.codeUnitsRemaining; - ret[3] = ted.codeUnitSize; - return ret; - } - - /** - * Divide a message text into several fragments, none bigger than - * the maximum SMS message text size. - * - * @param text text, must not be null. - * @return an ArrayList of strings that, in order, - * comprise the original msg text - * - * @hide - */ - public static ArrayList fragmentText(String text) { - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ? - com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false) : - com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false); - - // TODO(cleanup): The code here could be rolled into the logic - // below cleanly if these MAX_* constants were defined more - // flexibly... - - int limit; - if (ted.codeUnitSize == ENCODING_7BIT) { - int udhLength; - if (ted.languageTable != 0 && ted.languageShiftTable != 0) { - udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES; - } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) { - udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE; - } else { - udhLength = 0; - } - - if (ted.msgCount > 1) { - udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE; - } - - if (udhLength != 0) { - udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH; - } - - limit = MAX_USER_DATA_SEPTETS - udhLength; - } else { - if (ted.msgCount > 1) { - limit = MAX_USER_DATA_BYTES_WITH_HEADER; - } else { - limit = MAX_USER_DATA_BYTES; - } - } - - int pos = 0; // Index in code units. - int textLen = text.length(); - ArrayList result = new ArrayList(ted.msgCount); - while (pos < textLen) { - int nextPos = 0; // Counts code units. - if (ted.codeUnitSize == ENCODING_7BIT) { - if (activePhone == PHONE_TYPE_CDMA && ted.msgCount == 1) { - // For a singleton CDMA message, the encoding must be ASCII... - nextPos = pos + Math.min(limit, textLen - pos); - } else { - // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode). - nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit, - ted.languageTable, ted.languageShiftTable); - } - } else { // Assume unicode. - nextPos = pos + Math.min(limit / 2, textLen - pos); - } - if ((nextPos <= pos) || (nextPos > textLen)) { - Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " + - nextPos + " >= " + textLen + ")"); - break; - } - result.add(text.substring(pos, nextPos)); - pos = nextPos; - } - return result; - } - - /** - * 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 radio - * specific (GSM / CDMA) alphabet encoding are converted to as a - * single space characters. If false, a messageBody containing - * non-GSM or non-CDMA alphabet characters are encoded using - * 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) { - return calculateLength((CharSequence)messageBody, use7bitOnly); - } - - /* - * TODO(cleanup): It looks like there is now no useful reason why - * apps should generate pdus themselves using these routines, - * instead of handing the raw data to SMSDispatcher (and thereby - * have the phone process do the encoding). Moreover, CDMA now - * has shared state (in the form of the msgId system property) - * which can only be modified by the phone process, and hence - * makes the output of these routines incorrect. Since they now - * serve no purpose, they should probably just return null - * directly, and be deprecated. Going further in that direction, - * the above parsers of serialized pdu data should probably also - * be gotten rid of, hiding all but the necessarily visible - * structured data from client apps. A possible concern with - * doing this is that apps may be using these routines to generate - * pdus that are then sent elsewhere, some network server, for - * example, and that always returning null would thereby break - * otherwise useful apps. - */ - - /** - * Get an SMS-SUBMIT PDU for a destination address and a message. - * This method will not attempt to use any GSM national language 7 bit encodings. - * - * @param scAddress Service Centre address. Null means use default. - * @return a SubmitPdu 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().getCurrentPhoneType(); - - if (PHONE_TYPE_CDMA == activePhone) { - spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress, - destinationAddress, message, statusReportRequested, null); - } 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 & port. - * This method will not attempt to use any GSM national language 7 bit encodings. - * - * @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 SubmitPdu 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().getCurrentPhoneType(); - - 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(); - } - - /** - * 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 TP-Reply-Path bit is set in - * this message. - */ - public boolean isReplyPathPresent() { - return mWrappedSmsMessage.isReplyPathPresent(); - } -} diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index bc50906e0c7d..fa4b7cdc16ab 100755 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -23,15 +23,20 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.util.Log; import com.android.internal.telephony.IPhoneSubInfo; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.ITelephonyRegistry; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.TelephonyProperties; +import java.io.FileInputStream; +import java.io.IOException; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Provides access to information about the telephony services on @@ -131,25 +136,25 @@ public class TelephonyManager { * Retrieve with * {@link android.content.Intent#getStringExtra(String)}. */ - public static final String EXTRA_STATE = Phone.STATE_KEY; + public static final String EXTRA_STATE = PhoneConstants.STATE_KEY; /** * Value used with {@link #EXTRA_STATE} corresponding to * {@link #CALL_STATE_IDLE}. */ - public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString(); + public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString(); /** * Value used with {@link #EXTRA_STATE} corresponding to * {@link #CALL_STATE_RINGING}. */ - public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString(); + public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString(); /** * Value used with {@link #EXTRA_STATE} corresponding to * {@link #CALL_STATE_OFFHOOK}. */ - public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString(); + public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString(); /** * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast @@ -279,13 +284,13 @@ public class TelephonyManager { } /** No phone radio. */ - public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE; + public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE; /** Phone radio is GSM. */ - public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM; + public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM; /** Phone radio is CDMA. */ - public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA; + public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA; /** Phone is via SIP. */ - public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP; + public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP; /** * Returns the current phone type. @@ -348,8 +353,125 @@ public class TelephonyManager { int mode = SystemProperties.getInt("ro.telephony.default_network", -1); if (mode == -1) return PHONE_TYPE_NONE; - return PhoneFactory.getPhoneType(mode); + return getPhoneType(mode); } + + /** + * This function returns the type of the phone, depending + * on the network mode. + * + * @param network mode + * @return Phone Type + * + * @hide + */ + public static int getPhoneType(int networkMode) { + switch(networkMode) { + case RILConstants.NETWORK_MODE_CDMA: + case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: + case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + return PhoneConstants.PHONE_TYPE_CDMA; + + case RILConstants.NETWORK_MODE_WCDMA_PREF: + case RILConstants.NETWORK_MODE_GSM_ONLY: + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + case RILConstants.NETWORK_MODE_GSM_UMTS: + return PhoneConstants.PHONE_TYPE_GSM; + + // Use CDMA Phone for the global mode including CDMA + case RILConstants.NETWORK_MODE_GLOBAL: + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: + case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA: + return PhoneConstants.PHONE_TYPE_CDMA; + + case RILConstants.NETWORK_MODE_LTE_ONLY: + if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { + return PhoneConstants.PHONE_TYPE_CDMA; + } else { + return PhoneConstants.PHONE_TYPE_GSM; + } + default: + return PhoneConstants.PHONE_TYPE_GSM; + } + } + + /** + * The contents of the /proc/cmdline file + */ + private static String getProcCmdLine() + { + String cmdline = ""; + FileInputStream is = null; + try { + is = new FileInputStream("/proc/cmdline"); + byte [] buffer = new byte[2048]; + int count = is.read(buffer); + if (count > 0) { + cmdline = new String(buffer, 0, count); + } + } catch (IOException e) { + Log.d(TAG, "No /proc/cmdline exception=" + e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + } + } + } + Log.d(TAG, "/proc/cmdline=" + cmdline); + return cmdline; + } + + /** Kernel command line */ + private static final String sKernelCmdLine = getProcCmdLine(); + + /** Pattern for selecting the product type from the kernel command line */ + private static final Pattern sProductTypePattern = + Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)"); + + /** The ProductType used for LTE on CDMA devices */ + private static final String sLteOnCdmaProductType = + SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, ""); + + /** + * Return if the current radio is LTE on CDMA. This + * is a tri-state return value as for a period of time + * the mode may be unknown. + * + * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} + * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} + * + * @hide + */ + public static int getLteOnCdmaModeStatic() { + int retVal; + int curVal; + String productType = ""; + + curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE, + PhoneConstants.LTE_ON_CDMA_UNKNOWN); + retVal = curVal; + if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) { + Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine); + if (matcher.find()) { + productType = matcher.group(1); + if (sLteOnCdmaProductType.equals(productType)) { + retVal = PhoneConstants.LTE_ON_CDMA_TRUE; + } else { + retVal = PhoneConstants.LTE_ON_CDMA_FALSE; + } + } else { + retVal = PhoneConstants.LTE_ON_CDMA_FALSE; + } + } + + Log.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal + + " product_type='" + productType + + "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'"); + return retVal; + } + // // // Current Network @@ -695,10 +817,10 @@ public class TelephonyManager { return getITelephony().getLteOnCdmaMode(); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen - return Phone.LTE_ON_CDMA_UNKNOWN; + return PhoneConstants.LTE_ON_CDMA_UNKNOWN; } catch (NullPointerException ex) { // This could happen before phone restarts due to crashing - return Phone.LTE_ON_CDMA_UNKNOWN; + return PhoneConstants.LTE_ON_CDMA_UNKNOWN; } } diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java deleted file mode 100644 index 3b75298b593d..000000000000 --- a/telephony/java/android/telephony/gsm/SmsManager.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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 android.telephony.gsm; - -import android.app.PendingIntent; - -import java.util.ArrayList; - - -/** - * 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. - */ -@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; - } - - @Deprecated - private SmsManager() { - mSmsMgrProxy = android.telephony.SmsManager.getDefault(); - } - - /** - * 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 PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU. - * 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 PendingIntent 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. - */ - @Deprecated - public final void sendTextMessage( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent) { - mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text, - 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 ArrayList of strings that, in order, - * comprise the original message - * @deprecated Use android.telephony.SmsManager. - */ - @Deprecated - public final ArrayList 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 - * divideMessage. - * - * @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 ArrayList of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an ArrayList of - * PendingIntents (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU. - * 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 ArrayList of - * PendingIntents (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. - */ - @Deprecated - public final void sendMultipartTextMessage( - String destinationAddress, String scAddress, ArrayList parts, - ArrayList sentIntents, ArrayList deliveryIntents) { - mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts, - sentIntents, deliveryIntents); - } - - /** - * 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 PendingIntent is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU. - * 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 PendingIntent 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 - * @deprecated Use android.telephony.SmsManager. - */ - @Deprecated - public final void sendDataMessage( - String destinationAddress, String scAddress, short destinationPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort, - data, sentIntent, deliveryIntent); - } - - /** - * Copy a raw SMS PDU to the SIM. - * - * @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_SIM_READ, STATUS_ON_SIM_UNREAD, - * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT) - * @return true for success - * @deprecated Use android.telephony.SmsManager. - * {@hide} - */ - @Deprecated - public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) { - return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status); - } - - /** - * Delete the specified message from the SIM. - * - * @param messageIndex is the record index of the message on SIM - * @return true for success - * @deprecated Use android.telephony.SmsManager. - * {@hide} - */ - @Deprecated - public final boolean deleteMessageFromSim(int messageIndex) { - return mSmsMgrProxy.deleteMessageFromIcc(messageIndex); - } - - /** - * Update the specified message on the SIM. - * - * @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 pdu the raw PDU to store - * @return true for success - * @deprecated Use android.telephony.SmsManager. - * {@hide} - */ - @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 ArrayList of SmsMessage objects - * @deprecated Use android.telephony.SmsManager. - * {@hide} - */ - @Deprecated - public final ArrayList getAllMessagesFromSim() { - return mSmsMgrProxy.getAllMessagesFromIcc(); - } - - /** Free space (TS 51.011 10.5.3). - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int STATUS_ON_SIM_FREE = 0; - - /** Received and read (TS 51.011 10.5.3). - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int STATUS_ON_SIM_READ = 1; - - /** Received and unread (TS 51.011 10.5.3). - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int STATUS_ON_SIM_UNREAD = 3; - - /** Stored and sent (TS 51.011 10.5.3). - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int STATUS_ON_SIM_SENT = 5; - - /** Stored and unsent (TS 51.011 10.5.3). - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int STATUS_ON_SIM_UNSENT = 7; - - /** Generic failure cause - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated static public final int RESULT_ERROR_GENERIC_FAILURE = 1; - - /** 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; - - /** Failed because service is currently unavailable - * @deprecated Use android.telephony.SmsManager. */ - @Deprecated 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 deleted file mode 100644 index 8d86ec296854..000000000000 --- a/telephony/java/android/telephony/gsm/SmsMessage.java +++ /dev/null @@ -1,628 +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 android.telephony.gsm; - -import android.os.Parcel; -import android.telephony.TelephonyManager; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.EncodeException; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.SmsMessageBase.SubmitPduBase; - -import java.util.Arrays; - -import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; - - -/** - * 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"; - - /** - * SMS Class enumeration. - * See TS 23.038. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public enum MessageClass{ - UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3; - } - - /** Unknown encoding scheme (see TS 23.038) - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated public static final int ENCODING_UNKNOWN = 0; - - /** 7-bit encoding scheme (see TS 23.038) - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated public static final int ENCODING_7BIT = 1; - - /** 8-bit encoding scheme (see TS 23.038) - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated public static final int ENCODING_8BIT = 2; - - /** 16-bit encoding scheme (see TS 23.038) - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated public static final int ENCODING_16BIT = 3; - - /** The maximum number of payload bytes per message - * @deprecated Use android.telephony.SmsMessage. - */ - @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 - */ - @Deprecated public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134; - - /** 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. - */ - @Deprecated public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153; - - /** Contains actual SmsMessage. Only public for debugging and for framework layer. - * @deprecated Use android.telephony.SmsMessage. - * {@hide} - */ - @Deprecated public SmsMessageBase mWrappedSmsMessage; - - /** @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; - - //Constructor - /** @deprecated Use android.telephony.SmsMessage. */ - @Deprecated - public SubmitPdu() { - } - - /** @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) - + ", encodedMessage = " - + Arrays.toString(encodedMessage); - } - } - - // 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) { - SmsMessageBase wrappedMessage; - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - - 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); - } - - /** - * 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 activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - - 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. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) { - SmsMessageBase.TextEncodingDetails ted = - com.android.internal.telephony.gsm.SmsMessage - .calculateLength(messageBody, use7bitOnly); - int ret[] = new int[4]; - ret[0] = ted.msgCount; - ret[1] = ted.codeUnitCount; - ret[2] = ted.codeUnitsRemaining; - ret[3] = ted.codeUnitSize; - return ret; - } - - /** - * 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. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public static int[] calculateLength(String messageBody, boolean use7bitOnly) { - return calculateLength((CharSequence)messageBody, use7bitOnly); - } - - /** - * Get an SMS-SUBMIT PDU for a destination address and a message - * - * @param scAddress Service Centre address. Null means use default. - * @return a SubmitPdu 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().getCurrentPhoneType(); - - if (PHONE_TYPE_CDMA == activePhone) { - spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress, - destinationAddress, message, statusReportRequested, - SmsHeader.fromByteArray(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 SubmitPdu 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) { - SubmitPduBase spb; - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - - if (PHONE_TYPE_CDMA == activePhone) { - spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress, - destinationAddress, message, statusReportRequested, null); - } 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 & 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 SubmitPdu 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) { - SubmitPduBase spb; - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - - 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. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public String getServiceCenterAddress() { - 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() { - 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() { - 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 mWrappedSmsMessage.getMessageBody(); - } - - /** - * Returns the class of this message. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public MessageClass getMessageClass() { - 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() { - 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 mWrappedSmsMessage.getPseudoSubject(); - } - - /** - * Returns the service centre timestamp in currentTimeMillis() format - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - 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 - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public boolean 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 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 mWrappedSmsMessage.getEmailFrom(); - } - - /** - * Get protocol identifier. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public int getProtocolIdentifier() { - return mWrappedSmsMessage.getProtocolIdentifier(); - } - - /** - * 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 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 - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public boolean isCphsMwiMessage() { - 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() { - 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() { - 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() { - return mWrappedSmsMessage.isMwiDontStore(); - } - - /** - * returns the user data section minus the user data header if one was present. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - 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. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - 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 android.telephony.SmsMessage and 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 - * @deprecated Use android.telephony.SmsMessage. - * @hide - */ - @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 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. - * @hide - */ - @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 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. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public int getStatus() { - return mWrappedSmsMessage.getStatus(); - } - - /** - * Return true iff the message is a SMS-STATUS-REPORT message. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - public boolean isStatusReportMessage() { - return mWrappedSmsMessage.isStatusReportMessage(); - } - - /** - * Returns true iff the TP-Reply-Path bit is set in - * this message. - * @deprecated Use android.telephony.SmsMessage. - */ - @Deprecated - 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. - * @deprecated Use android.telephony.SmsMessage. - */ - private static final SmsMessageBase getSmsFacility(){ - int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); - 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/com/android/internal/telephony/ATParseEx.java b/telephony/java/com/android/internal/telephony/ATParseEx.java deleted file mode 100644 index c93b875e8bd0..000000000000 --- a/telephony/java/com/android/internal/telephony/ATParseEx.java +++ /dev/null @@ -1,35 +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; - -/** - * {@hide} - */ -public class ATParseEx extends RuntimeException -{ - public - ATParseEx() - { - super(); - } - - public - ATParseEx(String s) - { - super(s); - } -} diff --git a/telephony/java/com/android/internal/telephony/ATResponseParser.java b/telephony/java/com/android/internal/telephony/ATResponseParser.java deleted file mode 100644 index fdb05262da4c..000000000000 --- a/telephony/java/com/android/internal/telephony/ATResponseParser.java +++ /dev/null @@ -1,186 +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; - -/** - * {@hide} - */ -public class ATResponseParser -{ - /*************************** Instance Variables **************************/ - - private String line; - private int next = 0; - private int tokStart, tokEnd; - - /***************************** Class Methods *****************************/ - - public - ATResponseParser (String line) - { - this.line = line; - } - - public boolean - nextBoolean() - { - // "\s*(\d)(,|$)" - // \d is '0' or '1' - - nextTok(); - - if (tokEnd - tokStart > 1) { - throw new ATParseEx(); - } - char c = line.charAt(tokStart); - - if (c == '0') return false; - if (c == '1') return true; - throw new ATParseEx(); - } - - - /** positive int only */ - public int - nextInt() - { - // "\s*(\d+)(,|$)" - int ret = 0; - - nextTok(); - - for (int i = tokStart ; i < tokEnd ; i++) { - char c = line.charAt(i); - - // Yes, ASCII decimal digits only - if (c < '0' || c > '9') { - throw new ATParseEx(); - } - - ret *= 10; - ret += c - '0'; - } - - return ret; - } - - public String - nextString() - { - nextTok(); - - return line.substring(tokStart, tokEnd); - } - - public boolean - hasMore() - { - return next < line.length(); - } - - private void - nextTok() - { - int len = line.length(); - - if (next == 0) { - skipPrefix(); - } - - if (next >= len) { - throw new ATParseEx(); - } - - try { - // \s*("([^"]*)"|(.*)\s*)(,|$) - - char c = line.charAt(next++); - boolean hasQuote = false; - - c = skipWhiteSpace(c); - - if (c == '"') { - if (next >= len) { - throw new ATParseEx(); - } - c = line.charAt(next++); - tokStart = next - 1; - while (c != '"' && next < len) { - c = line.charAt(next++); - } - if (c != '"') { - throw new ATParseEx(); - } - tokEnd = next - 1; - if (next < len && line.charAt(next++) != ',') { - throw new ATParseEx(); - } - } else { - tokStart = next - 1; - tokEnd = tokStart; - while (c != ',') { - if (!Character.isWhitespace(c)) { - tokEnd = next; - } - if (next == len) { - break; - } - c = line.charAt(next++); - } - } - } catch (StringIndexOutOfBoundsException ex) { - throw new ATParseEx(); - } - } - - - /** Throws ATParseEx if whitespace extends to the end of string */ - private char - skipWhiteSpace (char c) - { - int len; - len = line.length(); - while (next < len && Character.isWhitespace(c)) { - c = line.charAt(next++); - } - - if (Character.isWhitespace(c)) { - throw new ATParseEx(); - } - return c; - } - - - private void - skipPrefix() - { - // consume "^[^:]:" - - next = 0; - int s = line.length(); - while (next < s){ - char c = line.charAt(next++); - - if (c == ':') { - return; - } - } - - throw new ATParseEx("missing prefix"); - } - -} diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java deleted file mode 100644 index 1bf2d3c61d50..000000000000 --- a/telephony/java/com/android/internal/telephony/AdnRecord.java +++ /dev/null @@ -1,321 +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; - -import android.os.Parcel; -import android.os.Parcelable; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; -import android.util.Log; - -import java.util.Arrays; - - -/** - * - * Used to load or store ADNs (Abbreviated Dialing Numbers). - * - * {@hide} - * - */ -public class AdnRecord implements Parcelable { - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - String alphaTag = null; - String number = null; - String[] emails; - int extRecord = 0xff; - int efid; // or 0 if none - int recordNumber; // or 0 if none - - - //***** Constants - - // In an ADN record, everything but the alpha identifier - // is in a footer that's 14 bytes - static final int FOOTER_SIZE_BYTES = 14; - - // Maximum size of the un-extended number field - static final int MAX_NUMBER_SIZE_BYTES = 11; - - static final int EXT_RECORD_LENGTH_BYTES = 13; - static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2; - static final int EXT_RECORD_TYPE_MASK = 3; - static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa; - - // ADN offset - static final int ADN_BCD_NUMBER_LENGTH = 0; - static final int ADN_TON_AND_NPI = 1; - static final int ADN_DIALING_NUMBER_START = 2; - static final int ADN_DIALING_NUMBER_END = 11; - static final int ADN_CAPABILITY_ID = 12; - static final int ADN_EXTENSION_ID = 13; - - //***** Static Methods - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public AdnRecord createFromParcel(Parcel source) { - int efid; - int recordNumber; - String alphaTag; - String number; - String[] emails; - - efid = source.readInt(); - recordNumber = source.readInt(); - alphaTag = source.readString(); - number = source.readString(); - emails = source.readStringArray(); - - return new AdnRecord(efid, recordNumber, alphaTag, number, emails); - } - - public AdnRecord[] newArray(int size) { - return new AdnRecord[size]; - } - }; - - - //***** Constructor - public AdnRecord (byte[] record) { - this(0, 0, record); - } - - public AdnRecord (int efid, int recordNumber, byte[] record) { - this.efid = efid; - this.recordNumber = recordNumber; - parseRecord(record); - } - - public AdnRecord (String alphaTag, String number) { - this(0, 0, alphaTag, number); - } - - public AdnRecord (String alphaTag, String number, String[] emails) { - this(0, 0, alphaTag, number, emails); - } - - public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) { - this.efid = efid; - this.recordNumber = recordNumber; - this.alphaTag = alphaTag; - this.number = number; - this.emails = emails; - } - - public AdnRecord(int efid, int recordNumber, String alphaTag, String number) { - this.efid = efid; - this.recordNumber = recordNumber; - this.alphaTag = alphaTag; - this.number = number; - this.emails = null; - } - - //***** Instance Methods - - public String getAlphaTag() { - return alphaTag; - } - - public String getNumber() { - return number; - } - - public String[] getEmails() { - return emails; - } - - public void setEmails(String[] emails) { - this.emails = emails; - } - - public String toString() { - return "ADN Record '" + alphaTag + "' '" + number + " " + emails + "'"; - } - - public boolean isEmpty() { - return TextUtils.isEmpty(alphaTag) && TextUtils.isEmpty(number) && emails == null; - } - - public boolean hasExtendedRecord() { - return extRecord != 0 && extRecord != 0xff; - } - - /** Helper function for {@link #isEqual}. */ - private static boolean stringCompareNullEqualsEmpty(String s1, String s2) { - if (s1 == s2) { - return true; - } - if (s1 == null) { - s1 = ""; - } - if (s2 == null) { - s2 = ""; - } - return (s1.equals(s2)); - } - - public boolean isEqual(AdnRecord adn) { - return ( stringCompareNullEqualsEmpty(alphaTag, adn.alphaTag) && - stringCompareNullEqualsEmpty(number, adn.number) && - Arrays.equals(emails, adn.emails)); - } - //***** Parcelable Implementation - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(efid); - dest.writeInt(recordNumber); - dest.writeString(alphaTag); - dest.writeString(number); - dest.writeStringArray(emails); - } - - /** - * Build adn hex byte array based on record size - * The format of byte array is defined in 51.011 10.5.1 - * - * @param recordSize is the size X of EF record - * @return hex byte[recordSize] to be written to EF record - * return null for wrong format of dialing number or tag - */ - public byte[] buildAdnString(int recordSize) { - byte[] bcdNumber; - byte[] byteTag; - byte[] adnString; - int footerOffset = recordSize - FOOTER_SIZE_BYTES; - - // create an empty record - adnString = new byte[recordSize]; - for (int i = 0; i < recordSize; i++) { - adnString[i] = (byte) 0xFF; - } - - if (TextUtils.isEmpty(number)) { - Log.w(LOG_TAG, "[buildAdnString] Empty dialing number"); - return adnString; // return the empty record (for delete) - } else if (number.length() - > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) { - Log.w(LOG_TAG, - "[buildAdnString] Max length of dialing number is 20"); - return null; - } else if (alphaTag != null && alphaTag.length() > footerOffset) { - Log.w(LOG_TAG, - "[buildAdnString] Max length of tag is " + footerOffset); - return null; - } else { - bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number); - - System.arraycopy(bcdNumber, 0, adnString, - footerOffset + ADN_TON_AND_NPI, bcdNumber.length); - - adnString[footerOffset + ADN_BCD_NUMBER_LENGTH] - = (byte) (bcdNumber.length); - adnString[footerOffset + ADN_CAPABILITY_ID] - = (byte) 0xFF; // Capability Id - adnString[footerOffset + ADN_EXTENSION_ID] - = (byte) 0xFF; // Extension Record Id - - if (!TextUtils.isEmpty(alphaTag)) { - byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag); - System.arraycopy(byteTag, 0, adnString, 0, byteTag.length); - } - - return adnString; - } - } - - /** - * See TS 51.011 10.5.10 - */ - public void - appendExtRecord (byte[] extRecord) { - try { - if (extRecord.length != EXT_RECORD_LENGTH_BYTES) { - return; - } - - if ((extRecord[0] & EXT_RECORD_TYPE_MASK) - != EXT_RECORD_TYPE_ADDITIONAL_DATA) { - return; - } - - if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) { - // invalid or empty record - return; - } - - number += PhoneNumberUtils.calledPartyBCDFragmentToString( - extRecord, 2, 0xff & extRecord[1]); - - // We don't support ext record chaining. - - } catch (RuntimeException ex) { - Log.w(LOG_TAG, "Error parsing AdnRecord ext record", ex); - } - } - - //***** Private Methods - - /** - * alphaTag and number are set to null on invalid format - */ - private void - parseRecord(byte[] record) { - try { - alphaTag = IccUtils.adnStringFieldToString( - record, 0, record.length - FOOTER_SIZE_BYTES); - - int footerOffset = record.length - FOOTER_SIZE_BYTES; - - int numberLength = 0xff & record[footerOffset]; - - if (numberLength > MAX_NUMBER_SIZE_BYTES) { - // Invalid number length - number = ""; - return; - } - - // 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 - // the ME (see note 2)." - - number = PhoneNumberUtils.calledPartyBCDToString( - record, footerOffset + 1, numberLength); - - - extRecord = 0xff & record[record.length - 1]; - - emails = null; - - } catch (RuntimeException ex) { - Log.w(LOG_TAG, "Error parsing AdnRecord", ex); - number = ""; - alphaTag = ""; - emails = null; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java deleted file mode 100644 index db5f4da6bd97..000000000000 --- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java +++ /dev/null @@ -1,364 +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; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.util.SparseArray; - -import com.android.internal.telephony.gsm.UsimPhoneBookManager; - -import java.util.ArrayList; -import java.util.Iterator; - -/** - * {@hide} - */ -public final class AdnRecordCache extends Handler implements IccConstants { - //***** Instance Variables - - private IccFileHandler mFh; - private UsimPhoneBookManager mUsimPhoneBookManager; - - // Indexed by EF ID - SparseArray> adnLikeFiles - = new SparseArray>(); - - // People waiting for ADN-like files to be loaded - SparseArray> adnLikeWaiters - = new SparseArray>(); - - // People waiting for adn record to be updated - SparseArray userWriteResponse = new SparseArray(); - - //***** Event Constants - - static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1; - static final int EVENT_UPDATE_ADN_DONE = 2; - - //***** Constructor - - - - public AdnRecordCache(IccFileHandler fh) { - mFh = fh; - mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this); - } - - //***** Called from SIMRecords - - /** - * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh. - */ - public void reset() { - adnLikeFiles.clear(); - mUsimPhoneBookManager.reset(); - - clearWaiters(); - clearUserWriters(); - - } - - private void clearWaiters() { - int size = adnLikeWaiters.size(); - for (int i = 0; i < size; i++) { - ArrayList waiters = adnLikeWaiters.valueAt(i); - AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset")); - notifyWaiters(waiters, ar); - } - adnLikeWaiters.clear(); - } - - private void clearUserWriters() { - int size = userWriteResponse.size(); - for (int i = 0; i < size; i++) { - sendErrorResponse(userWriteResponse.valueAt(i), "AdnCace reset"); - } - userWriteResponse.clear(); - } - - /** - * @return List of AdnRecords for efid if we've already loaded them this - * radio session, or null if we haven't - */ - public ArrayList - getRecordsIfLoaded(int efid) { - return adnLikeFiles.get(efid); - } - - /** - * Returns extension ef associated with ADN-like EF or -1 if - * we don't know. - * - * See 3GPP TS 51.011 for this mapping - */ - int extensionEfForEf(int efid) { - switch (efid) { - case EF_MBDN: return EF_EXT6; - 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_PBR: return 0; // The EF PBR doesn't have an extension record - default: return -1; - } - } - - private void sendErrorResponse(Message response, String errString) { - if (response != null) { - Exception e = new RuntimeException(errString); - AsyncResult.forMessage(response).exception = e; - response.sendToTarget(); - } - } - - /** - * Update an ADN-like record in EF by record index - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param adn is the new adn to be stored - * @param recordIndex is the 1-based adn record index - * @param pin2 is required to update EF_FDN, otherwise must be null - * @param response message to be posted when done - * response.exception hold the exception in error - */ - public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2, - Message response) { - - int extensionEF = extensionEfForEf(efid); - if (extensionEF < 0) { - sendErrorResponse(response, "EF is not known ADN-like EF:" + efid); - return; - } - - Message pendingResponse = userWriteResponse.get(efid); - if (pendingResponse != null) { - sendErrorResponse(response, "Have pending update for EF:" + efid); - return; - } - - userWriteResponse.put(efid, response); - - new AdnRecordLoader(mFh).updateEF(adn, efid, extensionEF, - recordIndex, pin2, - obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn)); - } - - /** - * Replace oldAdn with newAdn in ADN-like record in EF - * - * The ADN-like records must be read through requestLoadAllAdnLike() before - * - * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN - * @param oldAdn is the adn to be replaced - * If oldAdn.isEmpty() is ture, it insert the newAdn - * @param newAdn is the adn to be stored - * If newAdn.isEmpty() is true, it delete the oldAdn - * @param pin2 is required to update EF_FDN, otherwise must be null - * @param response message to be posted when done - * response.exception hold the exception in error - */ - public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn, - String pin2, Message response) { - - int extensionEF; - extensionEF = extensionEfForEf(efid); - - if (extensionEF < 0) { - sendErrorResponse(response, "EF is not known ADN-like EF:" + efid); - return; - } - - ArrayList oldAdnList; - - if (efid == EF_PBR) { - oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim(); - } else { - oldAdnList = getRecordsIfLoaded(efid); - } - - if (oldAdnList == null) { - sendErrorResponse(response, "Adn list not exist for EF:" + efid); - return; - } - - int index = -1; - int count = 1; - for (Iterator it = oldAdnList.iterator(); it.hasNext(); ) { - if (oldAdn.isEqual(it.next())) { - index = count; - break; - } - count++; - } - - if (index == -1) { - sendErrorResponse(response, "Adn record don't exist for " + oldAdn); - return; - } - - if (efid == EF_PBR) { - AdnRecord foundAdn = oldAdnList.get(index-1); - efid = foundAdn.efid; - extensionEF = foundAdn.extRecord; - index = foundAdn.recordNumber; - - newAdn.efid = efid; - newAdn.extRecord = extensionEF; - newAdn.recordNumber = index; - } - - Message pendingResponse = userWriteResponse.get(efid); - - if (pendingResponse != null) { - sendErrorResponse(response, "Have pending update for EF:" + efid); - return; - } - - userWriteResponse.put(efid, response); - - new AdnRecordLoader(mFh).updateEF(newAdn, efid, extensionEF, - index, pin2, - obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn)); - } - - - /** - * Responds with exception (in response) if efid is not a known ADN-like - * record - */ - public void - requestLoadAllAdnLike (int efid, int extensionEf, Message response) { - ArrayList waiters; - ArrayList result; - - if (efid == EF_PBR) { - result = mUsimPhoneBookManager.loadEfFilesFromUsim(); - } else { - result = getRecordsIfLoaded(efid); - } - - // Have we already loaded this efid? - if (result != null) { - if (response != null) { - AsyncResult.forMessage(response).result = result; - response.sendToTarget(); - } - - return; - } - - // Have we already *started* loading this efid? - - waiters = adnLikeWaiters.get(efid); - - if (waiters != null) { - // There's a pending request for this EF already - // just add ourselves to it - - waiters.add(response); - return; - } - - // Start loading efid - - waiters = new ArrayList(); - waiters.add(response); - - adnLikeWaiters.put(efid, waiters); - - - if (extensionEf < 0) { - // respond with error if not known ADN-like record - - if (response != null) { - AsyncResult.forMessage(response).exception - = new RuntimeException("EF is not known ADN-like EF:" + efid); - response.sendToTarget(); - } - - return; - } - - new AdnRecordLoader(mFh).loadAllFromEF(efid, extensionEf, - obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0)); - } - - //***** Private methods - - private void - notifyWaiters(ArrayList waiters, AsyncResult ar) { - - if (waiters == null) { - return; - } - - for (int i = 0, s = waiters.size() ; i < s ; i++) { - Message waiter = waiters.get(i); - - AsyncResult.forMessage(waiter, ar.result, ar.exception); - waiter.sendToTarget(); - } - } - - //***** Overridden from Handler - - public void - handleMessage(Message msg) { - AsyncResult ar; - int efid; - - switch(msg.what) { - case EVENT_LOAD_ALL_ADN_LIKE_DONE: - /* arg1 is efid, obj.result is ArrayList*/ - ar = (AsyncResult) msg.obj; - efid = msg.arg1; - ArrayList waiters; - - waiters = adnLikeWaiters.get(efid); - adnLikeWaiters.delete(efid); - - if (ar.exception == null) { - adnLikeFiles.put(efid, (ArrayList) ar.result); - } - notifyWaiters(waiters, ar); - break; - case EVENT_UPDATE_ADN_DONE: - ar = (AsyncResult)msg.obj; - efid = msg.arg1; - int index = msg.arg2; - AdnRecord adn = (AdnRecord) (ar.userObj); - - if (ar.exception == null) { - adnLikeFiles.get(efid).set(index - 1, adn); - mUsimPhoneBookManager.invalidateCache(); - } - - Message response = userWriteResponse.get(efid); - userWriteResponse.delete(efid); - - AsyncResult.forMessage(response, null, ar.exception); - response.sendToTarget(); - break; - } - - } - - -} diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java deleted file mode 100644 index 084fae6067f8..000000000000 --- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java +++ /dev/null @@ -1,284 +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; - -import java.util.ArrayList; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - - -public class AdnRecordLoader extends Handler { - final static String LOG_TAG = "RIL_AdnRecordLoader"; - - //***** Instance Variables - - private IccFileHandler mFh; - int ef; - int extensionEF; - int pendingExtLoads; - Message userResponse; - String pin2; - - // For "load one" - int recordNumber; - - // for "load all" - ArrayList adns; // only valid after EVENT_ADN_LOAD_ALL_DONE - - // Either an AdnRecord or a reference to adns depending - // if this is a load one or load all operation - Object result; - - //***** Event Constants - - static final int EVENT_ADN_LOAD_DONE = 1; - static final int EVENT_EXT_RECORD_LOAD_DONE = 2; - static final int EVENT_ADN_LOAD_ALL_DONE = 3; - static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4; - static final int EVENT_UPDATE_RECORD_DONE = 5; - - //***** Constructor - - public AdnRecordLoader(IccFileHandler fh) { - // The telephony unit-test cases may create AdnRecords - // in secondary threads - super(Looper.getMainLooper()); - mFh = fh; - } - - /** - * Resulting AdnRecord is placed in response.obj.result - * or response.obj.exception is set - */ - public void - loadFromEF(int ef, int extensionEF, int recordNumber, - Message response) { - this.ef = ef; - this.extensionEF = extensionEF; - this.recordNumber = recordNumber; - this.userResponse = response; - - mFh.loadEFLinearFixed( - ef, recordNumber, - obtainMessage(EVENT_ADN_LOAD_DONE)); - - } - - - /** - * Resulting ArrayList<adnRecord> is placed in response.obj.result - * or response.obj.exception is set - */ - public void - loadAllFromEF(int ef, int extensionEF, - Message response) { - this.ef = ef; - this.extensionEF = extensionEF; - this.userResponse = response; - - mFh.loadEFLinearFixedAll( - ef, - obtainMessage(EVENT_ADN_LOAD_ALL_DONE)); - - } - - /** - * Write adn to a EF SIM record - * It will get the record size of EF record and compose hex adn array - * then write the hex array to EF record - * - * @param adn is set with alphaTag and phone number - * @param ef EF fileid - * @param extensionEF extension EF fileid - * @param recordNumber 1-based record index - * @param pin2 for CHV2 operations, must be null if pin2 is not needed - * @param response will be sent to its handler when completed - */ - public void - updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber, - String pin2, Message response) { - this.ef = ef; - this.extensionEF = extensionEF; - this.recordNumber = recordNumber; - this.userResponse = response; - this.pin2 = pin2; - - mFh.getEFLinearRecordSize( ef, - obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn)); - } - - //***** Overridden from Handler - - public void - handleMessage(Message msg) { - AsyncResult ar; - byte data[]; - AdnRecord adn; - - try { - switch (msg.what) { - case EVENT_EF_LINEAR_RECORD_SIZE_DONE: - ar = (AsyncResult)(msg.obj); - adn = (AdnRecord)(ar.userObj); - - if (ar.exception != null) { - throw new RuntimeException("get EF record size failed", - ar.exception); - } - - int[] recordSize = (int[])ar.result; - // recordSize is int[3] array - // int[0] is the record length - // int[1] is the total length of the EF file - // int[2] is the number of records in the EF file - // So int[0] * int[2] = int[1] - if (recordSize.length != 3 || recordNumber > recordSize[2]) { - throw new RuntimeException("get wrong EF record size format", - ar.exception); - } - - data = adn.buildAdnString(recordSize[0]); - - if(data == null) { - throw new RuntimeException("wrong ADN format", - ar.exception); - } - - mFh.updateEFLinearFixed(ef, recordNumber, - data, pin2, obtainMessage(EVENT_UPDATE_RECORD_DONE)); - - pendingExtLoads = 1; - - break; - case EVENT_UPDATE_RECORD_DONE: - ar = (AsyncResult)(msg.obj); - if (ar.exception != null) { - throw new RuntimeException("update EF adn record failed", - ar.exception); - } - pendingExtLoads = 0; - result = null; - break; - 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" - + Integer.toHexString(ef) - + ":" + recordNumber - + "\n" + IccUtils.bytesToHexString(data)); - } - - adn = new AdnRecord(ef, recordNumber, data); - result = adn; - - if (adn.hasExtendedRecord()) { - // If we have a valid value in the ext record field, - // we're not done yet: we need to read the corresponding - // ext record and append it - - pendingExtLoads = 1; - - mFh.loadEFLinearFixed( - extensionEF, adn.extRecord, - obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn)); - } - break; - - case EVENT_EXT_RECORD_LOAD_DONE: - 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 extension EF: 0x" - + Integer.toHexString(extensionEF) - + ":" + adn.extRecord - + "\n" + IccUtils.bytesToHexString(data)); - - adn.appendExtRecord(data); - - pendingExtLoads--; - // result should have been set in - // EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE - break; - - case EVENT_ADN_LOAD_ALL_DONE: - ar = (AsyncResult)(msg.obj); - ArrayList datas = (ArrayList)(ar.result); - - if (ar.exception != null) { - throw new RuntimeException("load failed", ar.exception); - } - - adns = new ArrayList(datas.size()); - result = adns; - pendingExtLoads = 0; - - for(int i = 0, s = datas.size() ; i < s ; i++) { - adn = new AdnRecord(ef, 1 + i, datas.get(i)); - adns.add(adn); - - if (adn.hasExtendedRecord()) { - // If we have a valid value in the ext record field, - // we're not done yet: we need to read the corresponding - // ext record and append it - - pendingExtLoads++; - - mFh.loadEFLinearFixed( - extensionEF, adn.extRecord, - obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn)); - } - } - break; - } - } catch (RuntimeException exc) { - if (userResponse != null) { - AsyncResult.forMessage(userResponse) - .exception = exc; - userResponse.sendToTarget(); - // Loading is all or nothing--either every load succeeds - // or we fail the whole thing. - userResponse = null; - } - return; - } - - if (userResponse != null && pendingExtLoads == 0) { - AsyncResult.forMessage(userResponse).result - = result; - - userResponse.sendToTarget(); - userResponse = null; - } - } - - -} diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java deleted file mode 100644 index 3a3044e8a2fb..000000000000 --- a/telephony/java/com/android/internal/telephony/ApnContext.java +++ /dev/null @@ -1,228 +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; - -import android.util.Log; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Maintain the Apn context - */ -public class ApnContext { - - public final String LOG_TAG; - - protected static final boolean DBG = true; - - private final String mApnType; - - private DataConnectionTracker.State mState; - - private ArrayList mWaitingApns = null; - - /** A zero indicates that all waiting APNs had a permanent error */ - private AtomicInteger mWaitingApnsPermanentFailureCountDown; - - private ApnSetting mApnSetting; - - DataConnection mDataConnection; - - DataConnectionAc mDataConnectionAc; - - String mReason; - - /** - * user/app requested connection on this APN - */ - AtomicBoolean mDataEnabled; - - /** - * carrier requirements met - */ - AtomicBoolean mDependencyMet; - - public ApnContext(String apnType, String logTag) { - mApnType = apnType; - mState = DataConnectionTracker.State.IDLE; - setReason(Phone.REASON_DATA_ENABLED); - mDataEnabled = new AtomicBoolean(false); - mDependencyMet = new AtomicBoolean(true); - mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0); - LOG_TAG = logTag; - } - - public String getApnType() { - return mApnType; - } - - public synchronized DataConnection getDataConnection() { - return mDataConnection; - } - - public synchronized void setDataConnection(DataConnection dc) { - if (DBG) { - log("setDataConnection: old dc=" + mDataConnection + " new dc=" + dc + " this=" + this); - } - mDataConnection = dc; - } - - - public synchronized DataConnectionAc getDataConnectionAc() { - return mDataConnectionAc; - } - - public synchronized void setDataConnectionAc(DataConnectionAc dcac) { - if (DBG) { - log("setDataConnectionAc: old dcac=" + mDataConnectionAc + " new dcac=" + dcac); - } - if (dcac != null) { - dcac.addApnContextSync(this); - } else { - if (mDataConnectionAc != null) { - mDataConnectionAc.removeApnContextSync(this); - } - } - mDataConnectionAc = dcac; - } - - public synchronized ApnSetting getApnSetting() { - return mApnSetting; - } - - public synchronized void setApnSetting(ApnSetting apnSetting) { - mApnSetting = apnSetting; - } - - public synchronized void setWaitingApns(ArrayList waitingApns) { - mWaitingApns = waitingApns; - mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size()); - } - - public int getWaitingApnsPermFailCount() { - return mWaitingApnsPermanentFailureCountDown.get(); - } - - public void decWaitingApnsPermFailCount() { - mWaitingApnsPermanentFailureCountDown.decrementAndGet(); - } - - public synchronized ApnSetting getNextWaitingApn() { - ArrayList list = mWaitingApns; - ApnSetting apn = null; - - if (list != null) { - if (!list.isEmpty()) { - apn = list.get(0); - } - } - return apn; - } - - public synchronized void removeWaitingApn(ApnSetting apn) { - if (mWaitingApns != null) { - mWaitingApns.remove(apn); - } - } - - public synchronized ArrayList getWaitingApns() { - return mWaitingApns; - } - - public synchronized void setState(DataConnectionTracker.State s) { - if (DBG) { - log("setState: " + s + ", previous state:" + mState); - } - - mState = s; - - if (mState == DataConnectionTracker.State.FAILED) { - if (mWaitingApns != null) { - mWaitingApns.clear(); // when teardown the connection and set to IDLE - } - } - } - - public synchronized DataConnectionTracker.State getState() { - return mState; - } - - public boolean isDisconnected() { - DataConnectionTracker.State currentState = getState(); - return ((currentState == DataConnectionTracker.State.IDLE) || - currentState == DataConnectionTracker.State.FAILED); - } - - public synchronized void setReason(String reason) { - if (DBG) { - log("set reason as " + reason + ",current state " + mState); - } - mReason = reason; - } - - public synchronized String getReason() { - return mReason; - } - - public boolean isReady() { - return mDataEnabled.get() && mDependencyMet.get(); - } - - public void setEnabled(boolean enabled) { - if (DBG) { - log("set enabled as " + enabled + ", current state is " + mDataEnabled.get()); - } - mDataEnabled.set(enabled); - } - - public boolean isEnabled() { - return mDataEnabled.get(); - } - - public void setDependencyMet(boolean met) { - if (DBG) { - log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get()); - } - mDependencyMet.set(met); - } - - public boolean getDependencyMet() { - return mDependencyMet.get(); - } - - @Override - public String toString() { - // We don't print mDataConnection because its recursive. - return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns=" + mWaitingApns + - " mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown + - " mApnSetting=" + mApnSetting + " mDataConnectionAc=" + mDataConnectionAc + - " mReason=" + mReason + " mDataEnabled=" + mDataEnabled + - " mDependencyMet=" + mDependencyMet + "}"; - } - - protected void log(String s) { - Log.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s); - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("ApnContext: " + this.toString()); - } -} diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java deleted file mode 100755 index ad69fdb36b77..000000000000 --- a/telephony/java/com/android/internal/telephony/ApnSetting.java +++ /dev/null @@ -1,200 +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; - -/** - * This class represents a apn setting for create PDP link - */ -public class ApnSetting { - - static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; - - public final String carrier; - public final String apn; - public final String proxy; - public final String port; - public final String mmsc; - public final String mmsProxy; - public final String mmsPort; - public final String user; - public final String password; - public final int authType; - public final String[] types; - public final int id; - public final String numeric; - public final String protocol; - public final String roamingProtocol; - /** - * Current status of APN - * true : enabled APN, false : disabled APN. - */ - public final boolean carrierEnabled; - /** - * Radio Access Technology info - * To check what values can hold, refer to ServiceState.java. - * This should be spread to other technologies, - * but currently only used for LTE(14) and EHRPD(13). - */ - public final int bearer; - - public ApnSetting(int id, String numeric, String carrier, String apn, - String proxy, String port, - String mmsc, String mmsProxy, String mmsPort, - String user, String password, int authType, String[] types, - String protocol, String roamingProtocol, boolean carrierEnabled, int bearer) { - this.id = id; - this.numeric = numeric; - this.carrier = carrier; - this.apn = apn; - this.proxy = proxy; - this.port = port; - this.mmsc = mmsc; - this.mmsProxy = mmsProxy; - this.mmsPort = mmsPort; - this.user = user; - this.password = password; - this.authType = authType; - this.types = types; - this.protocol = protocol; - this.roamingProtocol = roamingProtocol; - this.carrierEnabled = carrierEnabled; - this.bearer = bearer; - } - - /** - * Creates an ApnSetting object from a string. - * - * @param data the string to read. - * - * The string must be in one of two formats (newlines added for clarity, - * spaces are optional): - * - * v1 format: - * , , , , , , - * , , , , ,, - * [, ...] - * - * v2 format: - * [ApnSettingV2] , , , , , , - * , , , , , , - * [| ...], , , , - * - * Note that the strings generated by toString() do not contain the username - * and password and thus cannot be read by this method. - * - * @see ApnSettingTest - */ - public static ApnSetting fromString(String data) { - if (data == null) return null; - - int version; - // matches() operates on the whole string, so append .* to the regex. - if (data.matches(V2_FORMAT_REGEX + ".*")) { - version = 2; - data = data.replaceFirst(V2_FORMAT_REGEX, ""); - } else { - version = 1; - } - - String[] a = data.split("\\s*,\\s*"); - if (a.length < 14) { - return null; - } - - int authType; - try { - authType = Integer.parseInt(a[12]); - } catch (Exception e) { - authType = 0; - } - - String[] typeArray; - String protocol, roamingProtocol; - boolean carrierEnabled; - int bearer; - if (version == 1) { - typeArray = new String[a.length - 13]; - System.arraycopy(a, 13, typeArray, 0, a.length - 13); - protocol = RILConstants.SETUP_DATA_PROTOCOL_IP; - roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP; - carrierEnabled = true; - bearer = 0; - } else { - if (a.length < 18) { - return null; - } - typeArray = a[13].split("\\s*\\|\\s*"); - protocol = a[14]; - roamingProtocol = a[15]; - try { - carrierEnabled = Boolean.parseBoolean(a[16]); - } catch (Exception e) { - carrierEnabled = true; - } - bearer = Integer.parseInt(a[17]); - } - - return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8], - a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol,carrierEnabled,bearer); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[ApnSettingV2] ") - .append(carrier) - .append(", ").append(id) - .append(", ").append(numeric) - .append(", ").append(apn) - .append(", ").append(proxy) - .append(", ").append(mmsc) - .append(", ").append(mmsProxy) - .append(", ").append(mmsPort) - .append(", ").append(port) - .append(", ").append(authType).append(", "); - for (int i = 0; i < types.length; i++) { - sb.append(types[i]); - if (i < types.length - 1) { - sb.append(" | "); - } - } - sb.append(", ").append(protocol); - sb.append(", ").append(roamingProtocol); - sb.append(", ").append(carrierEnabled); - sb.append(", ").append(bearer); - return sb.toString(); - } - - public boolean canHandleType(String type) { - for (String t : types) { - // DEFAULT handles all, and HIPRI is handled by DEFAULT - if (t.equalsIgnoreCase(type) || - t.equalsIgnoreCase(Phone.APN_TYPE_ALL) || - (t.equalsIgnoreCase(Phone.APN_TYPE_DEFAULT) && - type.equalsIgnoreCase(Phone.APN_TYPE_HIPRI))) { - return true; - } - } - return false; - } - - // TODO - if we have this function we should also have hashCode. - // Also should handle changes in type order and perhaps case-insensitivity - public boolean equals(Object o) { - if (o instanceof ApnSetting == false) return false; - return (this.toString().equals(o.toString())); - } -} diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java deleted file mode 100644 index 35cdf9bdfb99..000000000000 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ /dev/null @@ -1,721 +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; - - -import android.content.Context; -import android.os.RegistrantList; -import android.os.Registrant; -import android.os.Handler; -import android.os.AsyncResult; -import android.os.SystemProperties; -import android.util.Log; - -import java.io.FileInputStream; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * {@hide} - */ -public abstract class BaseCommands implements CommandsInterface { - static final String LOG_TAG = "RILB"; - - //***** Instance Variables - protected Context mContext; - protected RadioState mState = RadioState.RADIO_UNAVAILABLE; - protected Object mStateMonitor = new Object(); - - protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList(); - protected RegistrantList mOnRegistrants = new RegistrantList(); - protected RegistrantList mAvailRegistrants = new RegistrantList(); - protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList(); - protected RegistrantList mNotAvailRegistrants = new RegistrantList(); - protected RegistrantList mCallStateRegistrants = new RegistrantList(); - protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList(); - protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList(); - protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList(); - protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList(); - protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList(); - protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList(); - protected Registrant mUnsolOemHookRawRegistrant; - protected RegistrantList mOtaProvisionRegistrants = new RegistrantList(); - protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList(); - protected RegistrantList mDisplayInfoRegistrants = new RegistrantList(); - protected RegistrantList mSignalInfoRegistrants = new RegistrantList(); - protected RegistrantList mNumberInfoRegistrants = new RegistrantList(); - protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList(); - protected RegistrantList mLineControlInfoRegistrants = new RegistrantList(); - protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList(); - protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList(); - protected RegistrantList mRingbackToneRegistrants = new RegistrantList(); - protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList(); - protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList(); - protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList(); - protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList(); - protected RegistrantList mRilConnectedRegistrants = new RegistrantList(); - protected RegistrantList mIccRefreshRegistrants = new RegistrantList(); - - protected Registrant mGsmSmsRegistrant; - protected Registrant mCdmaSmsRegistrant; - protected Registrant mNITZTimeRegistrant; - protected Registrant mSignalStrengthRegistrant; - protected Registrant mUSSDRegistrant; - protected Registrant mSmsOnSimRegistrant; - protected Registrant mSmsStatusRegistrant; - protected Registrant mSsnRegistrant; - protected Registrant mCatSessionEndRegistrant; - protected Registrant mCatProCmdRegistrant; - protected Registrant mCatEventRegistrant; - protected Registrant mCatCallSetUpRegistrant; - protected Registrant mIccSmsFullRegistrant; - protected Registrant mEmergencyCallbackModeRegistrant; - protected Registrant mRingRegistrant; - protected Registrant mRestrictedStateRegistrant; - protected Registrant mGsmBroadcastSmsRegistrant; - - // Preferred network type received from PhoneFactory. - // This is used when establishing a connection to the - // vendor ril so it starts up in the correct mode. - protected int mPreferredNetworkType; - // CDMA subscription received from PhoneFactory - protected int mCdmaSubscription; - // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone. - protected int mPhoneType; - // RIL Version - protected int mRilVersion = -1; - - public BaseCommands(Context context) { - mContext = context; // May be null (if so we won't log statistics) - } - - //***** CommandsInterface implementation - - public RadioState getRadioState() { - return mState; - } - - public void registerForRadioStateChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mRadioStateChangedRegistrants.add(r); - r.notifyRegistrant(); - } - } - - 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) { - mOnRegistrants.add(r); - - if (mState.isOn()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - public void unregisterForOn(Handler h) { - synchronized (mStateMonitor) { - mOnRegistrants.remove(h); - } - } - - - public void registerForAvailable(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mAvailRegistrants.add(r); - - if (mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - 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) { - mNotAvailRegistrants.add(r); - - if (!mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - 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) { - mOffOrNotAvailRegistrants.add(r); - - if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - public void unregisterForOffOrNotAvailable(Handler h) { - synchronized(mStateMonitor) { - mOffOrNotAvailRegistrants.remove(h); - } - } - - public void registerForCallStateChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mCallStateRegistrants.add(r); - } - - public void unregisterForCallStateChanged(Handler h) { - mCallStateRegistrants.remove(h); - } - - public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mVoiceNetworkStateRegistrants.add(r); - } - - public void unregisterForVoiceNetworkStateChanged(Handler h) { - mVoiceNetworkStateRegistrants.remove(h); - } - - public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mDataNetworkStateRegistrants.add(r); - } - - public void unregisterForDataNetworkStateChanged(Handler h) { - mDataNetworkStateRegistrants.remove(h); - } - - public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mVoiceRadioTechChangedRegistrants.add(r); - } - - public void unregisterForVoiceRadioTechChanged(Handler h) { - mVoiceRadioTechChangedRegistrants.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 setOnNewGsmSms(Handler h, int what, Object obj) { - mGsmSmsRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnNewGsmSms(Handler h) { - mGsmSmsRegistrant.clear(); - } - - public void setOnNewCdmaSms(Handler h, int what, Object obj) { - mCdmaSmsRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnNewCdmaSms(Handler h) { - mCdmaSmsRegistrant.clear(); - } - - public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) { - mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnNewGsmBroadcastSms(Handler h) { - mGsmBroadcastSmsRegistrant.clear(); - } - - public void setOnSmsOnSim(Handler h, int what, Object obj) { - mSmsOnSimRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnSmsOnSim(Handler h) { - mSmsOnSimRegistrant.clear(); - } - - public void setOnSmsStatus(Handler h, int what, Object obj) { - mSmsStatusRegistrant = new Registrant (h, what, 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 unSetOnSignalStrengthUpdate(Handler h) { - mSignalStrengthRegistrant.clear(); - } - - public void setOnNITZTime(Handler h, int what, Object obj) { - mNITZTimeRegistrant = new Registrant (h, what, 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 unSetOnUSSD(Handler h) { - mUSSDRegistrant.clear(); - } - - public void setOnSuppServiceNotification(Handler h, int what, Object obj) { - mSsnRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnSuppServiceNotification(Handler h) { - mSsnRegistrant.clear(); - } - - public void setOnCatSessionEnd(Handler h, int what, Object obj) { - mCatSessionEndRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnCatSessionEnd(Handler h) { - mCatSessionEndRegistrant.clear(); - } - - public void setOnCatProactiveCmd(Handler h, int what, Object obj) { - mCatProCmdRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnCatProactiveCmd(Handler h) { - mCatProCmdRegistrant.clear(); - } - - public void setOnCatEvent(Handler h, int what, Object obj) { - mCatEventRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnCatEvent(Handler h) { - mCatEventRegistrant.clear(); - } - - public void setOnCatCallSetUp(Handler h, int what, Object obj) { - mCatCallSetUpRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnCatCallSetUp(Handler h) { - mCatCallSetUpRegistrant.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 registerForIccRefresh(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mIccRefreshRegistrants.add(r); - } - public void setOnIccRefresh(Handler h, int what, Object obj) { - registerForIccRefresh(h, what, obj); - } - - public void setEmergencyCallbackMode(Handler h, int what, Object obj) { - mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj); - } - - public void unregisterForIccRefresh(Handler h) { - mIccRefreshRegistrants.remove(h); - } - public void unsetOnIccRefresh(Handler h) { - unregisterForIccRefresh(h); - } - - 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); - } - - public void setOnRestrictedStateChanged(Handler h, int what, Object obj) { - mRestrictedStateRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnRestrictedStateChanged(Handler h) { - mRestrictedStateRegistrant.clear(); - } - - public void registerForDisplayInfo(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mDisplayInfoRegistrants.add(r); - } - - public void unregisterForDisplayInfo(Handler h) { - mDisplayInfoRegistrants.remove(h); - } - - public void registerForCallWaitingInfo(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mCallWaitingInfoRegistrants.add(r); - } - - public void unregisterForCallWaitingInfo(Handler h) { - mCallWaitingInfoRegistrants.remove(h); - } - - public void registerForSignalInfo(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mSignalInfoRegistrants.add(r); - } - - public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) { - mUnsolOemHookRawRegistrant = new Registrant (h, what, obj); - } - - public void unSetOnUnsolOemHookRaw(Handler h) { - mUnsolOemHookRawRegistrant.clear(); - } - - public void unregisterForSignalInfo(Handler h) { - mSignalInfoRegistrants.remove(h); - } - - public void registerForCdmaOtaProvision(Handler h,int what, Object obj){ - Registrant r = new Registrant (h, what, obj); - mOtaProvisionRegistrants.add(r); - } - - public void unregisterForCdmaOtaProvision(Handler h){ - mOtaProvisionRegistrants.remove(h); - } - - public void registerForNumberInfo(Handler h,int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mNumberInfoRegistrants.add(r); - } - - public void unregisterForNumberInfo(Handler h){ - mNumberInfoRegistrants.remove(h); - } - - public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mRedirNumInfoRegistrants.add(r); - } - - public void unregisterForRedirectedNumberInfo(Handler h) { - mRedirNumInfoRegistrants.remove(h); - } - - public void registerForLineControlInfo(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mLineControlInfoRegistrants.add(r); - } - - public void unregisterForLineControlInfo(Handler h) { - mLineControlInfoRegistrants.remove(h); - } - - public void registerFoT53ClirlInfo(Handler h,int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mT53ClirInfoRegistrants.add(r); - } - - public void unregisterForT53ClirInfo(Handler h) { - mT53ClirInfoRegistrants.remove(h); - } - - public void registerForT53AudioControlInfo(Handler h,int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mT53AudCntrlInfoRegistrants.add(r); - } - - public void unregisterForT53AudioControlInfo(Handler h) { - mT53AudCntrlInfoRegistrants.remove(h); - } - - public void registerForRingbackTone(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mRingbackToneRegistrants.add(r); - } - - public void unregisterForRingbackTone(Handler h) { - mRingbackToneRegistrants.remove(h); - } - - public void registerForResendIncallMute(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mResendIncallMuteRegistrants.add(r); - } - - public void unregisterForResendIncallMute(Handler h) { - mResendIncallMuteRegistrants.remove(h); - } - - @Override - public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mCdmaSubscriptionChangedRegistrants.add(r); - } - - @Override - public void unregisterForCdmaSubscriptionChanged(Handler h) { - mCdmaSubscriptionChangedRegistrants.remove(h); - } - - @Override - public void registerForCdmaPrlChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mCdmaPrlChangedRegistrants.add(r); - } - - @Override - public void unregisterForCdmaPrlChanged(Handler h) { - mCdmaPrlChangedRegistrants.remove(h); - } - - @Override - public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mExitEmergencyCallbackModeRegistrants.add(r); - } - - @Override - public void unregisterForExitEmergencyCallbackMode(Handler h) { - mExitEmergencyCallbackModeRegistrants.remove(h); - } - - /** - * {@inheritDoc} - */ - @Override - public void registerForRilConnected(Handler h, int what, Object obj) { - Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what); - Registrant r = new Registrant (h, what, obj); - mRilConnectedRegistrants.add(r); - if (mRilVersion != -1) { - Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion); - r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null)); - } - } - - @Override - public void unregisterForRilConnected(Handler h) { - mRilConnectedRegistrants.remove(h); - } - - /** - * {@inheritDoc} - */ - @Override - public void setCurrentPreferredNetworkType() { - } - - //***** Protected Methods - /** - * Store new RadioState and send notification based on the changes - * - * This function is called only by RIL.java when receiving unsolicited - * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED - * - * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON. - * - * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED - */ - protected void setRadioState(RadioState newState) { - RadioState oldState; - - synchronized (mStateMonitor) { - if (false) { - Log.v(LOG_TAG, "setRadioState old: " + mState - + " new " + newState); - } - - oldState = mState; - mState = newState; - - if (oldState == mState) { - // no state transition - return; - } - - mRadioStateChangedRegistrants.notifyRegistrants(); - - if (mState.isAvailable() && !oldState.isAvailable()) { - Log.d(LOG_TAG,"Notifying: radio available"); - mAvailRegistrants.notifyRegistrants(); - onRadioAvailable(); - } - - if (!mState.isAvailable() && oldState.isAvailable()) { - Log.d(LOG_TAG,"Notifying: radio not available"); - mNotAvailRegistrants.notifyRegistrants(); - } - - if (mState.isOn() && !oldState.isOn()) { - Log.d(LOG_TAG,"Notifying: Radio On"); - mOnRegistrants.notifyRegistrants(); - } - - if ((!mState.isOn() || !mState.isAvailable()) - && !((!oldState.isOn() || !oldState.isAvailable())) - ) { - Log.d(LOG_TAG,"Notifying: radio off or not available"); - mOffOrNotAvailRegistrants.notifyRegistrants(); - } - } - } - - protected void onRadioAvailable() { - } - - /** - * The contents of the /proc/cmdline file - */ - private static String getProcCmdLine() - { - String cmdline = ""; - FileInputStream is = null; - try { - is = new FileInputStream("/proc/cmdline"); - byte [] buffer = new byte[2048]; - int count = is.read(buffer); - if (count > 0) { - cmdline = new String(buffer, 0, count); - } - } catch (IOException e) { - Log.d(LOG_TAG, "No /proc/cmdline exception=" + e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - } - } - } - Log.d(LOG_TAG, "/proc/cmdline=" + cmdline); - return cmdline; - } - - /** - * {@inheritDoc} - */ - @Override - public int getLteOnCdmaMode() { - return getLteOnCdmaModeStatic(); - } - - /** Kernel command line */ - private static final String sKernelCmdLine = getProcCmdLine(); - - /** Pattern for selecting the product type from the kernel command line */ - private static final Pattern sProductTypePattern = - Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)"); - - /** The ProductType used for LTE on CDMA devices */ - private static final String sLteOnCdmaProductType = - SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, ""); - - /** - * Return if the current radio is LTE on CDMA. This - * is a tri-state return value as for a period of time - * the mode may be unknown. - * - * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} - * or {@link Phone#LTE_ON_CDMA_TRUE} - */ - public static int getLteOnCdmaModeStatic() { - int retVal; - int curVal; - String productType = ""; - - curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE, - Phone.LTE_ON_CDMA_UNKNOWN); - retVal = curVal; - if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) { - Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine); - if (matcher.find()) { - productType = matcher.group(1); - if (sLteOnCdmaProductType.equals(productType)) { - retVal = Phone.LTE_ON_CDMA_TRUE; - } else { - retVal = Phone.LTE_ON_CDMA_FALSE; - } - } else { - retVal = Phone.LTE_ON_CDMA_FALSE; - } - } - - Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal + - " product_type='" + productType + - "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'"); - return retVal; - } - - @Override - public void testingEmergencyCall() {} -} diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java deleted file mode 100644 index 4967ab81e5fc..000000000000 --- a/telephony/java/com/android/internal/telephony/Call.java +++ /dev/null @@ -1,255 +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; - -import java.util.List; - -import android.util.Log; - -/** - * {@hide} - */ -public abstract class Call { - /* Enums */ - - public enum State { - IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING; - - public boolean isAlive() { - return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING); - } - - public boolean isRinging() { - return this == INCOMING || this == WAITING; - } - - public boolean isDialing() { - return this == DIALING || this == ALERTING; - } - } - - - /* Instance Variables */ - - public State state = State.IDLE; - - - // Flag to indicate if the current calling/caller information - // is accurate. If false the information is known to be accurate. - // - // For CDMA, during call waiting/3 way, there is no network response - // if call waiting is answered, network timed out, dropped, 3 way - // merged, etc. - protected boolean isGeneric = false; - - protected final String LOG_TAG = "Call"; - - /* Instance Methods */ - - /** Do not modify the List result!!! This list is not yours to keep - * It will change across event loop iterations top - */ - - public abstract List getConnections(); - public abstract Phone getPhone(); - public abstract boolean isMultiparty(); - public abstract void hangup() throws CallStateException; - - - /** - * 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 - */ - public State getState() { - return state; - } - - /** - * isIdle - * - * FIXME rename - * @return true if the call contains only disconnected connections (if any) - */ - public boolean isIdle() { - return !getState().isAlive(); - } - - /** - * Returns the Connection associated with this Call that was created - * first, or null if there are no Connections in this Call - */ - public Connection - getEarliestConnection() { - List l; - 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; - time = t; - } - } - - return earliest; - } - - public long - getEarliestCreateTime() { - List l; - long time = Long.MAX_VALUE; - - l = getConnections(); - - if (l.size() == 0) { - return 0; - } - - for (int i = 0, s = l.size() ; i < s ; i++) { - Connection c = (Connection) l.get(i); - long t; - - t = c.getCreateTime(); - - time = t < time ? t : time; - } - - return time; - } - - public long - getEarliestConnectTime() { - long time = Long.MAX_VALUE; - List l = getConnections(); - - if (l.size() == 0) { - return 0; - } - - for (int i = 0, s = l.size() ; i < s ; i++) { - Connection c = (Connection) l.get(i); - long t; - - t = c.getConnectTime(); - - time = t < time ? t : time; - } - - return time; - } - - - public boolean - isDialingOrAlerting() { - return getState().isDialing(); - } - - public boolean - isRinging() { - return getState().isRinging(); - } - - /** - * Returns the Connection associated with this Call that was created - * last, or null if there are no Connections in this Call - */ - public Connection - getLatestConnection() { - List l = getConnections(); - if (l.size() == 0) { - return null; - } - - long time = 0; - Connection latest = null; - for (int i = 0, s = l.size() ; i < s ; i++) { - Connection c = (Connection) l.get(i); - long t = c.getCreateTime(); - - if (t > time) { - latest = c; - time = t; - } - } - - return latest; - } - - /** - * To indicate if the connection information is accurate - * or not. false means accurate. Only used for CDMA. - */ - public boolean isGeneric() { - return isGeneric; - } - - /** - * Set the generic instance variable - */ - public void setGeneric(boolean generic) { - isGeneric = generic; - } - - /** - * Hangup call if it is alive - */ - public void hangupIfAlive() { - if (getState().isAlive()) { - try { - hangup(); - } catch (CallStateException ex) { - Log.w(LOG_TAG, " hangupIfActive: caught " + ex); - } - } - } -} diff --git a/telephony/java/com/android/internal/telephony/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/CallForwardInfo.java deleted file mode 100644 index 8b853b0d124b..000000000000 --- a/telephony/java/com/android/internal/telephony/CallForwardInfo.java +++ /dev/null @@ -1,42 +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; - -import android.telephony.PhoneNumberUtils; - -/** - * See also RIL_CallForwardInfo in include/telephony/ril.h - * - * {@hide} - */ -public class CallForwardInfo { - public int status; /*1 = active, 0 = not active */ - public int reason; /* from TS 27.007 7.11 "reason" */ - public int serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */ - public int toa; /* "type" from TS 27.007 7.11 */ - public String number; /* "number" from TS 27.007 7.11 */ - public int timeSeconds; /* for CF no reply only */ - - public String toString() { - return super.toString() + (status == 0 ? " not active " : " active ") - + " reason: " + reason - + " serviceClass: " + serviceClass - + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" " - + timeSeconds + " seconds"; - - } -} diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java deleted file mode 100644 index f825f31dd005..000000000000 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ /dev/null @@ -1,1855 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import com.android.internal.telephony.sip.SipPhone; - -import android.content.Context; -import android.media.AudioManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.RegistrantList; -import android.os.Registrant; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - - - -/** - * @hide - * - * CallManager class provides an abstract layer for PhoneApp to access - * and control calls. It implements Phone interface. - * - * CallManager provides call and connection control as well as - * channel capability. - * - * There are three categories of APIs CallManager provided - * - * 1. Call control and operation, such as dial() and hangup() - * 2. Channel capabilities, such as CanConference() - * 3. Register notification - * - * - */ -public final class CallManager { - - private static final String LOG_TAG ="CallManager"; - private static final boolean DBG = true; - private static final boolean VDBG = false; - - private static final int EVENT_DISCONNECT = 100; - private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101; - private static final int EVENT_NEW_RINGING_CONNECTION = 102; - private static final int EVENT_UNKNOWN_CONNECTION = 103; - private static final int EVENT_INCOMING_RING = 104; - private static final int EVENT_RINGBACK_TONE = 105; - private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106; - private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107; - private static final int EVENT_CALL_WAITING = 108; - private static final int EVENT_DISPLAY_INFO = 109; - private static final int EVENT_SIGNAL_INFO = 110; - private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111; - private static final int EVENT_RESEND_INCALL_MUTE = 112; - private static final int EVENT_MMI_INITIATE = 113; - private static final int EVENT_MMI_COMPLETE = 114; - private static final int EVENT_ECM_TIMER_RESET = 115; - private static final int EVENT_SUBSCRIPTION_INFO_READY = 116; - private static final int EVENT_SUPP_SERVICE_FAILED = 117; - private static final int EVENT_SERVICE_STATE_CHANGED = 118; - private static final int EVENT_POST_DIAL_CHARACTER = 119; - - // Singleton instance - private static final CallManager INSTANCE = new CallManager(); - - // list of registered phones, which are PhoneBase objs - private final ArrayList mPhones; - - // list of supported ringing calls - private final ArrayList mRingingCalls; - - // list of supported background calls - private final ArrayList mBackgroundCalls; - - // list of supported foreground calls - private final ArrayList mForegroundCalls; - - // empty connection list - private final ArrayList emptyConnections = new ArrayList(); - - // default phone as the first phone registered, which is PhoneBase obj - private Phone mDefaultPhone; - - // state registrants - protected final RegistrantList mPreciseCallStateRegistrants - = new RegistrantList(); - - protected final RegistrantList mNewRingingConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mIncomingRingRegistrants - = new RegistrantList(); - - protected final RegistrantList mDisconnectRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiRegistrants - = new RegistrantList(); - - protected final RegistrantList mUnknownConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mRingbackToneRegistrants - = new RegistrantList(); - - protected final RegistrantList mInCallVoicePrivacyOnRegistrants - = new RegistrantList(); - - protected final RegistrantList mInCallVoicePrivacyOffRegistrants - = new RegistrantList(); - - protected final RegistrantList mCallWaitingRegistrants - = new RegistrantList(); - - protected final RegistrantList mDisplayInfoRegistrants - = new RegistrantList(); - - protected final RegistrantList mSignalInfoRegistrants - = new RegistrantList(); - - protected final RegistrantList mCdmaOtaStatusChangeRegistrants - = new RegistrantList(); - - protected final RegistrantList mResendIncallMuteRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiInitiateRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiCompleteRegistrants - = new RegistrantList(); - - protected final RegistrantList mEcmTimerResetRegistrants - = new RegistrantList(); - - protected final RegistrantList mSubscriptionInfoReadyRegistrants - = new RegistrantList(); - - protected final RegistrantList mSuppServiceFailedRegistrants - = new RegistrantList(); - - protected final RegistrantList mServiceStateChangedRegistrants - = new RegistrantList(); - - protected final RegistrantList mPostDialCharacterRegistrants - = new RegistrantList(); - - private CallManager() { - mPhones = new ArrayList(); - mRingingCalls = new ArrayList(); - mBackgroundCalls = new ArrayList(); - mForegroundCalls = new ArrayList(); - mDefaultPhone = null; - } - - /** - * get singleton instance of CallManager - * @return CallManager - */ - public static CallManager getInstance() { - return INSTANCE; - } - - /** - * Get the corresponding PhoneBase obj - * - * @param phone a Phone object - * @return the corresponding PhoneBase obj in Phone if Phone - * is a PhoneProxy obj - * or the Phone itself if Phone is not a PhoneProxy obj - */ - private static Phone getPhoneBase(Phone phone) { - if (phone instanceof PhoneProxy) { - return phone.getForegroundCall().getPhone(); - } - return phone; - } - - /** - * Check if two phones refer to the same PhoneBase obj - * - * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager - * - * Both PhoneBase and PhoneProxy implement Phone interface, so - * they have same phone APIs, such as dial(). The real implementation, for - * example in GSM, is in GSMPhone as extend from PhoneBase, so that - * foregroundCall.getPhone() returns GSMPhone obj. On the other hand, - * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class - * member of GSMPhone. - * - * So for phone returned by PhoneFacotry, which is used by PhoneApp, - * phone.getForegroundCall().getPhone() != phone - * but - * isSamePhone(phone, phone.getForegroundCall().getPhone()) == true - * - * @param p1 is the first Phone obj - * @param p2 is the second Phone obj - * @return true if p1 and p2 refer to the same phone - */ - public static boolean isSamePhone(Phone p1, Phone p2) { - return (getPhoneBase(p1) == getPhoneBase(p2)); - } - - /** - * Returns all the registered phone objects. - * @return all the registered phone objects. - */ - public List getAllPhones() { - return Collections.unmodifiableList(mPhones); - } - - /** - * Get current coarse-grained voice call state. - * If the Call Manager has an active call and call waiting occurs, - * then the phone state is RINGING not OFFHOOK - * - */ - public Phone.State getState() { - Phone.State s = Phone.State.IDLE; - - for (Phone phone : mPhones) { - if (phone.getState() == Phone.State.RINGING) { - s = Phone.State.RINGING; - } else if (phone.getState() == Phone.State.OFFHOOK) { - if (s == Phone.State.IDLE) s = Phone.State.OFFHOOK; - } - } - return s; - } - - /** - * @return the service state of CallManager, which represents the - * highest priority state of all the service states of phones - * - * The priority is defined as - * - * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF - * - */ - - public int getServiceState() { - int resultState = ServiceState.STATE_OUT_OF_SERVICE; - - for (Phone phone : mPhones) { - int serviceState = phone.getServiceState().getState(); - if (serviceState == ServiceState.STATE_IN_SERVICE) { - // IN_SERVICE has the highest priority - resultState = serviceState; - break; - } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { - // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF - // Note: EMERGENCY_ONLY is not in use at this moment - if ( resultState == ServiceState.STATE_EMERGENCY_ONLY || - resultState == ServiceState.STATE_POWER_OFF) { - resultState = serviceState; - } - } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) { - if (resultState == ServiceState.STATE_POWER_OFF) { - resultState = serviceState; - } - } - } - return resultState; - } - - /** - * Register phone to CallManager - * @param phone to be registered - * @return true if register successfully - */ - public boolean registerPhone(Phone phone) { - Phone basePhone = getPhoneBase(phone); - - if (basePhone != null && !mPhones.contains(basePhone)) { - - if (DBG) { - Log.d(LOG_TAG, "registerPhone(" + - phone.getPhoneName() + " " + phone + ")"); - } - - if (mPhones.isEmpty()) { - mDefaultPhone = basePhone; - } - mPhones.add(basePhone); - mRingingCalls.add(basePhone.getRingingCall()); - mBackgroundCalls.add(basePhone.getBackgroundCall()); - mForegroundCalls.add(basePhone.getForegroundCall()); - registerForPhoneStates(basePhone); - return true; - } - return false; - } - - /** - * unregister phone from CallManager - * @param phone to be unregistered - */ - public void unregisterPhone(Phone phone) { - Phone basePhone = getPhoneBase(phone); - - if (basePhone != null && mPhones.contains(basePhone)) { - - if (DBG) { - Log.d(LOG_TAG, "unregisterPhone(" + - phone.getPhoneName() + " " + phone + ")"); - } - - mPhones.remove(basePhone); - mRingingCalls.remove(basePhone.getRingingCall()); - mBackgroundCalls.remove(basePhone.getBackgroundCall()); - mForegroundCalls.remove(basePhone.getForegroundCall()); - unregisterForPhoneStates(basePhone); - if (basePhone == mDefaultPhone) { - if (mPhones.isEmpty()) { - mDefaultPhone = null; - } else { - mDefaultPhone = mPhones.get(0); - } - } - } - } - - /** - * return the default phone or null if no phone available - */ - public Phone getDefaultPhone() { - return mDefaultPhone; - } - - /** - * @return the phone associated with the foreground call - */ - public Phone getFgPhone() { - return getActiveFgCall().getPhone(); - } - - /** - * @return the phone associated with the background call - */ - public Phone getBgPhone() { - return getFirstActiveBgCall().getPhone(); - } - - /** - * @return the phone associated with the ringing call - */ - public Phone getRingingPhone() { - return getFirstActiveRingingCall().getPhone(); - } - - public void setAudioMode() { - Context context = getContext(); - if (context == null) return; - AudioManager audioManager = (AudioManager) - context.getSystemService(Context.AUDIO_SERVICE); - - // change the audio mode and request/abandon audio focus according to phone state, - // but only on audio mode transitions - switch (getState()) { - case RINGING: - if (audioManager.getMode() != AudioManager.MODE_RINGTONE) { - // only request audio focus if the ringtone is going to be heard - if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) { - if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING"); - audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); - } - audioManager.setMode(AudioManager.MODE_RINGTONE); - } - break; - case OFFHOOK: - Phone offhookPhone = getFgPhone(); - if (getActiveFgCallState() == Call.State.IDLE) { - // There is no active Fg calls, the OFFHOOK state - // is set by the Bg call. So set the phone to bgPhone. - offhookPhone = getBgPhone(); - } - - int newAudioMode = AudioManager.MODE_IN_CALL; - if (offhookPhone instanceof SipPhone) { - // enable IN_COMMUNICATION audio mode instead for sipPhone - newAudioMode = AudioManager.MODE_IN_COMMUNICATION; - } - if (audioManager.getMode() != newAudioMode) { - // request audio focus before setting the new mode - if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL"); - audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); - audioManager.setMode(newAudioMode); - } - break; - case IDLE: - if (audioManager.getMode() != AudioManager.MODE_NORMAL) { - audioManager.setMode(AudioManager.MODE_NORMAL); - if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus"); - // abandon audio focus after the mode has been set back to normal - audioManager.abandonAudioFocusForCall(); - } - break; - } - } - - private Context getContext() { - Phone defaultPhone = getDefaultPhone(); - return ((defaultPhone == null) ? null : defaultPhone.getContext()); - } - - private void registerForPhoneStates(Phone phone) { - // for common events supported by all phones - phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null); - phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null); - phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null); - phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null); - phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null); - phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null); - phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null); - phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null); - phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null); - phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null); - phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null); - phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null); - phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null); - phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null); - phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null); - - // for events supported only by GSM and CDMA phone - if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM || - phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null); - } - - // for events supported only by CDMA phone - if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){ - phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null); - phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null); - phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null); - phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null); - } - } - - private void unregisterForPhoneStates(Phone phone) { - // for common events supported by all phones - phone.unregisterForPreciseCallStateChanged(mHandler); - phone.unregisterForDisconnect(mHandler); - phone.unregisterForNewRingingConnection(mHandler); - phone.unregisterForUnknownConnection(mHandler); - phone.unregisterForIncomingRing(mHandler); - phone.unregisterForRingbackTone(mHandler); - phone.unregisterForInCallVoicePrivacyOn(mHandler); - phone.unregisterForInCallVoicePrivacyOff(mHandler); - phone.unregisterForDisplayInfo(mHandler); - phone.unregisterForSignalInfo(mHandler); - phone.unregisterForResendIncallMute(mHandler); - phone.unregisterForMmiInitiate(mHandler); - phone.unregisterForMmiComplete(mHandler); - phone.unregisterForSuppServiceFailed(mHandler); - phone.unregisterForServiceStateChanged(mHandler); - - // for events supported only by GSM and CDMA phone - if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM || - phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null); - } - - // for events supported only by CDMA phone - if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){ - phone.unregisterForCdmaOtaStatusChange(mHandler); - phone.unregisterForSubscriptionInfoReady(mHandler); - phone.unregisterForCallWaiting(mHandler); - phone.unregisterForEcmTimerReset(mHandler); - } - } - - /** - * Answers a ringing or waiting call. - * - * Active call, if any, go on hold. - * If active call can't be held, i.e., a background call of the same channel exists, - * the active call will be hang up. - * - * Answering occurs asynchronously, and final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException when call is not ringing or waiting - */ - public void acceptCall(Call ringingCall) throws CallStateException { - Phone ringingPhone = ringingCall.getPhone(); - - if (VDBG) { - Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if ( hasActiveFgCall() ) { - Phone activePhone = getActiveFgCall().getPhone(); - boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle()); - boolean sameChannel = (activePhone == ringingPhone); - - if (VDBG) { - Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel); - } - - if (sameChannel && hasBgCall) { - getActiveFgCall().hangup(); - } else if (!sameChannel && !hasBgCall) { - activePhone.switchHoldingAndActive(); - } else if (!sameChannel && hasBgCall) { - getActiveFgCall().hangup(); - } - } - - ringingPhone.acceptCall(); - - if (VDBG) { - Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * Reject (ignore) a ringing call. In GSM, this means UDUB - * (User Determined User Busy). Reject occurs asynchronously, - * and final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException when no call is ringing or waiting - */ - public void rejectCall(Call ringingCall) throws CallStateException { - if (VDBG) { - Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - Phone ringingPhone = ringingCall.getPhone(); - - ringingPhone.rejectCall(); - - if (VDBG) { - Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * Places active call on hold, and makes held call active. - * Switch occurs asynchronously and may fail. - * - * There are 4 scenarios - * 1. only active call but no held call, aka, hold - * 2. no active call but only held call, aka, unhold - * 3. both active and held calls from same phone, aka, swap - * 4. active and held calls from different phones, aka, phone swap - * - * Final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if active call is ringing, waiting, or - * dialing/alerting, or heldCall can't be active. - * In these cases, this operation may not be performed. - */ - public void switchHoldingAndActive(Call heldCall) throws CallStateException { - Phone activePhone = null; - Phone heldPhone = null; - - if (VDBG) { - Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - activePhone = getActiveFgCall().getPhone(); - } - - if (heldCall != null) { - heldPhone = heldCall.getPhone(); - } - - if (activePhone != null) { - activePhone.switchHoldingAndActive(); - } - - if (heldPhone != null && heldPhone != activePhone) { - heldPhone.switchHoldingAndActive(); - } - - if (VDBG) { - Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * Hangup foreground call and resume the specific background call - * - * Note: this is noop if there is no foreground call or the heldCall is null - * - * @param heldCall to become foreground - * @throws CallStateException - */ - public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException { - Phone foregroundPhone = null; - Phone backgroundPhone = null; - - if (VDBG) { - Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - foregroundPhone = getFgPhone(); - if (heldCall != null) { - backgroundPhone = heldCall.getPhone(); - if (foregroundPhone == backgroundPhone) { - getActiveFgCall().hangup(); - } else { - // the call to be hangup and resumed belongs to different phones - getActiveFgCall().hangup(); - switchHoldingAndActive(heldCall); - } - } - } - - if (VDBG) { - Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * 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. - */ - public boolean canConference(Call heldCall) { - Phone activePhone = null; - Phone heldPhone = null; - - if (hasActiveFgCall()) { - activePhone = getActiveFgCall().getPhone(); - } - - if (heldCall != null) { - heldPhone = heldCall.getPhone(); - } - - return heldPhone.getClass().equals(activePhone.getClass()); - } - - /** - * Conferences holding and active. Conference occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if canConference() would return false. - * In these cases, this operation may not be performed. - */ - public void conference(Call heldCall) throws CallStateException { - - if (VDBG) { - Log.d(LOG_TAG, "conference(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - - Phone fgPhone = getFgPhone(); - if (fgPhone instanceof SipPhone) { - ((SipPhone) fgPhone).conference(heldCall); - } else if (canConference(heldCall)) { - fgPhone.conference(); - } else { - throw(new CallStateException("Can't conference foreground and selected background call")); - } - - if (VDBG) { - Log.d(LOG_TAG, "End conference(" +heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - } - - /** - * 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 - * handled asynchronously. - */ - public Connection dial(Phone phone, String dialString) throws CallStateException { - Phone basePhone = getPhoneBase(phone); - Connection result; - - if (VDBG) { - Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (!canDial(phone)) { - throw new CallStateException("cannot dial in current state"); - } - - if ( hasActiveFgCall() ) { - Phone activePhone = getActiveFgCall().getPhone(); - boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle()); - - if (DBG) { - Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone)); - } - - if (activePhone != basePhone) { - if (hasBgCall) { - Log.d(LOG_TAG, "Hangup"); - getActiveFgCall().hangup(); - } else { - Log.d(LOG_TAG, "Switch"); - activePhone.switchHoldingAndActive(); - } - } - } - - result = basePhone.dial(dialString); - - if (VDBG) { - Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")"); - Log.d(LOG_TAG, this.toString()); - } - - return result; - } - - /** - * 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 - * handled asynchronously. - */ - public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException { - return phone.dial(dialString, uusInfo); - } - - /** - * clear disconnect connection for each phone - */ - public void clearDisconnected() { - for(Phone phone : mPhones) { - phone.clearDisconnected(); - } - } - - /** - * Phone can make a call only if ALL of the following are true: - * - Phone is not powered off - * - There's no incoming or waiting call - * - There's available call slot in either foreground or background - * - The foreground call is ACTIVE or IDLE or DISCONNECTED. - * (We mainly need to make sure it *isn't* DIALING or ALERTING.) - * @param phone - * @return true if the phone can make a new call - */ - private boolean canDial(Phone phone) { - int serviceState = phone.getServiceState().getState(); - boolean hasRingingCall = hasActiveRingingCall(); - boolean hasActiveCall = hasActiveFgCall(); - boolean hasHoldingCall = hasActiveBgCall(); - boolean allLinesTaken = hasActiveCall && hasHoldingCall; - Call.State fgCallState = getActiveFgCallState(); - - boolean result = (serviceState != ServiceState.STATE_POWER_OFF - && !hasRingingCall - && !allLinesTaken - && ((fgCallState == Call.State.ACTIVE) - || (fgCallState == Call.State.IDLE) - || (fgCallState == Call.State.DISCONNECTED))); - - if (result == false) { - Log.d(LOG_TAG, "canDial serviceState=" + serviceState - + " hasRingingCall=" + hasRingingCall - + " hasActiveCall=" + hasActiveCall - + " hasHoldingCall=" + hasHoldingCall - + " allLinesTaken=" + allLinesTaken - + " fgCallState=" + fgCallState); - } - return result; - } - - /** - * Whether or not the phone can do explicit call transfer in the current - * phone state--that is, one call holding and one call active. - * @return true if the phone can do explicit call transfer; false otherwise. - */ - public boolean canTransfer(Call heldCall) { - Phone activePhone = null; - Phone heldPhone = null; - - if (hasActiveFgCall()) { - activePhone = getActiveFgCall().getPhone(); - } - - if (heldCall != null) { - heldPhone = heldCall.getPhone(); - } - - return (heldPhone == activePhone && activePhone.canTransfer()); - } - - /** - * Connects the held call and active call - * Disconnects the subscriber from both calls - * - * Explicit Call Transfer occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if canTransfer() would return false. - * In these cases, this operation may not be performed. - */ - public void explicitCallTransfer(Call heldCall) throws CallStateException { - if (VDBG) { - Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (canTransfer(heldCall)) { - heldCall.getPhone().explicitCallTransfer(); - } - - if (VDBG) { - Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")"); - Log.d(LOG_TAG, this.toString()); - } - - } - - /** - * Returns a list of MMI codes that are pending for a phone. (They have initiated - * but have not yet completed). - * Presently there is only ever one. - * - * Use registerForMmiInitiate - * and registerForMmiComplete for change notification. - * @return null if phone doesn't have or support mmi code - */ - public List getPendingMmiCodes(Phone phone) { - Log.e(LOG_TAG, "getPendingMmiCodes not implemented"); - return null; - } - - /** - * Sends user response to a USSD REQUEST message. An MmiCode instance - * representing this response is sent to handlers registered with - * registerForMmiInitiate. - * - * @param ussdMessge Message to send in the response. - * @return false if phone doesn't support ussd service - */ - public boolean sendUssdResponse(Phone phone, String ussdMessge) { - Log.e(LOG_TAG, "sendUssdResponse not implemented"); - return false; - } - - /** - * 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, - * false to activate the microphone. - */ - - public void setMute(boolean muted) { - if (VDBG) { - Log.d(LOG_TAG, " setMute(" + muted + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - getActiveFgCall().getPhone().setMute(muted); - } - - if (VDBG) { - Log.d(LOG_TAG, "End setMute(" + muted + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * Gets current mute status. Use - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()} - * as a change notifcation, although presently phone state changed is not - * fired when setMute() is called. - * - * @return true is muting, false is unmuting - */ - public boolean getMute() { - if (hasActiveFgCall()) { - return getActiveFgCall().getPhone().getMute(); - } else if (hasActiveBgCall()) { - return getFirstActiveBgCall().getPhone().getMute(); - } - return false; - } - - /** - * Enables or disables echo suppression. - */ - public void setEchoSuppressionEnabled(boolean enabled) { - if (VDBG) { - Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled); - } - - if (VDBG) { - Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * Play a DTMF tone on the active call. - * - * @param c should be one of 0-9, '*' or '#'. Other values will be - * silently ignored. - * @return false if no active call or the active call doesn't support - * dtmf tone - */ - public boolean sendDtmf(char c) { - boolean result = false; - - if (VDBG) { - Log.d(LOG_TAG, " sendDtmf(" + c + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - getActiveFgCall().getPhone().sendDtmf(c); - result = true; - } - - if (VDBG) { - Log.d(LOG_TAG, "End sendDtmf(" + c + ")"); - Log.d(LOG_TAG, this.toString()); - } - return result; - } - - /** - * Start to paly a DTMF tone on the active call. - * or there is a playing DTMF tone. - * @param c should be one of 0-9, '*' or '#'. Other values will be - * silently ignored. - * - * @return false if no active call or the active call doesn't support - * dtmf tone - */ - public boolean startDtmf(char c) { - boolean result = false; - - if (VDBG) { - Log.d(LOG_TAG, " startDtmf(" + c + ")"); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) { - getActiveFgCall().getPhone().startDtmf(c); - result = true; - } - - if (VDBG) { - Log.d(LOG_TAG, "End startDtmf(" + c + ")"); - Log.d(LOG_TAG, this.toString()); - } - - return result; - } - - /** - * Stop the playing DTMF tone. Ignored if there is no playing DTMF - * tone or no active call. - */ - public void stopDtmf() { - if (VDBG) { - Log.d(LOG_TAG, " stopDtmf()" ); - Log.d(LOG_TAG, this.toString()); - } - - if (hasActiveFgCall()) getFgPhone().stopDtmf(); - - if (VDBG) { - Log.d(LOG_TAG, "End stopDtmf()"); - Log.d(LOG_TAG, this.toString()); - } - } - - /** - * send burst DTMF tone, it can send the string as single character or multiple character - * ignore if there is no active call or not valid digits string. - * Valid digit means only includes characters ISO-LATIN characters 0-9, *, # - * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character, - * this api can send single character and multiple character, also, this api has response - * back to caller. - * - * @param dtmfString is string representing the dialing digit(s) in the active call - * @param on the DTMF ON length in milliseconds, or 0 for default - * @param off the DTMF OFF length in milliseconds, or 0 for default - * @param onComplete is the callback message when the action is processed by BP - * - */ - public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { - if (hasActiveFgCall()) { - getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete); - return true; - } - return false; - } - - /** - * 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:

- *

  • Message.obj will be an AsyncResult
  • - *
  • AsyncResult.userObj = obj
  • - *
  • AsyncResult.result = a Connection object that is - * no longer connected.
- */ - public void registerForDisconnect(Handler h, int what, Object obj) { - mDisconnectRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for voice disconnection notification. - * Extraneous calls are tolerated silently - */ - public void unregisterForDisconnect(Handler h){ - mDisconnectRegistrants.remove(h); - } - - /** - * Register for getting notifications for change in the Call State {@link Call.State} - * This is called PreciseCallState because the call state is more precise than the - * {@link Phone.State} which can be obtained using the {@link PhoneStateListener} - * - * Resulting events will have an AsyncResult in Message.obj. - * AsyncResult.userData will be set to the obj argument here. - * The h parameter is held only by a weak reference. - */ - public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){ - mPreciseCallStateRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for voice call state change notifications. - * Extraneous calls are tolerated silently. - */ - public void unregisterForPreciseCallStateChanged(Handler h){ - mPreciseCallStateRegistrants.remove(h); - } - - /** - * 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. - */ - public void registerForUnknownConnection(Handler h, int what, Object obj){ - mUnknownConnectionRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for unknown connection notifications. - */ - public void unregisterForUnknownConnection(Handler h){ - mUnknownConnectionRegistrants.remove(h); - } - - - /** - * Notifies when a new ringing or waiting connection has appeared.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection.

- * Please check Connection.isRinging() to make sure the Connection - * has not dropped since this message was posted. - * If Connection.isRinging() is true, then - * Connection.getCall() == Phone.getRingingCall() - */ - public void registerForNewRingingConnection(Handler h, int what, Object obj){ - mNewRingingConnectionRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for new ringing connection notification. - * Extraneous calls are tolerated silently - */ - - public void unregisterForNewRingingConnection(Handler h){ - mNewRingingConnectionRegistrants.remove(h); - } - - /** - * Notifies when an incoming call rings.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection.

- */ - public void registerForIncomingRing(Handler h, int what, Object obj){ - mIncomingRingRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for ring notification. - * Extraneous calls are tolerated silently - */ - - public void unregisterForIncomingRing(Handler h){ - mIncomingRingRegistrants.remove(h); - } - - /** - * Notifies when out-band ringback tone is needed.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = boolean, true to start play ringback tone - * and false to stop.

- */ - public void registerForRingbackTone(Handler h, int what, Object obj){ - mRingbackToneRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for ringback tone notification. - */ - - public void unregisterForRingbackTone(Handler h){ - mRingbackToneRegistrants.remove(h); - } - - /** - * Registers the handler to reset the uplink mute state to get - * uplink audio. - */ - public void registerForResendIncallMute(Handler h, int what, Object obj){ - mResendIncallMuteRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for resend incall mute notifications. - */ - public void unregisterForResendIncallMute(Handler h){ - mResendIncallMuteRegistrants.remove(h); - } - - /** - * Register for notifications of initiation of a new MMI code request. - * MMI codes for GSM are discussed in 3GPP TS 22.030.

- * - * Example: If Phone.dial is called with "*#31#", then the app will - * be notified here.

- * - * The returned Message.obj will contain an AsyncResult. - * - * obj.result will be an "MmiCode" object. - */ - public void registerForMmiInitiate(Handler h, int what, Object obj){ - mMmiInitiateRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for new MMI initiate notification. - * Extraneous calls are tolerated silently - */ - public void unregisterForMmiInitiate(Handler h){ - mMmiInitiateRegistrants.remove(h); - } - - /** - * Register for notifications that an MMI request has completed - * its network activity and is in its final state. This may mean a state - * of COMPLETE, FAILED, or CANCELLED. - * - * Message.obj will contain an AsyncResult. - * obj.result will be an "MmiCode" object - */ - public void registerForMmiComplete(Handler h, int what, Object obj){ - mMmiCompleteRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for MMI complete notification. - * Extraneous calls are tolerated silently - */ - public void unregisterForMmiComplete(Handler h){ - mMmiCompleteRegistrants.remove(h); - } - - /** - * Registration point for Ecm timer reset - * @param h handler to notify - * @param what user-defined message code - * @param obj placed in Message.obj - */ - public void registerForEcmTimerReset(Handler h, int what, Object obj){ - mEcmTimerResetRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notification for Ecm timer reset - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForEcmTimerReset(Handler h){ - mEcmTimerResetRegistrants.remove(h); - } - - /** - * Register for ServiceState changed. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a ServiceState instance - */ - public void registerForServiceStateChanged(Handler h, int what, Object obj){ - mServiceStateChangedRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for ServiceStateChange notification. - * Extraneous calls are tolerated silently - */ - public void unregisterForServiceStateChanged(Handler h){ - mServiceStateChangedRegistrants.remove(h); - } - - /** - * Register for notifications when a supplementary service attempt fails. - * Message.obj will contain an AsyncResult. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - public void registerForSuppServiceFailed(Handler h, int what, Object obj){ - mSuppServiceFailedRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications when a supplementary service attempt fails. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForSuppServiceFailed(Handler h){ - mSuppServiceFailedRegistrants.remove(h); - } - - /** - * 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. - */ - public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ - mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications when a sInCall VoicePrivacy is enabled - * - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForInCallVoicePrivacyOn(Handler h){ - mInCallVoicePrivacyOnRegistrants.remove(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. - */ - public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ - mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications when a sInCall VoicePrivacy is disabled - * - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForInCallVoicePrivacyOff(Handler h){ - mInCallVoicePrivacyOffRegistrants.remove(h); - } - - /** - * Register for notifications when CDMA call waiting comes - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - public void registerForCallWaiting(Handler h, int what, Object obj){ - mCallWaitingRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications when CDMA Call waiting comes - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForCallWaiting(Handler h){ - mCallWaitingRegistrants.remove(h); - } - - - /** - * Register for signal information notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - - public void registerForSignalInfo(Handler h, int what, Object obj){ - mSignalInfoRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for signal information notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForSignalInfo(Handler h){ - mSignalInfoRegistrants.remove(h); - } - - /** - * Register for display information notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - public void registerForDisplayInfo(Handler h, int what, Object obj){ - mDisplayInfoRegistrants.addUnique(h, what, obj); - } - - /** - * Unregisters for display information notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForDisplayInfo(Handler h) { - mDisplayInfoRegistrants.remove(h); - } - - /** - * Register for notifications when CDMA OTA Provision status change - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){ - mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications when CDMA OTA Provision status change - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForCdmaOtaStatusChange(Handler h){ - mCdmaOtaStatusChangeRegistrants.remove(h); - } - - /** - * Registration point for subscription info ready - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){ - mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj); - } - - /** - * Unregister for notifications for subscription info - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForSubscriptionInfoReady(Handler h){ - mSubscriptionInfoReadyRegistrants.remove(h); - } - - /** - * Sets an event to be fired when the telephony system processes - * a post-dial character on an outgoing call.

- * - * Messages of type what will be sent to h. - * The obj field of these Message's will be instances of - * AsyncResult. Message.obj.result will be - * a Connection object.

- * - * Message.arg1 will be the post dial character being processed, - * or 0 ('\0') if end of string.

- * - * 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 - * DTMF sequence.

- * - * 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() - * Connection.cancelPostDial()} - * for the telephony system to continue playing the - * post-dial DTMF sequence.

- * - */ - public void registerForPostDialCharacter(Handler h, int what, Object obj){ - mPostDialCharacterRegistrants.addUnique(h, what, obj); - } - - public void unregisterForPostDialCharacter(Handler h){ - mPostDialCharacterRegistrants.remove(h); - } - - /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls - * 1. APIs to access list of calls - * 2. APIs to check if any active call, which has connection other than - * disconnected ones, pleaser refer to Call.isIdle() - * 3. APIs to return first active call - * 4. APIs to return the connections of first active call - * 5. APIs to return other property of first active call - */ - - /** - * @return list of all ringing calls - */ - public List getRingingCalls() { - return Collections.unmodifiableList(mRingingCalls); - } - - /** - * @return list of all foreground calls - */ - public List getForegroundCalls() { - return Collections.unmodifiableList(mForegroundCalls); - } - - /** - * @return list of all background calls - */ - public List getBackgroundCalls() { - return Collections.unmodifiableList(mBackgroundCalls); - } - - /** - * Return true if there is at least one active foreground call - */ - public boolean hasActiveFgCall() { - return (getFirstActiveCall(mForegroundCalls) != null); - } - - /** - * Return true if there is at least one active background call - */ - public boolean hasActiveBgCall() { - // TODO since hasActiveBgCall may get called often - // better to cache it to improve performance - return (getFirstActiveCall(mBackgroundCalls) != null); - } - - /** - * Return true if there is at least one active ringing call - * - */ - public boolean hasActiveRingingCall() { - return (getFirstActiveCall(mRingingCalls) != null); - } - - /** - * return the active foreground call from foreground calls - * - * Active call means the call is NOT in Call.State.IDLE - * - * 1. If there is active foreground call, return it - * 2. If there is no active foreground call, return the - * foreground call associated with default phone, which state is IDLE. - * 3. If there is no phone registered at all, return null. - * - */ - public Call getActiveFgCall() { - Call call = getFirstNonIdleCall(mForegroundCalls); - if (call == null) { - call = (mDefaultPhone == null) - ? null - : mDefaultPhone.getForegroundCall(); - } - return call; - } - - // Returns the first call that is not in IDLE state. If both active calls - // and disconnecting/disconnected calls exist, return the first active call. - private Call getFirstNonIdleCall(List calls) { - Call result = null; - for (Call call : calls) { - if (!call.isIdle()) { - return call; - } else if (call.getState() != Call.State.IDLE) { - if (result == null) result = call; - } - } - return result; - } - - /** - * return one active background call from background calls - * - * Active call means the call is NOT idle defined by Call.isIdle() - * - * 1. If there is only one active background call, return it - * 2. If there is more than one active background call, return the first one - * 3. If there is no active background call, return the background call - * associated with default phone, which state is IDLE. - * 4. If there is no background call at all, return null. - * - * Complete background calls list can be get by getBackgroundCalls() - */ - public Call getFirstActiveBgCall() { - Call call = getFirstNonIdleCall(mBackgroundCalls); - if (call == null) { - call = (mDefaultPhone == null) - ? null - : mDefaultPhone.getBackgroundCall(); - } - return call; - } - - /** - * return one active ringing call from ringing calls - * - * Active call means the call is NOT idle defined by Call.isIdle() - * - * 1. If there is only one active ringing call, return it - * 2. If there is more than one active ringing call, return the first one - * 3. If there is no active ringing call, return the ringing call - * associated with default phone, which state is IDLE. - * 4. If there is no ringing call at all, return null. - * - * Complete ringing calls list can be get by getRingingCalls() - */ - public Call getFirstActiveRingingCall() { - Call call = getFirstNonIdleCall(mRingingCalls); - if (call == null) { - call = (mDefaultPhone == null) - ? null - : mDefaultPhone.getRingingCall(); - } - return call; - } - - /** - * @return the state of active foreground call - * return IDLE if there is no active foreground call - */ - public Call.State getActiveFgCallState() { - Call fgCall = getActiveFgCall(); - - if (fgCall != null) { - return fgCall.getState(); - } - - return Call.State.IDLE; - } - - /** - * @return the connections of active foreground call - * return empty list if there is no active foreground call - */ - public List getFgCallConnections() { - Call fgCall = getActiveFgCall(); - if ( fgCall != null) { - return fgCall.getConnections(); - } - return emptyConnections; - } - - /** - * @return the connections of active background call - * return empty list if there is no active background call - */ - public List getBgCallConnections() { - Call bgCall = getFirstActiveBgCall(); - if ( bgCall != null) { - return bgCall.getConnections(); - } - return emptyConnections; - } - - /** - * @return the latest connection of active foreground call - * return null if there is no active foreground call - */ - public Connection getFgCallLatestConnection() { - Call fgCall = getActiveFgCall(); - if ( fgCall != null) { - return fgCall.getLatestConnection(); - } - return null; - } - - /** - * @return true if there is at least one Foreground call in disconnected state - */ - public boolean hasDisconnectedFgCall() { - return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null); - } - - /** - * @return true if there is at least one background call in disconnected state - */ - public boolean hasDisconnectedBgCall() { - return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null); - } - - /** - * @return the first active call from a call list - */ - private Call getFirstActiveCall(ArrayList calls) { - for (Call call : calls) { - if (!call.isIdle()) { - return call; - } - } - return null; - } - - /** - * @return the first call in a the Call.state from a call list - */ - private Call getFirstCallOfState(ArrayList calls, Call.State state) { - for (Call call : calls) { - if (call.getState() == state) { - return call; - } - } - return null; - } - - - private boolean hasMoreThanOneRingingCall() { - int count = 0; - for (Call call : mRingingCalls) { - if (call.getState().isRinging()) { - if (++count > 1) return true; - } - } - return false; - } - - private Handler mHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - - switch (msg.what) { - case EVENT_DISCONNECT: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)"); - mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_PRECISE_CALL_STATE_CHANGED: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)"); - mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_NEW_RINGING_CONNECTION: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)"); - if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) { - Connection c = (Connection) ((AsyncResult) msg.obj).result; - try { - Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall()); - c.getCall().hangup(); - } catch (CallStateException e) { - Log.w(LOG_TAG, "new ringing connection", e); - } - } else { - mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj); - } - break; - case EVENT_UNKNOWN_CONNECTION: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)"); - mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_INCOMING_RING: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)"); - // The event may come from RIL who's not aware of an ongoing fg call - if (!hasActiveFgCall()) { - mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj); - } - break; - case EVENT_RINGBACK_TONE: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)"); - mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_IN_CALL_VOICE_PRIVACY_ON: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)"); - mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_IN_CALL_VOICE_PRIVACY_OFF: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)"); - mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_CALL_WAITING: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)"); - mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_DISPLAY_INFO: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)"); - mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_SIGNAL_INFO: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)"); - mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_CDMA_OTA_STATUS_CHANGE: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)"); - mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_RESEND_INCALL_MUTE: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)"); - mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_MMI_INITIATE: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)"); - mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_MMI_COMPLETE: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)"); - mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_ECM_TIMER_RESET: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)"); - mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_SUBSCRIPTION_INFO_READY: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)"); - mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_SUPP_SERVICE_FAILED: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)"); - mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_SERVICE_STATE_CHANGED: - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)"); - mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj); - break; - case EVENT_POST_DIAL_CHARACTER: - // we need send the character that is being processed in msg.arg1 - // so can't use notifyRegistrants() - if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)"); - for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) { - Message notifyMsg; - notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant(); - notifyMsg.obj = msg.obj; - notifyMsg.arg1 = msg.arg1; - notifyMsg.sendToTarget(); - } - break; - } - } - }; - - @Override - public String toString() { - Call call; - StringBuilder b = new StringBuilder(); - - b.append("CallManager {"); - b.append("\nstate = " + getState()); - call = getActiveFgCall(); - b.append("\n- Foreground: " + getActiveFgCallState()); - b.append(" from " + call.getPhone()); - b.append("\n Conn: ").append(getFgCallConnections()); - call = getFirstActiveBgCall(); - b.append("\n- Background: " + call.getState()); - b.append(" from " + call.getPhone()); - b.append("\n Conn: ").append(getBgCallConnections()); - call = getFirstActiveRingingCall(); - b.append("\n- Ringing: " +call.getState()); - b.append(" from " + call.getPhone()); - - for (Phone phone : getAllPhones()) { - if (phone != null) { - b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName() - + ", state = " + phone.getState()); - call = phone.getForegroundCall(); - b.append("\n- Foreground: ").append(call); - call = phone.getBackgroundCall(); - b.append(" Background: ").append(call); - call = phone.getRingingCall(); - b.append(" Ringing: ").append(call); - } - } - b.append("\n}"); - return b.toString(); - } -} diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java deleted file mode 100644 index 60871248d3fb..000000000000 --- a/telephony/java/com/android/internal/telephony/CallStateException.java +++ /dev/null @@ -1,34 +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; - -/** - * {@hide} - */ -public class CallStateException extends Exception -{ - public - CallStateException() - { - } - - public - CallStateException(String string) - { - super(string); - } -} diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java deleted file mode 100644 index 62caf01df600..000000000000 --- a/telephony/java/com/android/internal/telephony/CallTracker.java +++ /dev/null @@ -1,182 +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; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.telephony.CommandException; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - - -/** - * {@hide} - */ -public abstract class CallTracker extends Handler { - - 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; - protected static final int EVENT_OPERATION_COMPLETE = 4; - protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; - - protected static final int EVENT_SWITCH_RESULT = 8; - protected static final int EVENT_RADIO_AVAILABLE = 9; - protected static final int EVENT_RADIO_NOT_AVAILABLE = 10; - protected static final int EVENT_CONFERENCE_RESULT = 11; - protected static final int EVENT_SEPARATE_RESULT = 12; - protected static final int EVENT_ECT_RESULT = 13; - protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14; - protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15; - protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16; - - protected void pollCallsWhenSafe() { - needsPoll = true; - - if (checkNoOperationsPending()) { - lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); - cm.getCurrentCalls(lastRelevantPoll); - } - } - - protected void - pollCallsAfterDelay() { - Message msg = obtainMessage(); - - msg.what = EVENT_REPOLL_AFTER_DELAY; - 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 invocation - * of getCurrentCalls() will be postponed until this - * operation is also complete. - */ - protected Message - obtainNoPollCompleteMessage(int what) { - pendingOperations++; - lastRelevantPoll = null; - return obtainMessage(what); - } - - /** - * @return true if we're idle or there's a call to getCurrentCalls() pending - * but nothing else - */ - private boolean - checkNoOperationsPending() { - if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" + - pendingOperations); - return pendingOperations == 0; - } - - /** - * Routine called from dial to check if the number is a test Emergency number - * and if so remap the number. This allows a short emergency number to be remapped - * to a regular number for testing how the frameworks handles emergency numbers - * without actually calling an emergency number. - * - * This is not a full test and is not a substitute for testing real emergency - * numbers but can be useful. - * - * To use this feature set a system property ril.test.emergencynumber to a pair of - * numbers separated by a colon. If the first number matches the number parameter - * this routine returns the second number. Example: - * - * ril.test.emergencynumber=112:1-123-123-45678 - * - * To test Dial 112 take call then hang up on MO device to enter ECM - * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND - * - * @param number to test if it should be remapped - * @return the same number or the remapped number. - */ - protected String checkForTestEmergencyNumber(String dialString) { - String testEn = SystemProperties.get("ril.test.emergencynumber"); - if (DBG_POLL) { - log("checkForTestEmergencyNumber: dialString=" + dialString + - " testEn=" + testEn); - } - if (!TextUtils.isEmpty(testEn)) { - String values[] = testEn.split(":"); - log("checkForTestEmergencyNumber: values.length=" + values.length); - if (values.length == 2) { - if (values[0].equals( - android.telephony.PhoneNumberUtils.stripSeparators(dialString))) { - cm.testingEmergencyCall(); - log("checkForTestEmergencyNumber: remap " + - dialString + " to " + values[1]); - dialString = values[1]; - } - } - } - return dialString; - } - - //***** Overridden from Handler - public abstract void handleMessage (Message msg); - public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj); - public abstract void unregisterForVoiceCallStarted(Handler h); - public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj); - public abstract void unregisterForVoiceCallEnded(Handler h); - - protected abstract void log(String msg); - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CallTracker:"); - pw.println(" pendingOperations=" + pendingOperations); - pw.println(" needsPoll=" + needsPoll); - pw.println(" lastRelevantPoll=" + lastRelevantPoll); - } -} diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java deleted file mode 100644 index 94c544ecffd5..000000000000 --- a/telephony/java/com/android/internal/telephony/CommandException.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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; - -import com.android.internal.telephony.RILConstants; - -import android.util.Log; - -/** - * {@hide} - */ -public class CommandException extends RuntimeException { - private Error e; - - public enum Error { - INVALID_RESPONSE, - RADIO_NOT_AVAILABLE, - GENERIC_FAILURE, - PASSWORD_INCORRECT, - SIM_PIN2, - SIM_PUK2, - REQUEST_NOT_SUPPORTED, - OP_NOT_ALLOWED_DURING_VOICE_CALL, - OP_NOT_ALLOWED_BEFORE_REG_NW, - SMS_FAIL_RETRY, - SIM_ABSENT, - SUBSCRIPTION_NOT_AVAILABLE, - MODE_NOT_SUPPORTED, - FDN_CHECK_FAILURE, - ILLEGAL_SIM_OR_ME, - } - - public CommandException(Error e) { - super(e.toString()); - this.e = e; - } - - public static CommandException - fromRilErrno(int ril_errno) { - switch(ril_errno) { - case RILConstants.SUCCESS: return null; - case RILConstants.RIL_ERRNO_INVALID_RESPONSE: - return new CommandException(Error.INVALID_RESPONSE); - case RILConstants.RADIO_NOT_AVAILABLE: - return new CommandException(Error.RADIO_NOT_AVAILABLE); - case RILConstants.GENERIC_FAILURE: - return new CommandException(Error.GENERIC_FAILURE); - case RILConstants.PASSWORD_INCORRECT: - return new CommandException(Error.PASSWORD_INCORRECT); - case RILConstants.SIM_PIN2: - return new CommandException(Error.SIM_PIN2); - case RILConstants.SIM_PUK2: - return new CommandException(Error.SIM_PUK2); - 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); - case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW: - return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW); - case RILConstants.SMS_SEND_FAIL_RETRY: - return new CommandException(Error.SMS_FAIL_RETRY); - case RILConstants.SIM_ABSENT: - return new CommandException(Error.SIM_ABSENT); - case RILConstants.SUBSCRIPTION_NOT_AVAILABLE: - return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE); - case RILConstants.MODE_NOT_SUPPORTED: - return new CommandException(Error.MODE_NOT_SUPPORTED); - case RILConstants.FDN_CHECK_FAILURE: - return new CommandException(Error.FDN_CHECK_FAILURE); - case RILConstants.ILLEGAL_SIM_OR_ME: - return new CommandException(Error.ILLEGAL_SIM_OR_ME); - default: - Log.e("GSM", "Unrecognized RIL errno " + ril_errno); - return new CommandException(Error.INVALID_RESPONSE); - } - } - - public Error getCommandError() { - return e; - } - - - -} diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java deleted file mode 100644 index f7757b3867e5..000000000000 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ /dev/null @@ -1,1579 +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; - -import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; - -import android.os.Message; -import android.os.Handler; -import android.util.Log; - -/** - * {@hide} - */ -public interface CommandsInterface { - enum RadioState { - RADIO_OFF, /* Radio explicitly powered off (eg CFUN=0) */ - RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */ - RADIO_ON; /* Radio is on */ - - public boolean isOn() /* and available...*/ { - return this == RADIO_ON; - } - - public boolean isAvailable() { - return this != RADIO_UNAVAILABLE; - } - } - - //***** Constants - - // Used as parameter to dial() and setCLIR() below - static final int CLIR_DEFAULT = 0; // "use subscription default value" - static final int CLIR_INVOCATION = 1; // (restrict CLI presentation) - static final int CLIR_SUPPRESSION = 2; // (allow CLI presentation) - - - // Used as parameters for call forward methods below - static final int CF_ACTION_DISABLE = 0; - static final int CF_ACTION_ENABLE = 1; -// static final int CF_ACTION_UNUSED = 2; - static final int CF_ACTION_REGISTRATION = 3; - static final int CF_ACTION_ERASURE = 4; - - static final int CF_REASON_UNCONDITIONAL = 0; - static final int CF_REASON_BUSY = 1; - static final int CF_REASON_NO_REPLY = 2; - static final int CF_REASON_NOT_REACHABLE = 3; - static final int CF_REASON_ALL = 4; - static final int CF_REASON_ALL_CONDITIONAL = 5; - - // Used for call barring methods below - static final String CB_FACILITY_BAOC = "AO"; - static final String CB_FACILITY_BAOIC = "OI"; - static final String CB_FACILITY_BAOICxH = "OX"; - static final String CB_FACILITY_BAIC = "AI"; - static final String CB_FACILITY_BAICr = "IR"; - static final String CB_FACILITY_BA_ALL = "AB"; - static final String CB_FACILITY_BA_MO = "AG"; - 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 - static final int SERVICE_CLASS_NONE = 0; // no user input - static final int SERVICE_CLASS_VOICE = (1 << 0); - static final int SERVICE_CLASS_DATA = (1 << 1); //synonym for 16+32+64+128 - static final int SERVICE_CLASS_FAX = (1 << 2); - static final int SERVICE_CLASS_SMS = (1 << 3); - static final int SERVICE_CLASS_DATA_SYNC = (1 << 4); - 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); - static final int SERVICE_CLASS_MAX = (1 << 7); // Max SERVICE_CLASS value - - // Numeric representation of string values returned - // by messages sent to setOnUSSD handler - static final int USSD_MODE_NOTIFY = 0; - static final int USSD_MODE_REQUEST = 1; - - // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22. - static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0xD3; - static final int GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY = 0xD4; - static final int GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR = 0xD5; - static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR = 0xFF; - - // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms. From TS N.S0005, 6.5.2.125. - static final int CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID = 4; - static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE = 35; - static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM = 39; - static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM = 96; - - //***** Methods - RadioState getRadioState(); - - void getVoiceRadioTechnology(Message result); - - /** - * Fires on any RadioState transition - * Always fires immediately as well - * - * do not attempt to calculate transitions by storing getRadioState() values - * on previous invocations of this notification. Instead, use the other - * registration methods - */ - void registerForRadioStateChanged(Handler h, int what, Object obj); - void unregisterForRadioStateChanged(Handler h); - - void registerForVoiceRadioTechChanged(Handler h, int what, Object obj); - void unregisterForVoiceRadioTechChanged(Handler h); - - /** - * 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 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); - - /** - * 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); - - /** - * 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 unregisterForOffOrNotAvailable(Handler h); - - /** - * Fires on any change in ICC status - */ - void registerForIccStatusChanged(Handler h, int what, Object obj); - void unregisterForIccStatusChanged(Handler h); - - void registerForCallStateChanged(Handler h, int what, Object obj); - void unregisterForCallStateChanged(Handler h); - void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj); - void unregisterForVoiceNetworkStateChanged(Handler h); - void registerForDataNetworkStateChanged(Handler h, int what, Object obj); - void unregisterForDataNetworkStateChanged(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); - - /** - * unlike the register* methods, there's only one new 3GPP format SMS handler. - * if you need to unregister, you should also tell the radio to stop - * sending SMS's to you (via AT+CNMI) - * - * AsyncResult.result is a String containing the SMS PDU - */ - void setOnNewGsmSms(Handler h, int what, Object obj); - void unSetOnNewGsmSms(Handler h); - - /** - * unlike the register* methods, there's only one new 3GPP2 format SMS handler. - * if you need to unregister, you should also tell the radio to stop - * sending SMS's to you (via AT+CNMI) - * - * AsyncResult.result is a String containing the SMS PDU - */ - void setOnNewCdmaSms(Handler h, int what, Object obj); - void unSetOnNewCdmaSms(Handler h); - - /** - * Set the handler for SMS Cell Broadcast messages. - * - * AsyncResult.result is a byte array containing the SMS-CB PDU - */ - void setOnNewGsmBroadcastSms(Handler h, int what, Object obj); - void unSetOnNewGsmBroadcastSms(Handler h); - - /** - * 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 - * - * 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)[1] is a Long containing the milliseconds since boot as - * returned by elapsedRealtime() when this NITZ time - * was posted. - * - * Please note that the delivery of this message may be delayed several - * 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] - * "1" USSD-Request -- text in ((const char **)data)[1] - * "2" Session terminated by network - * "3" other local client (eg, SIM Toolkit) has responded - * "4" Operation not supported - * "5" Network timeout - * - * ((String[])(AsyncResult.result))[1] contains the USSD message - * The numeric representations of these are in USSD_MODE_* - */ - - 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) - * 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/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 setOnIccSmsFull(Handler h, int what, Object obj); - void unSetOnIccSmsFull(Handler h); - - /** - * Sets the handler for SIM Refresh notifications. - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForIccRefresh(Handler h, int what, Object obj); - void unregisterForIccRefresh(Handler h); - - 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 - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnCallRing(Handler h, int what, Object obj); - void unSetOnCallRing(Handler h); - - /** - * Sets the handler for RESTRICTED_STATE changed notification, - * eg, for Domain Specific Access Control - * unlike the register* methods, there's only one signal strength handler - * - * AsyncResult.result is an int[1] - * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values - */ - - void setOnRestrictedStateChanged(Handler h, int what, Object obj); - void unSetOnRestrictedStateChanged(Handler h); - - /** - * Sets the handler for Supplementary Service Notifications. - * 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 setOnSuppServiceNotification(Handler h, int what, Object obj); - void unSetOnSuppServiceNotification(Handler h); - - /** - * Sets the handler for Session End Notifications for CAT. - * 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 setOnCatSessionEnd(Handler h, int what, Object obj); - void unSetOnCatSessionEnd(Handler h); - - /** - * Sets the handler for Proactive Commands for CAT. - * 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 setOnCatProactiveCmd(Handler h, int what, Object obj); - void unSetOnCatProactiveCmd(Handler h); - - /** - * Sets the handler for Event Notifications for CAT. - * 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 setOnCatEvent(Handler h, int what, Object obj); - void unSetOnCatEvent(Handler h); - - /** - * Sets the handler for Call Set Up Notifications for CAT. - * 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 setOnCatCallSetUp(Handler h, int what, Object obj); - void unSetOnCatCallSetUp(Handler h); - - /** - * Enables/disbables supplementary service related notifications from - * the network. - * - * @param enable true to enable notifications, false to disable. - * @param result Message to be posted when command completes. - */ - void setSuppServiceNotifications(boolean enable, Message result); - //void unSetSuppServiceNotifications(Handler h); - - /** - * Sets the handler for Event Notifications for CDMA Display Info. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForDisplayInfo(Handler h, int what, Object obj); - void unregisterForDisplayInfo(Handler h); - - /** - * Sets the handler for Event Notifications for CallWaiting Info. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForCallWaitingInfo(Handler h, int what, Object obj); - void unregisterForCallWaitingInfo(Handler h); - - /** - * Sets the handler for Event Notifications for Signal Info. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForSignalInfo(Handler h, int what, Object obj); - void unregisterForSignalInfo(Handler h); - - /** - * Registers the handler for CDMA number information record - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForNumberInfo(Handler h, int what, Object obj); - void unregisterForNumberInfo(Handler h); - - /** - * Registers the handler for CDMA redirected number Information record - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForRedirectedNumberInfo(Handler h, int what, Object obj); - void unregisterForRedirectedNumberInfo(Handler h); - - /** - * Registers the handler for CDMA line control information record - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForLineControlInfo(Handler h, int what, Object obj); - void unregisterForLineControlInfo(Handler h); - - /** - * Registers the handler for CDMA T53 CLIR information record - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerFoT53ClirlInfo(Handler h, int what, Object obj); - void unregisterForT53ClirInfo(Handler h); - - /** - * Registers the handler for CDMA T53 audio control information record - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForT53AudioControlInfo(Handler h, int what, Object obj); - void unregisterForT53AudioControlInfo(Handler h); - - /** - * Fires on if Modem enters Emergency Callback mode - */ - void setEmergencyCallbackMode(Handler h, int what, Object obj); - - /** - * Fires on any CDMA OTA provision status change - */ - void registerForCdmaOtaProvision(Handler h,int what, Object obj); - void unregisterForCdmaOtaProvision(Handler h); - - /** - * Registers the handler when out-band ringback tone is needed.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = boolean.

- */ - void registerForRingbackTone(Handler h, int what, Object obj); - void unregisterForRingbackTone(Handler h); - - /** - * Registers the handler when mute/unmute need to be resent to get - * uplink audio during a call.

- * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - * - */ - void registerForResendIncallMute(Handler h, int what, Object obj); - void unregisterForResendIncallMute(Handler h); - - /** - * Registers the handler for when Cdma subscription changed events - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - * - */ - void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj); - void unregisterForCdmaSubscriptionChanged(Handler h); - - /** - * Registers the handler for when Cdma prl changed events - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - * - */ - void registerForCdmaPrlChanged(Handler h, int what, Object obj); - void unregisterForCdmaPrlChanged(Handler h); - - /** - * Registers the handler for when Cdma prl changed events - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - * - */ - void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj); - void unregisterForExitEmergencyCallbackMode(Handler h); - - /** - * Registers the handler for RIL_UNSOL_RIL_CONNECT events. - * - * When ril connects or disconnects a message is sent to the registrant - * which contains an AsyncResult, ar, in msg.obj. The ar.result is an - * Integer which is the version of the ril or -1 if the ril disconnected. - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForRilConnected(Handler h, int what, Object obj); - void unregisterForRilConnected(Handler h); - - /** - * Supply the ICC PIN to the ICC card - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPin(String pin, Message result); - - /** - * Supply the PIN for the app with this AID on the ICC card - * - * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4 - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPinForApp(String pin, String aid, Message result); - - /** - * Supply the ICC PUK and newPin to the ICC card - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPuk(String puk, String newPin, Message result); - - /** - * Supply the PUK, new pin for the app with this AID on the ICC card - * - * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4 - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPukForApp(String puk, String newPin, String aid, Message result); - - /** - * 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 - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPin2(String pin2, Message result); - - /** - * Supply the PIN2 for the app with this AID on the ICC card - * Only called following operation where ICC_PIN2 was - * returned as a a failure from a previous operation - * - * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4 - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPin2ForApp(String pin2, String aid, Message result); - - /** - * 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 - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPuk2(String puk2, String newPin2, Message result); - - /** - * Supply the PUK2, newPin2 for the app with this AID on the ICC card - * Only called following operation where SIM_PUK2 was - * returned as a a failure from a previous operation - * - * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4 - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result); - - void changeIccPin(String oldPin, String newPin, Message result); - void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result); - void changeIccPin2(String oldPin2, String newPin2, Message result); - void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result); - - void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result); - - void supplyNetworkDepersonalization(String netpin, 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 DriverCall - * The ar.result List is sorted by DriverCall.index - */ - 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 DataCallState - * @deprecated Do not use. - */ - @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 DataCallState - */ - void getDataCallList(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 is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - void dial (String address, int clirMode, 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 is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - void dial(String address, int clirMode, UUSInfo uusInfo, 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 is String containing IMSI on success - */ - void getIMSI(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 is String containing IMSI on success - */ - void getIMSIForApp(String aid, 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 is String containing IMEI on success - */ - void getIMEI(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 is String containing IMEISV on success - */ - void getIMEISV(Message result); - - /** - * Hang up one individual connection. - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - * - * 3GPP 22.030 6.5.5 - * "Releases a specific active call X" - */ - void hangupConnection (int gsmIndex, Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Releases all held calls or sets User Determined User Busy (UDUB) - * for a waiting call." - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void hangupWaitingOrBackground (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Releases all active calls (if any exist) and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void hangupForegroundResumeBackground (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls (if any exist) on hold and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void switchWaitingOrHoldingAndActive (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Adds a held call to the conversation" - * - * 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); - - /** - * Set preferred Voice Privacy (VP). - * - * @param enable true is enhanced and false is normal VP - * @param result is a callback message - */ - void setPreferredVoicePrivacy(boolean enable, Message result); - - /** - * Get currently set preferred Voice Privacy (VP) mode. - * - * @param result is a callback message - */ - void getPreferredVoicePrivacy(Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls on hold except call X with which - * communication shall be supported." - */ - void separateConnection (int gsmIndex, Message result); - - /** - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void 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); - - /** - * 3GPP 22.030 6.5.5 - * "Connects the two calls and disconnects the subscriber from both calls" - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void explicitCallTransfer (Message result); - - /** - * cause code returned as int[0] in Message.obj.response - * Returns integer cause code defined in TS 24.008 - * Annex H or closest approximation. - * Most significant codes: - * - Any defined in 22.001 F.4 (for generating busy/congestion) - * - Cause 68: ACM >= ACMMax - */ - 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 Do not use. - */ - @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); - - /** - * 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) - * as defined in TS 27.007 8.5 - */ - void getSignalStrength (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 - * valid LAC and CIDs are 0x0000 - 0xffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - void getVoiceRegistrationState (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 - * valid LAC and CIDs are 0x0000 - 0xffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - void getDataRegistrationState (Message response); - - /** - * response.obj.result is a String[3] - * 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); - - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void startDtmf(char c, Message result); - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void stopDtmf(Message result); - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void sendBurstDtmf(String dtmfString, int on, int off, Message result); - - /** - * 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 - */ - 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_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 - * any error that may have occurred (eg, out of memory). - */ - void writeSmsToSim(int status, String smsc, String pdu, Message response); - - void writeSmsToRuim(int status, String pdu, Message response); - - void setRadioPower(boolean on, Message response); - - void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response); - - void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response); - - /** - * Acknowledge successful or failed receipt of last incoming SMS, - * including acknowledgement TPDU to send as the RP-User-Data element - * of the RP-ACK or RP-ERROR PDU. - * - * @param success true to send RP-ACK, false to send RP-ERROR - * @param ackPdu the acknowledgement TPDU in hexadecimal format - * @param response sent when operation completes. - */ - void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response); - - /** - * parameters equivalent to 27.007 AT+CRSM command - * response.obj will be an AsyncResult - * response.obj.result will be an IccIoResult on success - */ - void iccIO (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, Message response); - - /** - * parameters equivalent to 27.007 AT+CRSM command - * response.obj will be an AsyncResult - * response.obj.userObj will be a IccIoResult on success - */ - void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, String aid, 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". - * - * @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 - * - * 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 - */ - - 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. - * - * @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_* - */ - 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, - String number, Message response); - - void setNetworkSelectionModeAutomatic(Message response); - - void setNetworkSelectionModeManual(String operatorNumeric, Message response); - - /** - * Queries whether the current network selection mode is automatic - * or manual - * - * ((AsyncResult)response.obj).result is an int[] with element [0] being - * a 0 for automatic selection and a 1 for manual selection - */ - - void getNetworkSelectionMode(Message response); - - /** - * Queries the currently available networks - * - * ((AsyncResult)response.obj).result is a List of NetworkInfo objects - */ - void getAvailableNetworks(Message response); - - void getBasebandVersion (Message response); - - - /** - * (AsyncResult)response.obj).result will be an Integer representing - * the sum of enabled service classes (sum of SERVICE_CLASS_*) - * - * @param facility one of CB_FACILTY_* - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - void queryFacilityLock (String facility, String password, int serviceClass, - Message response); - - /** - * (AsyncResult)response.obj).result will be an Integer representing - * the sum of enabled service classes (sum of SERVICE_CLASS_*) for the - * application with appId. - * - * @param facility one of CB_FACILTY_* - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param appId is application Id or null if none - * @param response is callback message - */ - - void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId, - Message response); - - /** - * @param facility one of CB_FACILTY_* - * @param lockState true means lock, false means unlock - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - void setFacilityLock (String facility, boolean lockState, String password, - int serviceClass, Message response); - - /** - * Set the facility lock for the app with this AID on the ICC card. - * - * @param facility one of CB_FACILTY_* - * @param lockState true means lock, false means unlock - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param appId is application Id or null if none - * @param response is callback message - */ - void setFacilityLockForApp(String facility, boolean lockState, String password, - int serviceClass, String appId, Message response); - - void sendUSSD (String ussdString, Message response); - - /** - * Cancels a pending USSD session if one exists. - * @param response callback message - */ - void cancelPendingUssd (Message response); - - void resetRadio(Message result); - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - void setBandMode (int bandMode, Message response); - - /** - * 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 - */ - void queryAvailableBandMode (Message response); - - /** - * Set the current preferred network type. This will be the last - * networkType that was passed to setPreferredNetworkType. - */ - void setCurrentPreferredNetworkType(); - - /** - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * @param networkType one of NT_*_TYPE - * @param response is callback message - */ - void setPreferredNetworkType(int networkType , Message response); - - /** - * Query the preferred network type setting - * - * @param response is callback message to report one of NT_*_TYPE - */ - void getPreferredNetworkType(Message response); - - /** - * Query neighboring cell ids - * - * @param response s callback message to cell ids - */ - void getNeighboringCids(Message response); - - /** - * Request to enable/disable network state change notifications when - * location information (lac and/or cid) has changed. - * - * @param enable true to enable, false to disable - * @param response callback message - */ - void setLocationUpdates(boolean enable, Message response); - - /** - * Gets the default SMSC address. - * - * @param result Callback message contains the SMSC address. - */ - void getSmscAddress(Message result); - - /** - * Sets the default SMSC address. - * - * @param address new SMSC address - * @param result Callback message is empty on completion - */ - void setSmscAddress(String address, Message result); - - /** - * Indicates whether there is storage available for new SMS messages. - * @param available true if storage is available - * @param result callback message - */ - void reportSmsMemoryStatus(boolean available, Message result); - - /** - * Indicates to the vendor ril that StkService is running - * and is ready to receive RIL_UNSOL_STK_XXXX commands. - * - * @param result callback message - */ - void reportStkServiceIsRunning(Message result); - - void invokeOemRilRequestRaw(byte[] data, Message response); - - void invokeOemRilRequestStrings(String[] strings, Message response); - - - /** - * Send TERMINAL RESPONSE to the SIM, after processing a proactive command - * sent by the SIM. - * - * @param contents String containing SAT/USAT response in hexadecimal - * format starting with first byte of response data. See - * TS 102 223 for details. - * @param response Callback message - */ - public void sendTerminalResponse(String contents, Message response); - - /** - * Send ENVELOPE to the SIM, after processing a proactive command sent by - * the SIM. - * - * @param contents String containing SAT/USAT response in hexadecimal - * format starting with command tag. See TS 102 223 for - * details. - * @param response Callback message - */ - public void sendEnvelope(String contents, Message response); - - /** - * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope - * for a SIM data download message. This method has one difference - * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response - * are returned along with the response data. - * - * response.obj will be an AsyncResult - * response.obj.result will be an IccIoResult on success - * - * @param contents String containing SAT/USAT response in hexadecimal - * format starting with command tag. See TS 102 223 for - * details. - * @param response Callback message - */ - public void sendEnvelopeWithStatus(String contents, Message response); - - /** - * Accept or reject the call setup request from SIM. - * - * @param accept true if the call is to be accepted, false otherwise. - * @param response Callback message - */ - public void handleCallSetupRequestFromSim(boolean accept, Message response); - - /** - * Activate or deactivate cell broadcast SMS for GSM. - * - * @param activate - * true = activate, false = deactivate - * @param result Callback message is empty on completion - */ - public void setGsmBroadcastActivation(boolean activate, Message result); - - /** - * Configure cell broadcast SMS for GSM. - * - * @param response Callback message is empty on completion - */ - public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response); - - /** - * Query the current configuration of cell broadcast SMS of GSM. - * - * @param response - * Callback message contains the configuration from the modem - * on completion - */ - public void getGsmBroadcastConfig(Message response); - - //***** new Methods for CDMA support - - /** - * 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 - */ - public void getDeviceIdentity(Message response); - - /** - * Request the device MDN / H_SID / H_NID / MIN. - * "response" is const char ** - * [0] is MDN if CDMA subscription is available - * [1] is a comma separated list of H_SID (Home SID) in decimal format - * if CDMA subscription is available - * [2] is a comma separated list of H_NID (Home NID) in decimal format - * if CDMA subscription is available - * [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available - */ - public void getCDMASubscription(Message response); - - /** - * Send Flash Code. - * "response" is is NULL - * [0] is a FLASH string - */ - public void sendCDMAFeatureCode(String FeatureCode, Message response); - - /** Set the Phone type created */ - void setPhoneType(int phoneType); - - /** - * Query the CDMA roaming preference setting - * - * @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 setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response); - - /** - * Requests to get the CDMA subscription srouce - * @param response is callback message - */ - void getCdmaSubscriptionSource(Message response); - - /** - * Set the TTY mode - * - * @param ttyMode one of the following: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * @param response is callback message - */ - void setTTYMode(int ttyMode, Message response); - - /** - * Query the TTY mode - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * tty mode: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * @param response is callback message - */ - void queryTTYMode(Message response); - - /** - * Setup a packet data connection On successful completion, the result - * message will return a {@link DataCallState} object containing the connection - * information. - * - * @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 authType - * the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_* - * @param protocol - * one of the PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - * @param result - * Callback message - */ - public void setupDataCall(String radioTechnology, String profile, - String apn, String user, String password, String authType, - String protocol, Message result); - - /** - * Deactivate packet data connection - * - * @param cid - * The connection ID - * @param reason - * Data disconnect reason. - * @param result - * Callback message is empty on completion - */ - public void deactivateDataCall(int cid, int reason, Message result); - - /** - * Activate or deactivate cell broadcast SMS for CDMA. - * - * @param activate - * true = activate, false = deactivate - * @param result - * Callback message is empty on completion - */ - public void setCdmaBroadcastActivation(boolean activate, Message result); - - /** - * Configure cdma cell broadcast SMS. - * - * @param result - * Callback message is empty on completion - */ - // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig - 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); - - /** - * Requests the radio's system selection module to exit emergency callback mode. - * This function should only be called from CDMAPHone.java. - * - * @param response callback message - */ - public void exitEmergencyCallbackMode(Message response); - - /** - * Request the status of the ICC and UICC cards. - * - * @param result - * Callback message containing {@link IccCardStatus} structure for the card. - */ - public void getIccCardStatus(Message result); - - /** - * Return if the current radio is LTE on CDMA. This - * is a tri-state return value as for a period of time - * the mode may be unknown. - * - * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} - * or {@link Phone#LTE_ON_CDMA_TRUE} - */ - public int getLteOnCdmaMode(); - - /** - * Request the ISIM application on the UICC to perform the AKA - * challenge/response algorithm for IMS authentication. The nonce string - * and challenge response are Base64 encoded Strings. - * - * @param nonce the nonce string to pass with the ISIM authentication request - * @param response a callback message with the String response in the obj field - */ - public void requestIsimAuthentication(String nonce, Message response); - - /** - * Notifiy that we are testing an emergency call - */ - public void testingEmergencyCall(); -} diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java deleted file mode 100644 index 021602fe2ab2..000000000000 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ /dev/null @@ -1,314 +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; -import android.util.Log; - -/** - * {@hide} - */ -public abstract class Connection { - - // Number presentation type for caller id display - public static int PRESENTATION_ALLOWED = 1; // normal - public static int PRESENTATION_RESTRICTED = 2; // block by user - public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network - public static int PRESENTATION_PAYPHONE = 4; // show pay phone info - - //Caller Name Display - protected String cnapName; - protected int cnapNamePresentation = PRESENTATION_ALLOWED; - - private static String LOG_TAG = "TelephonyConnection"; - - public enum DisconnectCause { - NOT_DISCONNECTED, /* has not yet disconnected */ - INCOMING_MISSED, /* an incoming call that was missed and never answered */ - NORMAL, /* normal; remote */ - LOCAL, /* normal; local hangup */ - BUSY, /* outgoing call to busy line */ - CONGESTION, /* outgoing call to congested network */ - MMI, /* not presently used; dial() returns null */ - INVALID_NUMBER, /* invalid dial string */ - NUMBER_UNREACHABLE, /* cannot reach the peer */ - SERVER_UNREACHABLE, /* cannot reach the server */ - INVALID_CREDENTIALS, /* invalid credentials */ - OUT_OF_NETWORK, /* calling from out of network is not allowed */ - SERVER_ERROR, /* server error */ - TIMED_OUT, /* client timed out */ - LOST_SIGNAL, - LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ - INCOMING_REJECTED, /* an incoming call that was rejected */ - POWER_OFF, /* radio is turned off explicitly */ - OUT_OF_SERVICE, /* out of service */ - ICC_ERROR, /* No ICC, ICC locked, or other ICC error */ - CALL_BARRED, /* call was blocked by call barring */ - FDN_BLOCKED, /* call was blocked by fixed dial number */ - CS_RESTRICTED, /* call was blocked by restricted all voice access */ - CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */ - CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */ - UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */ - CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */ - CDMA_DROP, - CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */ - CDMA_REORDER, /* MS has been redirected, call is cancelled */ - CDMA_SO_REJECT, /* service option rejection */ - CDMA_RETRY_ORDER, /* requested service is rejected, retry delay is set */ - CDMA_ACCESS_FAILURE, - CDMA_PREEMPTED, - CDMA_NOT_EMERGENCY, /* not an emergency call */ - CDMA_ACCESS_BLOCKED, /* Access Blocked by CDMA network */ - ERROR_UNSPECIFIED - } - - Object userData; - - /* Instance Methods */ - - /** - * Gets address (e.g. phone number) associated with connection. - * TODO: distinguish reasons for unavailability - * - * @return address or null if unavailable - */ - - public abstract String getAddress(); - - /** - * Gets CNAP name associated with connection. - * @return cnap name or null if unavailable - */ - public String getCnapName() { - return cnapName; - } - - /** - * Get original dial string. - * @return original dial string or null if unavailable - */ - public String getOrigDialString(){ - return null; - } - - /** - * Gets CNAP presentation associated with connection. - * @return cnap name or null if unavailable - */ - - public int getCnapNamePresentation() { - return cnapNamePresentation; - }; - - /** - * @return Call that owns this Connection, or null if none - */ - public abstract Call getCall(); - - /** - * Connection create time in currentTimeMillis() format - * Basically, set when object is created. - * Effectively, when an incoming call starts ringing or an - * outgoing call starts dialing - */ - public abstract long getCreateTime(); - - /** - * Connection connect time in currentTimeMillis() format. - * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. - * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. - * Returns 0 before then. - */ - public abstract long getConnectTime(); - - /** - * Disconnect time in currentTimeMillis() format. - * The time when this Connection makes a transition into ENDED or FAIL. - * Returns 0 before then. - */ - public abstract long getDisconnectTime(); - - /** - * 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. - */ - public abstract long getDurationMillis(); - - /** - * If this connection is HOLDING, return the number of milliseconds - * that it has been on hold for (approximately). - * If this connection is in any other state, return 0. - */ - - public abstract long getHoldDurationMillis(); - - /** - * Returns "NOT_DISCONNECTED" if not yet disconnected. - */ - public abstract DisconnectCause getDisconnectCause(); - - /** - * 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(); - - /** - * If this Connection is connected, then it is associated with - * a Call. - * - * Returns getCall().getState() or Call.State.IDLE if not - * connected - */ - public Call.State getState() { - Call c; - - c = getCall(); - - 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) - */ - public boolean - isAlive() { - return getState().isAlive(); - } - - /** - * Returns true if Connection is connected and is INCOMING or WAITING - */ - public boolean - isRinging() { - return getState().isRinging(); - } - - /** - * - * @return the userdata set in setUserData() - */ - public Object getUserData() { - return userData; - } - - /** - * - * @param userdata user can store an any userdata in the Connection object. - */ - public void setUserData(Object userdata) { - this.userData = userdata; - } - - /** - * Hangup individual Connection - */ - public abstract void hangup() throws CallStateException; - - /** - * Separate this call from its owner Call and assigns it to a new Call - * (eg if it is currently part of a Conference call - * TODO: Throw exception? Does GSM require error display on failure here? - */ - 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 - 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 - call to proceedAfterWaitChar() */ - 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 - with cancelPostDial() */ - PAUSE /* The post dial string playback is pausing for a - call to processNextPostDialChar*/ - } - - public void clearUserData(){ - userData = null; - } - - public abstract PostDialState getPostDialState(); - - /** - * Returns the portion of the post dial string that has not - * yet been dialed, or "" if none - */ - public abstract String getRemainingPostDialString(); - - /** - * See Phone.setOnPostDialWaitCharacter() - */ - - public abstract void proceedAfterWaitChar(); - - /** - * See Phone.setOnPostDialWildCharacter() - */ - public abstract void proceedAfterWildChar(String str); - /** - * Cancel any post - */ - public abstract void cancelPostDial(); - - /** - * Returns the caller id presentation type for incoming and waiting calls - * @return one of PRESENTATION_* - */ - public abstract int getNumberPresentation(); - - /** - * Returns the User to User Signaling (UUS) information associated with - * incoming and waiting calls - * @return UUSInfo containing the UUS userdata. - */ - public abstract UUSInfo getUUSInfo(); - - /** - * Build a human representation of a connection instance, suitable for debugging. - * Don't log personal stuff unless in debug mode. - * @return a string representing the internal state of this connection. - */ - public String toString() { - StringBuilder str = new StringBuilder(128); - - if (Log.isLoggable(LOG_TAG, Log.DEBUG)) { - str.append("addr: " + getAddress()) - .append(" pres.: " + getNumberPresentation()) - .append(" dial: " + getOrigDialString()) - .append(" postdial: " + getRemainingPostDialString()) - .append(" cnap name: " + getCnapName()) - .append("(" + getCnapNamePresentation() + ")"); - } - str.append(" incoming: " + isIncoming()) - .append(" state: " + getState()) - .append(" post dial state: " + getPostDialState()); - return str.toString(); - } -} diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java deleted file mode 100644 index efbf608d9020..000000000000 --- a/telephony/java/com/android/internal/telephony/DataCallState.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved. - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.NetworkUtils; -import android.net.RouteInfo; -import android.os.SystemProperties; -import android.util.Log; - -import com.android.internal.telephony.DataConnection.FailCause; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * This is RIL_Data_Call_Response_v5 from ril.h - * TODO: Rename to DataCallResponse. - */ -public class DataCallState { - private final boolean DBG = true; - private final String LOG_TAG = "GSM"; - - public int version = 0; - public int status = 0; - public int cid = 0; - public int active = 0; - public String type = ""; - public String ifname = ""; - public String [] addresses = new String[0]; - public String [] dnses = new String[0]; - public String[] gateways = new String[0]; - public int suggestedRetryTime = -1; - - /** - * Class returned by onSetupConnectionCompleted. - */ - public enum SetupResult { - SUCCESS, - ERR_BadCommand, - ERR_UnacceptableParameter, - ERR_GetLastErrorFromRil, - ERR_Stale, - ERR_RilError; - - public FailCause mFailCause; - - SetupResult() { - mFailCause = FailCause.fromInt(0); - } - - @Override - public String toString() { - return name() + " SetupResult.mFailCause=" + mFailCause; - } - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("DataCallState: {") - .append("version=").append(version) - .append(" status=").append(status) - .append(" retry=").append(suggestedRetryTime) - .append(" cid=").append(cid) - .append(" active=").append(active) - .append(" type=").append(type) - .append("' ifname='").append(ifname); - sb.append("' addresses=["); - for (String addr : addresses) { - sb.append(addr); - sb.append(","); - } - if (addresses.length > 0) sb.deleteCharAt(sb.length()-1); - sb.append("] dnses=["); - for (String addr : dnses) { - sb.append(addr); - sb.append(","); - } - if (dnses.length > 0) sb.deleteCharAt(sb.length()-1); - sb.append("] gateways=["); - for (String addr : gateways) { - sb.append(addr); - sb.append(","); - } - if (gateways.length > 0) sb.deleteCharAt(sb.length()-1); - sb.append("]}"); - return sb.toString(); - } - - public SetupResult setLinkProperties(LinkProperties linkProperties, - boolean okToUseSystemPropertyDns) { - SetupResult result; - - // Start with clean network properties and if we have - // a failure we'll clear again at the bottom of this code. - if (linkProperties == null) - linkProperties = new LinkProperties(); - else - linkProperties.clear(); - - if (status == FailCause.NONE.getErrorCode()) { - String propertyPrefix = "net." + ifname + "."; - - try { - // set interface name - linkProperties.setInterfaceName(ifname); - - // set link addresses - if (addresses != null && addresses.length > 0) { - for (String addr : addresses) { - addr = addr.trim(); - if (addr.isEmpty()) continue; - LinkAddress la; - int addrPrefixLen; - - String [] ap = addr.split("/"); - if (ap.length == 2) { - addr = ap[0]; - addrPrefixLen = Integer.parseInt(ap[1]); - } else { - addrPrefixLen = 0; - } - InetAddress ia; - try { - ia = NetworkUtils.numericToInetAddress(addr); - } catch (IllegalArgumentException e) { - throw new UnknownHostException("Non-numeric ip addr=" + addr); - } - if (! ia.isAnyLocalAddress()) { - if (addrPrefixLen == 0) { - // Assume point to point - addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128; - } - if (DBG) Log.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen); - la = new LinkAddress(ia, addrPrefixLen); - linkProperties.addLinkAddress(la); - } - } - } else { - throw new UnknownHostException("no address for ifname=" + ifname); - } - - // set dns servers - if (dnses != null && dnses.length > 0) { - for (String addr : dnses) { - addr = addr.trim(); - if (addr.isEmpty()) continue; - InetAddress ia; - try { - ia = NetworkUtils.numericToInetAddress(addr); - } catch (IllegalArgumentException e) { - throw new UnknownHostException("Non-numeric dns addr=" + addr); - } - if (! ia.isAnyLocalAddress()) { - linkProperties.addDns(ia); - } - } - } else if (okToUseSystemPropertyDns){ - String dnsServers[] = new String[2]; - dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); - dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); - for (String dnsAddr : dnsServers) { - dnsAddr = dnsAddr.trim(); - if (dnsAddr.isEmpty()) continue; - InetAddress ia; - try { - ia = NetworkUtils.numericToInetAddress(dnsAddr); - } catch (IllegalArgumentException e) { - throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr); - } - if (! ia.isAnyLocalAddress()) { - linkProperties.addDns(ia); - } - } - } else { - throw new UnknownHostException("Empty dns response and no system default dns"); - } - - // set gateways - if ((gateways == null) || (gateways.length == 0)) { - String sysGateways = SystemProperties.get(propertyPrefix + "gw"); - if (sysGateways != null) { - gateways = sysGateways.split(" "); - } else { - gateways = new String[0]; - } - } - for (String addr : gateways) { - addr = addr.trim(); - if (addr.isEmpty()) continue; - InetAddress ia; - try { - ia = NetworkUtils.numericToInetAddress(addr); - } catch (IllegalArgumentException e) { - throw new UnknownHostException("Non-numeric gateway addr=" + addr); - } - if (! ia.isAnyLocalAddress()) { - linkProperties.addRoute(new RouteInfo(ia)); - } - } - - result = SetupResult.SUCCESS; - } catch (UnknownHostException e) { - Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e); - e.printStackTrace(); - result = SetupResult.ERR_UnacceptableParameter; - } - } else { - if (version < 4) { - result = SetupResult.ERR_GetLastErrorFromRil; - } else { - result = SetupResult.ERR_RilError; - } - } - - // An error occurred so clear properties - if (result != SetupResult.SUCCESS) { - if(DBG) { - Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " + - "status=" + status + " result=" + result); - } - linkProperties.clear(); - } - - return result; - } -} diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java deleted file mode 100644 index a6bd85ea701f..000000000000 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ /dev/null @@ -1,1277 +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; - - -import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Protocol; -import com.android.internal.util.State; -import com.android.internal.util.StateMachine; - -import android.app.PendingIntent; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.net.ProxyProperties; -import android.os.AsyncResult; -import android.os.Message; -import android.os.SystemProperties; -import android.text.TextUtils; -import android.util.TimeUtils; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * {@hide} - * - * DataConnection StateMachine. - * - * This is an abstract base class for representing a single data connection. - * Instances of this class such as CdmaDataConnection and - * GsmDataConnection, * represent a connection via the cellular network. - * There may be multiple data connections and all of them are managed by the - * DataConnectionTracker. - * - * Instances are asynchronous state machines and have two primary entry points - * connect() and disconnect. The message a parameter will be returned - * hen the operation completes. The msg.obj will contain an AsyncResult - * object and AsyncResult.userObj is the original msg.obj. if successful - * with the AsyncResult.result == null and AsyncResult.exception == null. - * If an error AsyncResult.result = FailCause and - * AsyncResult.exception = new Exception(). - * - * The other public methods are provided for debugging. - */ -public abstract class DataConnection extends StateMachine { - protected static final boolean DBG = true; - protected static final boolean VDBG = false; - - protected static AtomicInteger mCount = new AtomicInteger(0); - protected AsyncChannel mAc; - - protected List mApnList = null; - PendingIntent mReconnectIntent = null; - - private DataConnectionTracker mDataConnectionTracker = null; - - /** - * Used internally for saving connecting parameters. - */ - protected static class ConnectionParams { - public ConnectionParams(ApnSetting apn, Message onCompletedMsg) { - this.apn = apn; - this.onCompletedMsg = onCompletedMsg; - } - - public int tag; - public ApnSetting apn; - public Message onCompletedMsg; - } - - /** - * Used internally for saving disconnecting parameters. - */ - protected static class DisconnectParams { - public DisconnectParams(String reason, Message onCompletedMsg) { - this.reason = reason; - this.onCompletedMsg = onCompletedMsg; - } - public int tag; - public String reason; - public Message onCompletedMsg; - } - - /** - * Returned as the reason for a connection failure as defined - * by RIL_DataCallFailCause in ril.h and some local errors. - */ - public enum FailCause { - NONE(0), - - // This series of errors as specified by the standards - // specified in ril.h - OPERATOR_BARRED(0x08), - INSUFFICIENT_RESOURCES(0x1A), - MISSING_UNKNOWN_APN(0x1B), - UNKNOWN_PDP_ADDRESS_TYPE(0x1C), - USER_AUTHENTICATION(0x1D), - ACTIVATION_REJECT_GGSN(0x1E), - ACTIVATION_REJECT_UNSPECIFIED(0x1F), - SERVICE_OPTION_NOT_SUPPORTED(0x20), - SERVICE_OPTION_NOT_SUBSCRIBED(0x21), - SERVICE_OPTION_OUT_OF_ORDER(0x22), - NSAPI_IN_USE(0x23), - ONLY_IPV4_ALLOWED(0x32), - ONLY_IPV6_ALLOWED(0x33), - ONLY_SINGLE_BEARER_ALLOWED(0x34), - PROTOCOL_ERRORS(0x6F), - - // Local errors generated by Vendor RIL - // specified in ril.h - REGISTRATION_FAIL(-1), - GPRS_REGISTRATION_FAIL(-2), - SIGNAL_LOST(-3), - PREF_RADIO_TECH_CHANGED(-4), - RADIO_POWER_OFF(-5), - TETHERED_CALL_ACTIVE(-6), - ERROR_UNSPECIFIED(0xFFFF), - - // Errors generated by the Framework - // specified here - UNKNOWN(0x10000), - RADIO_NOT_AVAILABLE(0x10001), - UNACCEPTABLE_NETWORK_PARAMETER(0x10002), - CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003); - - private final int mErrorCode; - private static final HashMap sErrorCodeToFailCauseMap; - static { - sErrorCodeToFailCauseMap = new HashMap(); - for (FailCause fc : values()) { - sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc); - } - } - - FailCause(int errorCode) { - mErrorCode = errorCode; - } - - int getErrorCode() { - return mErrorCode; - } - - public boolean isPermanentFail() { - return (this == OPERATOR_BARRED) || (this == MISSING_UNKNOWN_APN) || - (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) || - (this == SERVICE_OPTION_NOT_SUPPORTED) || - (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) || - (this == PROTOCOL_ERRORS); - } - - public boolean isEventLoggable() { - return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) || - (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) || - (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) || - (this == SERVICE_OPTION_NOT_SUBSCRIBED) || - (this == SERVICE_OPTION_NOT_SUPPORTED) || - (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) || - (this == PROTOCOL_ERRORS) || - (this == UNACCEPTABLE_NETWORK_PARAMETER); - } - - public static FailCause fromInt(int errorCode) { - FailCause fc = sErrorCodeToFailCauseMap.get(errorCode); - if (fc == null) { - fc = UNKNOWN; - } - return fc; - } - } - - public static class CallSetupException extends Exception { - private int mRetryOverride = -1; - - CallSetupException (int retryOverride) { - mRetryOverride = retryOverride; - } - - public int getRetryOverride() { - return mRetryOverride; - } - } - - // ***** Event codes for driving the state machine - protected static final int BASE = Protocol.BASE_DATA_CONNECTION; - protected static final int EVENT_CONNECT = BASE + 0; - protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1; - protected static final int EVENT_GET_LAST_FAIL_DONE = BASE + 2; - protected static final int EVENT_DEACTIVATE_DONE = BASE + 3; - protected static final int EVENT_DISCONNECT = BASE + 4; - protected static final int EVENT_RIL_CONNECTED = BASE + 5; - protected static final int EVENT_DISCONNECT_ALL = BASE + 6; - - private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL - BASE + 1; - private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; - static { - sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT"; - sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] = - "EVENT_SETUP_DATA_CONNECTION_DONE"; - sCmdToString[EVENT_GET_LAST_FAIL_DONE - BASE] = "EVENT_GET_LAST_FAIL_DONE"; - sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE"; - sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT"; - sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED"; - sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL"; - } - protected static String cmdToString(int cmd) { - cmd -= BASE; - if ((cmd >= 0) && (cmd < sCmdToString.length)) { - return sCmdToString[cmd]; - } else { - return null; - } - } - - //***** Tag IDs for EventLog - protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100; - - //***** Member Variables - protected ApnSetting mApn; - protected int mTag; - protected PhoneBase phone; - protected int mRilVersion = -1; - protected int cid; - protected LinkProperties mLinkProperties = new LinkProperties(); - protected LinkCapabilities mCapabilities = new LinkCapabilities(); - protected long createTime; - protected long lastFailTime; - protected FailCause lastFailCause; - protected int mRetryOverride = -1; - protected static final String NULL_IP = "0.0.0.0"; - protected int mRefCount; - Object userData; - - //***** Abstract methods - @Override - public abstract String toString(); - - protected abstract void onConnect(ConnectionParams cp); - - protected abstract boolean isDnsOk(String[] domainNameServers); - - protected abstract void log(String s); - - //***** Constructor - protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm, - DataConnectionTracker dct) { - super(name); - setLogRecSize(100); - if (DBG) log("DataConnection constructor E"); - this.phone = phone; - this.mDataConnectionTracker = dct; - mId = id; - mRetryMgr = rm; - this.cid = -1; - - setDbg(false); - addState(mDefaultState); - addState(mInactiveState, mDefaultState); - addState(mActivatingState, mDefaultState); - addState(mActiveState, mDefaultState); - addState(mDisconnectingState, mDefaultState); - addState(mDisconnectingErrorCreatingConnection, mDefaultState); - setInitialState(mInactiveState); - - mApnList = new ArrayList(); - if (DBG) log("DataConnection constructor X"); - } - - /** - * Shut down this instance and its state machine. - */ - private void shutDown() { - if (DBG) log("shutDown"); - - if (mAc != null) { - mAc.disconnected(); - mAc = null; - } - mApnList = null; - mReconnectIntent = null; - mDataConnectionTracker = null; - mApn = null; - phone = null; - mLinkProperties = null; - mCapabilities = null; - lastFailCause = null; - userData = null; - } - - /** - * TearDown the data connection. - * - * @param o will be returned in AsyncResult.userObj - * and is either a DisconnectParams or ConnectionParams. - */ - private void tearDownData(Object o) { - int discReason = RILConstants.DEACTIVATE_REASON_NONE; - if ((o != null) && (o instanceof DisconnectParams)) { - DisconnectParams dp = (DisconnectParams)o; - Message m = dp.onCompletedMsg; - if (TextUtils.equals(dp.reason, Phone.REASON_RADIO_TURNED_OFF)) { - discReason = RILConstants.DEACTIVATE_REASON_RADIO_OFF; - } else if (TextUtils.equals(dp.reason, Phone.REASON_PDP_RESET)) { - discReason = RILConstants.DEACTIVATE_REASON_PDP_RESET; - } - } - if (phone.mCM.getRadioState().isOn()) { - if (DBG) log("tearDownData radio is on, call deactivateDataCall"); - phone.mCM.deactivateDataCall(cid, discReason, obtainMessage(EVENT_DEACTIVATE_DONE, o)); - } else { - if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately"); - AsyncResult ar = new AsyncResult(o, null, null); - sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, ar)); - } - } - - /** - * Send the connectionCompletedMsg. - * - * @param cp is the ConnectionParams - * @param cause - */ - private void notifyConnectCompleted(ConnectionParams cp, FailCause cause) { - Message connectionCompletedMsg = cp.onCompletedMsg; - if (connectionCompletedMsg == null) { - return; - } - - long timeStamp = System.currentTimeMillis(); - connectionCompletedMsg.arg1 = cid; - - if (cause == FailCause.NONE) { - createTime = timeStamp; - AsyncResult.forMessage(connectionCompletedMsg); - } else { - lastFailCause = cause; - lastFailTime = timeStamp; - AsyncResult.forMessage(connectionCompletedMsg, cause, - new CallSetupException(mRetryOverride)); - } - if (DBG) log("notifyConnectionCompleted at " + timeStamp + " cause=" + cause); - - connectionCompletedMsg.sendToTarget(); - } - - /** - * Send ar.userObj if its a message, which is should be back to originator. - * - * @param dp is the DisconnectParams. - */ - private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { - if (VDBG) log("NotifyDisconnectCompleted"); - - ApnContext alreadySent = null; - String reason = null; - - if (dp.onCompletedMsg != null) { - // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices. - Message msg = dp.onCompletedMsg; - if (msg.obj instanceof ApnContext) { - alreadySent = (ApnContext)msg.obj; - } - reason = dp.reason; - if (VDBG) { - log(String.format("msg=%s msg.obj=%s", msg.toString(), - ((msg.obj instanceof String) ? (String) msg.obj : ""))); - } - AsyncResult.forMessage(msg); - msg.sendToTarget(); - } - if (sendAll) { - for (ApnContext a : mApnList) { - if (a == alreadySent) continue; - if (reason != null) a.setReason(reason); - Message msg = mDataConnectionTracker.obtainMessage( - DataConnectionTracker.EVENT_DISCONNECT_DONE, a); - AsyncResult.forMessage(msg); - msg.sendToTarget(); - } - } - - if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); - } - - protected int getRilRadioTechnology(int defaultRilRadioTechnology) { - int rilRadioTechnology; - if (mRilVersion < 6) { - rilRadioTechnology = defaultRilRadioTechnology; - } else { - rilRadioTechnology = phone.getServiceState().getRilRadioTechnology() + 2; - } - return rilRadioTechnology; - } - - /* - * ************************************************************************** - * Begin Members and methods owned by DataConnectionTracker but stored - * in a DataConnection because there is one per connection. - * ************************************************************************** - */ - - /* - * The id is owned by DataConnectionTracker. - */ - private int mId; - - /** - * Get the DataConnection ID - */ - public int getDataConnectionId() { - return mId; - } - - /* - * The retry manager is currently owned by the DataConnectionTracker but is stored - * in the DataConnection because there is one per connection. These methods - * should only be used by the DataConnectionTracker although someday the retrying - * maybe managed by the DataConnection itself and these methods could disappear. - */ - private RetryManager mRetryMgr; - - /** - * @return retry manager retryCount - */ - public int getRetryCount() { - return mRetryMgr.getRetryCount(); - } - - /** - * @return retry manager retryTimer - */ - public int getRetryTimer() { - return mRetryMgr.getRetryTimer(); - } - - /** - * increaseRetryCount of retry manager - */ - public void increaseRetryCount() { - mRetryMgr.increaseRetryCount(); - } - - /** - * @return retry manager isRetryNeeded - */ - public boolean isRetryNeeded() { - return mRetryMgr.isRetryNeeded(); - } - - /** - * resetRetryCount of retry manager - */ - public void resetRetryCount() { - mRetryMgr.resetRetryCount(); - } - - /** - * set retryForeverUsingLasttimeout of retry manager - */ - public void retryForeverUsingLastTimeout() { - mRetryMgr.retryForeverUsingLastTimeout(); - } - - /** - * @return retry manager isRetryForever - */ - public boolean isRetryForever() { - return mRetryMgr.isRetryForever(); - } - - /** - * @return whether the retry config is set successfully or not - */ - public boolean configureRetry(int maxRetryCount, int retryTime, int randomizationTime) { - return mRetryMgr.configure(maxRetryCount, retryTime, randomizationTime); - } - - /** - * @return whether the retry config is set successfully or not - */ - public boolean configureRetry(String configStr) { - return mRetryMgr.configure(configStr); - } - - /* - * ************************************************************************** - * End members owned by DataConnectionTracker - * ************************************************************************** - */ - - /** - * Clear all settings called when entering mInactiveState. - */ - protected void clearSettings() { - if (DBG) log("clearSettings"); - - createTime = -1; - lastFailTime = -1; - lastFailCause = FailCause.NONE; - mRetryOverride = -1; - mRefCount = 0; - cid = -1; - - mLinkProperties = new LinkProperties(); - mApn = null; - } - - /** - * Process setup completion. - * - * @param ar is the result - * @return SetupResult. - */ - private DataCallState.SetupResult onSetupConnectionCompleted(AsyncResult ar) { - DataCallState response = (DataCallState) ar.result; - ConnectionParams cp = (ConnectionParams) ar.userObj; - DataCallState.SetupResult result; - - if (ar.exception != null) { - if (DBG) { - log("onSetupConnectionCompleted failed, ar.exception=" + ar.exception + - " response=" + response); - } - - if (ar.exception instanceof CommandException - && ((CommandException) (ar.exception)).getCommandError() - == CommandException.Error.RADIO_NOT_AVAILABLE) { - result = DataCallState.SetupResult.ERR_BadCommand; - result.mFailCause = FailCause.RADIO_NOT_AVAILABLE; - } else if ((response == null) || (response.version < 4)) { - result = DataCallState.SetupResult.ERR_GetLastErrorFromRil; - } else { - result = DataCallState.SetupResult.ERR_RilError; - result.mFailCause = FailCause.fromInt(response.status); - } - } else if (cp.tag != mTag) { - if (DBG) { - log("BUG: onSetupConnectionCompleted is stale cp.tag=" + cp.tag + ", mtag=" + mTag); - } - result = DataCallState.SetupResult.ERR_Stale; - } else if (response.status != 0) { - result = DataCallState.SetupResult.ERR_RilError; - result.mFailCause = FailCause.fromInt(response.status); - } else { - if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response); - cid = response.cid; - result = updateLinkProperty(response).setupResult; - } - - return result; - } - - private int getSuggestedRetryTime(AsyncResult ar) { - int retry = -1; - if (ar.exception == null) { - DataCallState response = (DataCallState) ar.result; - retry = response.suggestedRetryTime; - } - return retry; - } - - private DataCallState.SetupResult setLinkProperties(DataCallState response, - LinkProperties lp) { - // Check if system property dns usable - boolean okToUseSystemPropertyDns = false; - String propertyPrefix = "net." + response.ifname + "."; - String dnsServers[] = new String[2]; - dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); - dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); - okToUseSystemPropertyDns = isDnsOk(dnsServers); - - // set link properties based on data call response - return response.setLinkProperties(lp, okToUseSystemPropertyDns); - } - - public static class UpdateLinkPropertyResult { - public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS; - public LinkProperties oldLp; - public LinkProperties newLp; - public UpdateLinkPropertyResult(LinkProperties curLp) { - oldLp = curLp; - newLp = curLp; - } - } - - private UpdateLinkPropertyResult updateLinkProperty(DataCallState newState) { - UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties); - - if (newState == null) return result; - - DataCallState.SetupResult setupResult; - result.newLp = new LinkProperties(); - - // set link properties based on data call response - result.setupResult = setLinkProperties(newState, result.newLp); - if (result.setupResult != DataCallState.SetupResult.SUCCESS) { - if (DBG) log("updateLinkProperty failed : " + result.setupResult); - return result; - } - // copy HTTP proxy as it is not part DataCallState. - result.newLp.setHttpProxy(mLinkProperties.getHttpProxy()); - - if (DBG && (! result.oldLp.equals(result.newLp))) { - log("updateLinkProperty old LP=" + result.oldLp); - log("updateLinkProperty new LP=" + result.newLp); - } - mLinkProperties = result.newLp; - - return result; - } - - /** - * The parent state for all other states. - */ - private class DcDefaultState extends State { - @Override - public void enter() { - phone.mCM.registerForRilConnected(getHandler(), EVENT_RIL_CONNECTED, null); - } - @Override - public void exit() { - phone.mCM.unregisterForRilConnected(getHandler()); - shutDown(); - } - @Override - public boolean processMessage(Message msg) { - boolean retVal = HANDLED; - AsyncResult ar; - - switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { - if (mAc != null) { - if (VDBG) log("Disconnecting to previous connection mAc=" + mAc); - mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, - AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED); - } else { - mAc = new AsyncChannel(); - mAc.connected(null, getHandler(), msg.replyTo); - if (VDBG) log("DcDefaultState: FULL_CONNECTION reply connected"); - mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, - AsyncChannel.STATUS_SUCCESSFUL, mId, "hi"); - } - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { - if (VDBG) log("CMD_CHANNEL_DISCONNECTED"); - quit(); - break; - } - case DataConnectionAc.REQ_IS_INACTIVE: { - boolean val = getCurrentState() == mInactiveState; - if (VDBG) log("REQ_IS_INACTIVE isInactive=" + val); - mAc.replyToMessage(msg, DataConnectionAc.RSP_IS_INACTIVE, val ? 1 : 0); - break; - } - case DataConnectionAc.REQ_GET_CID: { - if (VDBG) log("REQ_GET_CID cid=" + cid); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_CID, cid); - break; - } - case DataConnectionAc.REQ_GET_APNSETTING: { - if (VDBG) log("REQ_GET_APNSETTING apnSetting=" + mApn); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNSETTING, mApn); - break; - } - case DataConnectionAc.REQ_GET_LINK_PROPERTIES: { - LinkProperties lp = new LinkProperties(mLinkProperties); - if (VDBG) log("REQ_GET_LINK_PROPERTIES linkProperties" + lp); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_PROPERTIES, lp); - break; - } - case DataConnectionAc.REQ_SET_LINK_PROPERTIES_HTTP_PROXY: { - ProxyProperties proxy = (ProxyProperties) msg.obj; - if (VDBG) log("REQ_SET_LINK_PROPERTIES_HTTP_PROXY proxy=" + proxy); - mLinkProperties.setHttpProxy(proxy); - mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY); - break; - } - case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: { - DataCallState newState = (DataCallState) msg.obj; - UpdateLinkPropertyResult result = - updateLinkProperty(newState); - if (VDBG) { - log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result=" - + result + " newState=" + newState); - } - mAc.replyToMessage(msg, - DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, - result); - break; - } - case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: { - LinkCapabilities lc = new LinkCapabilities(mCapabilities); - if (VDBG) log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc); - break; - } - case DataConnectionAc.REQ_RESET: - if (VDBG) log("DcDefaultState: msg.what=REQ_RESET"); - mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET); - transitionTo(mInactiveState); - break; - case DataConnectionAc.REQ_GET_REFCOUNT: { - if (VDBG) log("REQ_GET_REFCOUNT refCount=" + mRefCount); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_REFCOUNT, mRefCount); - break; - } - case DataConnectionAc.REQ_ADD_APNCONTEXT: { - ApnContext apnContext = (ApnContext) msg.obj; - if (VDBG) log("REQ_ADD_APNCONTEXT apn=" + apnContext.getApnType()); - if (!mApnList.contains(apnContext)) { - mApnList.add(apnContext); - } - mAc.replyToMessage(msg, DataConnectionAc.RSP_ADD_APNCONTEXT); - break; - } - case DataConnectionAc.REQ_REMOVE_APNCONTEXT: { - ApnContext apnContext = (ApnContext) msg.obj; - if (VDBG) log("REQ_REMOVE_APNCONTEXT apn=" + apnContext.getApnType()); - mApnList.remove(apnContext); - mAc.replyToMessage(msg, DataConnectionAc.RSP_REMOVE_APNCONTEXT); - break; - } - case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: { - if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size()); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST, - new ArrayList(mApnList)); - break; - } - case DataConnectionAc.REQ_SET_RECONNECT_INTENT: { - PendingIntent intent = (PendingIntent) msg.obj; - if (VDBG) log("REQ_SET_RECONNECT_INTENT"); - mReconnectIntent = intent; - mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_RECONNECT_INTENT); - break; - } - case DataConnectionAc.REQ_GET_RECONNECT_INTENT: { - if (VDBG) log("REQ_GET_RECONNECT_INTENT"); - mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_RECONNECT_INTENT, - mReconnectIntent); - break; - } - case EVENT_CONNECT: - if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected"); - ConnectionParams cp = (ConnectionParams) msg.obj; - notifyConnectCompleted(cp, FailCause.UNKNOWN); - break; - - case EVENT_DISCONNECT: - if (DBG) { - log("DcDefaultState deferring msg.what=EVENT_DISCONNECT" + mRefCount); - } - deferMessage(msg); - break; - - case EVENT_DISCONNECT_ALL: - if (DBG) { - log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount); - } - deferMessage(msg); - break; - - case EVENT_RIL_CONNECTED: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - mRilVersion = (Integer)ar.result; - if (DBG) { - log("DcDefaultState: msg.what=EVENT_RIL_CONNECTED mRilVersion=" + - mRilVersion); - } - } else { - log("Unexpected exception on EVENT_RIL_CONNECTED"); - mRilVersion = -1; - } - break; - - default: - if (DBG) { - log("DcDefaultState: shouldn't happen but ignore msg.what=0x" + - Integer.toHexString(msg.what)); - } - break; - } - - return retVal; - } - } - private DcDefaultState mDefaultState = new DcDefaultState(); - - /** - * The state machine is inactive and expects a EVENT_CONNECT. - */ - private class DcInactiveState extends State { - private ConnectionParams mConnectionParams = null; - private FailCause mFailCause = null; - private DisconnectParams mDisconnectParams = null; - - public void setEnterNotificationParams(ConnectionParams cp, FailCause cause, - int retryOverride) { - if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause"); - mConnectionParams = cp; - mFailCause = cause; - mRetryOverride = retryOverride; - } - - public void setEnterNotificationParams(DisconnectParams dp) { - if (VDBG) log("DcInactiveState: setEnterNoticationParams dp"); - mDisconnectParams = dp; - } - - @Override - public void enter() { - mTag += 1; - - /** - * Now that we've transitioned to Inactive state we - * can send notifications. Previously we sent the - * notifications in the processMessage handler but - * that caused a race condition because the synchronous - * call to isInactive. - */ - if ((mConnectionParams != null) && (mFailCause != null)) { - if (VDBG) log("DcInactiveState: enter notifyConnectCompleted"); - notifyConnectCompleted(mConnectionParams, mFailCause); - } - if (mDisconnectParams != null) { - if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted"); - notifyDisconnectCompleted(mDisconnectParams, true); - } - clearSettings(); - } - - @Override - public void exit() { - // clear notifications - mConnectionParams = null; - mFailCause = null; - mDisconnectParams = null; - } - - @Override - public boolean processMessage(Message msg) { - boolean retVal; - - switch (msg.what) { - case DataConnectionAc.REQ_RESET: - if (DBG) { - log("DcInactiveState: msg.what=RSP_RESET, ignore we're already reset"); - } - mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET); - retVal = HANDLED; - break; - - case EVENT_CONNECT: - ConnectionParams cp = (ConnectionParams) msg.obj; - cp.tag = mTag; - if (DBG) { - log("DcInactiveState msg.what=EVENT_CONNECT." + "RefCount = " - + mRefCount); - } - mRefCount = 1; - onConnect(cp); - transitionTo(mActivatingState); - retVal = HANDLED; - break; - - case EVENT_DISCONNECT: - if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); - notifyDisconnectCompleted((DisconnectParams)msg.obj, false); - retVal = HANDLED; - break; - - case EVENT_DISCONNECT_ALL: - if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); - notifyDisconnectCompleted((DisconnectParams)msg.obj, false); - retVal = HANDLED; - break; - - default: - if (VDBG) { - log("DcInactiveState nothandled msg.what=0x" + - Integer.toHexString(msg.what)); - } - retVal = NOT_HANDLED; - break; - } - return retVal; - } - } - private DcInactiveState mInactiveState = new DcInactiveState(); - - /** - * The state machine is activating a connection. - */ - private class DcActivatingState extends State { - @Override - public boolean processMessage(Message msg) { - boolean retVal; - AsyncResult ar; - ConnectionParams cp; - - switch (msg.what) { - case EVENT_CONNECT: - if (DBG) log("DcActivatingState deferring msg.what=EVENT_CONNECT refCount = " - + mRefCount); - deferMessage(msg); - retVal = HANDLED; - break; - - case EVENT_SETUP_DATA_CONNECTION_DONE: - if (DBG) log("DcActivatingState msg.what=EVENT_SETUP_DATA_CONNECTION_DONE"); - - ar = (AsyncResult) msg.obj; - cp = (ConnectionParams) ar.userObj; - - DataCallState.SetupResult result = onSetupConnectionCompleted(ar); - if (DBG) log("DcActivatingState onSetupConnectionCompleted result=" + result); - switch (result) { - case SUCCESS: - // All is well - mActiveState.setEnterNotificationParams(cp, FailCause.NONE); - transitionTo(mActiveState); - break; - case ERR_BadCommand: - // Vendor ril rejected the command and didn't connect. - // Transition to inactive but send notifications after - // we've entered the mInactive state. - mInactiveState.setEnterNotificationParams(cp, result.mFailCause, -1); - transitionTo(mInactiveState); - break; - case ERR_UnacceptableParameter: - // The addresses given from the RIL are bad - tearDownData(cp); - transitionTo(mDisconnectingErrorCreatingConnection); - break; - case ERR_GetLastErrorFromRil: - // Request failed and this is an old RIL - phone.mCM.getLastDataCallFailCause( - obtainMessage(EVENT_GET_LAST_FAIL_DONE, cp)); - break; - case ERR_RilError: - // Request failed and mFailCause has the reason - mInactiveState.setEnterNotificationParams(cp, result.mFailCause, - getSuggestedRetryTime(ar)); - transitionTo(mInactiveState); - break; - case ERR_Stale: - // Request is stale, ignore. - break; - default: - throw new RuntimeException("Unknown SetupResult, should not happen"); - } - retVal = HANDLED; - break; - - case EVENT_GET_LAST_FAIL_DONE: - ar = (AsyncResult) msg.obj; - cp = (ConnectionParams) ar.userObj; - FailCause cause = FailCause.UNKNOWN; - - if (cp.tag == mTag) { - if (DBG) log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE"); - if (ar.exception == null) { - int rilFailCause = ((int[]) (ar.result))[0]; - cause = FailCause.fromInt(rilFailCause); - } - // Transition to inactive but send notifications after - // we've entered the mInactive state. - mInactiveState.setEnterNotificationParams(cp, cause, -1); - transitionTo(mInactiveState); - } else { - if (DBG) { - log("DcActivatingState EVENT_GET_LAST_FAIL_DONE is stale cp.tag=" - + cp.tag + ", mTag=" + mTag); - } - } - - retVal = HANDLED; - break; - - default: - if (VDBG) { - log("DcActivatingState not handled msg.what=0x" + - Integer.toHexString(msg.what)); - } - retVal = NOT_HANDLED; - break; - } - return retVal; - } - } - private DcActivatingState mActivatingState = new DcActivatingState(); - - /** - * The state machine is connected, expecting an EVENT_DISCONNECT. - */ - private class DcActiveState extends State { - private ConnectionParams mConnectionParams = null; - private FailCause mFailCause = null; - - public void setEnterNotificationParams(ConnectionParams cp, FailCause cause) { - if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause"); - mConnectionParams = cp; - mFailCause = cause; - } - - @Override public void enter() { - /** - * Now that we've transitioned to Active state we - * can send notifications. Previously we sent the - * notifications in the processMessage handler but - * that caused a race condition because the synchronous - * call to isActive. - */ - if ((mConnectionParams != null) && (mFailCause != null)) { - if (VDBG) log("DcActiveState: enter notifyConnectCompleted"); - notifyConnectCompleted(mConnectionParams, mFailCause); - } - } - - @Override - public void exit() { - // clear notifications - mConnectionParams = null; - mFailCause = null; - } - - @Override - public boolean processMessage(Message msg) { - boolean retVal; - - switch (msg.what) { - case EVENT_CONNECT: - mRefCount++; - if (DBG) log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mRefCount); - if (msg.obj != null) { - notifyConnectCompleted((ConnectionParams) msg.obj, FailCause.NONE); - } - retVal = HANDLED; - break; - case EVENT_DISCONNECT: - mRefCount--; - if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mRefCount); - if (mRefCount == 0) - { - DisconnectParams dp = (DisconnectParams) msg.obj; - dp.tag = mTag; - tearDownData(dp); - transitionTo(mDisconnectingState); - } else { - if (msg.obj != null) { - notifyDisconnectCompleted((DisconnectParams) msg.obj, false); - } - } - retVal = HANDLED; - break; - - case EVENT_DISCONNECT_ALL: - if (DBG) { - log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount); - } - mRefCount = 0; - DisconnectParams dp = (DisconnectParams) msg.obj; - dp.tag = mTag; - tearDownData(dp); - transitionTo(mDisconnectingState); - retVal = HANDLED; - break; - - default: - if (VDBG) { - log("DcActiveState not handled msg.what=0x" + - Integer.toHexString(msg.what)); - } - retVal = NOT_HANDLED; - break; - } - return retVal; - } - } - private DcActiveState mActiveState = new DcActiveState(); - - /** - * The state machine is disconnecting. - */ - private class DcDisconnectingState extends State { - @Override - public boolean processMessage(Message msg) { - boolean retVal; - - switch (msg.what) { - case EVENT_CONNECT: - if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = " - + mRefCount); - deferMessage(msg); - retVal = HANDLED; - break; - - case EVENT_DEACTIVATE_DONE: - if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE"); - AsyncResult ar = (AsyncResult) msg.obj; - DisconnectParams dp = (DisconnectParams) ar.userObj; - if (dp.tag == mTag) { - // Transition to inactive but send notifications after - // we've entered the mInactive state. - mInactiveState.setEnterNotificationParams((DisconnectParams) ar.userObj); - transitionTo(mInactiveState); - } else { - if (DBG) log("DcDisconnectState EVENT_DEACTIVATE_DONE stale dp.tag=" - + dp.tag + " mTag=" + mTag); - } - retVal = HANDLED; - break; - - default: - if (VDBG) { - log("DcDisconnectingState not handled msg.what=0x" + - Integer.toHexString(msg.what)); - } - retVal = NOT_HANDLED; - break; - } - return retVal; - } - } - private DcDisconnectingState mDisconnectingState = new DcDisconnectingState(); - - /** - * The state machine is disconnecting after an creating a connection. - */ - private class DcDisconnectionErrorCreatingConnection extends State { - @Override - public boolean processMessage(Message msg) { - boolean retVal; - - switch (msg.what) { - case EVENT_DEACTIVATE_DONE: - AsyncResult ar = (AsyncResult) msg.obj; - ConnectionParams cp = (ConnectionParams) ar.userObj; - if (cp.tag == mTag) { - if (DBG) { - log("DcDisconnectionErrorCreatingConnection" + - " msg.what=EVENT_DEACTIVATE_DONE"); - } - - // Transition to inactive but send notifications after - // we've entered the mInactive state. - mInactiveState.setEnterNotificationParams(cp, - FailCause.UNACCEPTABLE_NETWORK_PARAMETER, -1); - transitionTo(mInactiveState); - } else { - if (DBG) { - log("DcDisconnectionErrorCreatingConnection EVENT_DEACTIVATE_DONE" + - " stale dp.tag=" + cp.tag + ", mTag=" + mTag); - } - } - retVal = HANDLED; - break; - - default: - if (VDBG) { - log("DcDisconnectionErrorCreatingConnection not handled msg.what=0x" - + Integer.toHexString(msg.what)); - } - retVal = NOT_HANDLED; - break; - } - return retVal; - } - } - private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection = - new DcDisconnectionErrorCreatingConnection(); - - // ******* public interface - - /** - * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg. - * Used for cellular networks that use Acesss Point Names (APN) such - * as GSM networks. - * - * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. - * With AsyncResult.userObj set to the original msg.obj, - * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). - * @param apn is the Access Point Name to bring up a connection to - */ - public void bringUp(Message onCompletedMsg, ApnSetting apn) { - sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg))); - } - - /** - * Tear down the connection through the apn on the network. - * - * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. - * With AsyncResult.userObj set to the original msg.obj. - */ - public void tearDown(String reason, Message onCompletedMsg) { - sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg))); - } - - /** - * Tear down the connection through the apn on the network. Ignores refcount and - * and always tears down. - * - * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. - * With AsyncResult.userObj set to the original msg.obj. - */ - public void tearDownAll(String reason, Message onCompletedMsg) { - sendMessage(obtainMessage(EVENT_DISCONNECT_ALL, - new DisconnectParams(reason, onCompletedMsg))); - } - - /** - * @return the string for msg.what as our info. - */ - @Override - protected String getWhatToString(int what) { - String info = null; - info = cmdToString(what); - if (info == null) { - info = DataConnectionAc.cmdToString(what); - } - return info; - } - - /** - * Dump the current state. - * - * @param fd - * @param pw - * @param args - */ - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.print("DataConnection "); - super.dump(fd, pw, args); - pw.println(" mApnList=" + mApnList); - pw.flush(); - pw.println(" mDataConnectionTracker=" + mDataConnectionTracker); - pw.println(" mApn=" + mApn); - pw.println(" mTag=" + mTag); - pw.flush(); - pw.println(" phone=" + phone); - pw.println(" mRilVersion=" + mRilVersion); - pw.println(" cid=" + cid); - pw.flush(); - pw.println(" mLinkProperties=" + mLinkProperties); - pw.flush(); - pw.println(" mCapabilities=" + mCapabilities); - pw.println(" createTime=" + TimeUtils.logTimeOfDay(createTime)); - pw.println(" lastFailTime=" + TimeUtils.logTimeOfDay(lastFailTime)); - pw.println(" lastFailCause=" + lastFailCause); - pw.flush(); - pw.println(" mRetryOverride=" + mRetryOverride); - pw.println(" mRefCount=" + mRefCount); - pw.println(" userData=" + userData); - if (mRetryMgr != null) pw.println(" " + mRetryMgr); - pw.flush(); - } -} diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java deleted file mode 100644 index a24414ff3dd3..000000000000 --- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (C) 2011 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 com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult; -import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Protocol; - -import android.app.PendingIntent; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.net.ProxyProperties; -import android.os.Message; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * AsyncChannel to a DataConnection - */ -public class DataConnectionAc extends AsyncChannel { - private static final boolean DBG = false; - private String mLogTag; - - public DataConnection dataConnection; - - public static final int BASE = Protocol.BASE_DATA_CONNECTION_AC; - - public static final int REQ_IS_INACTIVE = BASE + 0; - public static final int RSP_IS_INACTIVE = BASE + 1; - - public static final int REQ_GET_CID = BASE + 2; - public static final int RSP_GET_CID = BASE + 3; - - public static final int REQ_GET_APNSETTING = BASE + 4; - public static final int RSP_GET_APNSETTING = BASE + 5; - - public static final int REQ_GET_LINK_PROPERTIES = BASE + 6; - public static final int RSP_GET_LINK_PROPERTIES = BASE + 7; - - public static final int REQ_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 8; - public static final int RSP_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 9; - - public static final int REQ_GET_LINK_CAPABILITIES = BASE + 10; - public static final int RSP_GET_LINK_CAPABILITIES = BASE + 11; - - public static final int REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 12; - public static final int RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 13; - - public static final int REQ_RESET = BASE + 14; - public static final int RSP_RESET = BASE + 15; - - public static final int REQ_GET_REFCOUNT = BASE + 16; - public static final int RSP_GET_REFCOUNT = BASE + 17; - - public static final int REQ_ADD_APNCONTEXT = BASE + 18; - public static final int RSP_ADD_APNCONTEXT = BASE + 19; - - public static final int REQ_REMOVE_APNCONTEXT = BASE + 20; - public static final int RSP_REMOVE_APNCONTEXT = BASE + 21; - - public static final int REQ_GET_APNCONTEXT_LIST = BASE + 22; - public static final int RSP_GET_APNCONTEXT_LIST = BASE + 23; - - public static final int REQ_SET_RECONNECT_INTENT = BASE + 24; - public static final int RSP_SET_RECONNECT_INTENT = BASE + 25; - - public static final int REQ_GET_RECONNECT_INTENT = BASE + 26; - public static final int RSP_GET_RECONNECT_INTENT = BASE + 27; - - private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT - BASE + 1; - private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; - static { - sCmdToString[REQ_IS_INACTIVE - BASE] = "REQ_IS_INACTIVE"; - sCmdToString[RSP_IS_INACTIVE - BASE] = "RSP_IS_INACTIVE"; - sCmdToString[REQ_GET_CID - BASE] = "REQ_GET_CID"; - sCmdToString[RSP_GET_CID - BASE] = "RSP_GET_CID"; - sCmdToString[REQ_GET_APNSETTING - BASE] = "REQ_GET_APNSETTING"; - sCmdToString[RSP_GET_APNSETTING - BASE] = "RSP_GET_APNSETTING"; - sCmdToString[REQ_GET_LINK_PROPERTIES - BASE] = "REQ_GET_LINK_PROPERTIES"; - sCmdToString[RSP_GET_LINK_PROPERTIES - BASE] = "RSP_GET_LINK_PROPERTIES"; - sCmdToString[REQ_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] = - "REQ_SET_LINK_PROPERTIES_HTTP_PROXY"; - sCmdToString[RSP_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] = - "RSP_SET_LINK_PROPERTIES_HTTP_PROXY"; - sCmdToString[REQ_GET_LINK_CAPABILITIES - BASE] = "REQ_GET_LINK_CAPABILITIES"; - sCmdToString[RSP_GET_LINK_CAPABILITIES - BASE] = "RSP_GET_LINK_CAPABILITIES"; - sCmdToString[REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] = - "REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE"; - sCmdToString[RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] = - "RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE"; - sCmdToString[REQ_RESET - BASE] = "REQ_RESET"; - sCmdToString[RSP_RESET - BASE] = "RSP_RESET"; - sCmdToString[REQ_GET_REFCOUNT - BASE] = "REQ_GET_REFCOUNT"; - sCmdToString[RSP_GET_REFCOUNT - BASE] = "RSP_GET_REFCOUNT"; - sCmdToString[REQ_ADD_APNCONTEXT - BASE] = "REQ_ADD_APNCONTEXT"; - sCmdToString[RSP_ADD_APNCONTEXT - BASE] = "RSP_ADD_APNCONTEXT"; - sCmdToString[REQ_REMOVE_APNCONTEXT - BASE] = "REQ_REMOVE_APNCONTEXT"; - sCmdToString[RSP_REMOVE_APNCONTEXT - BASE] = "RSP_REMOVE_APNCONTEXT"; - sCmdToString[REQ_GET_APNCONTEXT_LIST - BASE] = "REQ_GET_APNCONTEXT_LIST"; - sCmdToString[RSP_GET_APNCONTEXT_LIST - BASE] = "RSP_GET_APNCONTEXT_LIST"; - sCmdToString[REQ_SET_RECONNECT_INTENT - BASE] = "REQ_SET_RECONNECT_INTENT"; - sCmdToString[RSP_SET_RECONNECT_INTENT - BASE] = "RSP_SET_RECONNECT_INTENT"; - sCmdToString[REQ_GET_RECONNECT_INTENT - BASE] = "REQ_GET_RECONNECT_INTENT"; - sCmdToString[RSP_GET_RECONNECT_INTENT - BASE] = "RSP_GET_RECONNECT_INTENT"; - } - protected static String cmdToString(int cmd) { - cmd -= BASE; - if ((cmd >= 0) && (cmd < sCmdToString.length)) { - return sCmdToString[cmd]; - } else { - return AsyncChannel.cmdToString(cmd + BASE); - } - } - - /** - * enum used to notify action taken or necessary to be - * taken after the link property is changed. - */ - public enum LinkPropertyChangeAction { - NONE, CHANGED, RESET; - - public static LinkPropertyChangeAction fromInt(int value) { - if (value == NONE.ordinal()) { - return NONE; - } else if (value == CHANGED.ordinal()) { - return CHANGED; - } else if (value == RESET.ordinal()) { - return RESET; - } else { - throw new RuntimeException("LinkPropertyChangeAction.fromInt: bad value=" + value); - } - } - } - - public DataConnectionAc(DataConnection dc, String logTag) { - dataConnection = dc; - mLogTag = logTag; - } - - /** - * Request if the state machine is in the inactive state. - * Response {@link #rspIsInactive} - */ - public void reqIsInactive() { - sendMessage(REQ_IS_INACTIVE); - if (DBG) log("reqIsInactive"); - } - - /** - * Evaluate RSP_IS_INACTIVE. - * - * @return true if the state machine is in the inactive state. - */ - public boolean rspIsInactive(Message response) { - boolean retVal = response.arg1 == 1; - if (DBG) log("rspIsInactive=" + retVal); - return retVal; - } - - /** - * @return true if the state machine is in the inactive state. - */ - public boolean isInactiveSync() { - Message response = sendMessageSynchronously(REQ_IS_INACTIVE); - if ((response != null) && (response.what == RSP_IS_INACTIVE)) { - return rspIsInactive(response); - } else { - log("rspIsInactive error response=" + response); - return false; - } - } - - /** - * Request the Connection ID. - * Response {@link #rspCid} - */ - public void reqCid() { - sendMessage(REQ_GET_CID); - if (DBG) log("reqCid"); - } - - /** - * Evaluate a RSP_GET_CID message and return the cid. - * - * @param response Message - * @return connection id or -1 if an error - */ - public int rspCid(Message response) { - int retVal = response.arg1; - if (DBG) log("rspCid=" + retVal); - return retVal; - } - - /** - * @return connection id or -1 if an error - */ - public int getCidSync() { - Message response = sendMessageSynchronously(REQ_GET_CID); - if ((response != null) && (response.what == RSP_GET_CID)) { - return rspCid(response); - } else { - log("rspCid error response=" + response); - return -1; - } - } - - /** - * Request the Reference Count. - * Response {@link #rspRefCount} - */ - public void reqRefCount() { - sendMessage(REQ_GET_REFCOUNT); - if (DBG) log("reqRefCount"); - } - - /** - * Evaluate a RSP_GET_REFCOUNT message and return the refCount. - * - * @param response Message - * @return ref count or -1 if an error - */ - public int rspRefCount(Message response) { - int retVal = response.arg1; - if (DBG) log("rspRefCount=" + retVal); - return retVal; - } - - /** - * @return connection id or -1 if an error - */ - public int getRefCountSync() { - Message response = sendMessageSynchronously(REQ_GET_REFCOUNT); - if ((response != null) && (response.what == RSP_GET_REFCOUNT)) { - return rspRefCount(response); - } else { - log("rspRefCount error response=" + response); - return -1; - } - } - - /** - * Request the connections ApnSetting. - * Response {@link #rspApnSetting} - */ - public void reqApnSetting() { - sendMessage(REQ_GET_APNSETTING); - if (DBG) log("reqApnSetting"); - } - - /** - * Evaluate a RSP_APN_SETTING message and return the ApnSetting. - * - * @param response Message - * @return ApnSetting, maybe null - */ - public ApnSetting rspApnSetting(Message response) { - ApnSetting retVal = (ApnSetting) response.obj; - if (DBG) log("rspApnSetting=" + retVal); - return retVal; - } - - /** - * Get the connections ApnSetting. - * - * @return ApnSetting or null if an error - */ - public ApnSetting getApnSettingSync() { - Message response = sendMessageSynchronously(REQ_GET_APNSETTING); - if ((response != null) && (response.what == RSP_GET_APNSETTING)) { - return rspApnSetting(response); - } else { - log("getApnSetting error response=" + response); - return null; - } - } - - /** - * Request the connections LinkProperties. - * Response {@link #rspLinkProperties} - */ - public void reqLinkProperties() { - sendMessage(REQ_GET_LINK_PROPERTIES); - if (DBG) log("reqLinkProperties"); - } - - /** - * Evaluate RSP_GET_LINK_PROPERTIES - * - * @param response - * @return LinkProperties, maybe null. - */ - public LinkProperties rspLinkProperties(Message response) { - LinkProperties retVal = (LinkProperties) response.obj; - if (DBG) log("rspLinkProperties=" + retVal); - return retVal; - } - - /** - * Get the connections LinkProperties. - * - * @return LinkProperties or null if an error - */ - public LinkProperties getLinkPropertiesSync() { - Message response = sendMessageSynchronously(REQ_GET_LINK_PROPERTIES); - if ((response != null) && (response.what == RSP_GET_LINK_PROPERTIES)) { - return rspLinkProperties(response); - } else { - log("getLinkProperties error response=" + response); - return null; - } - } - - /** - * Request setting the connections LinkProperties.HttpProxy. - * Response RSP_SET_LINK_PROPERTIES when complete. - */ - public void reqSetLinkPropertiesHttpProxy(ProxyProperties proxy) { - sendMessage(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy); - if (DBG) log("reqSetLinkPropertiesHttpProxy proxy=" + proxy); - } - - /** - * Set the connections LinkProperties.HttpProxy - */ - public void setLinkPropertiesHttpProxySync(ProxyProperties proxy) { - Message response = - sendMessageSynchronously(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy); - if ((response != null) && (response.what == RSP_SET_LINK_PROPERTIES_HTTP_PROXY)) { - if (DBG) log("setLinkPropertiesHttpPoxy ok"); - } else { - log("setLinkPropertiesHttpPoxy error response=" + response); - } - } - - /** - * Request update LinkProperties from DataCallState - * Response {@link #rspUpdateLinkPropertiesDataCallState} - */ - public void reqUpdateLinkPropertiesDataCallState(DataCallState newState) { - sendMessage(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState); - if (DBG) log("reqUpdateLinkPropertiesDataCallState"); - } - - public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) { - UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj; - if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal); - return retVal; - } - - /** - * Update link properties in the data connection - * - * @return the removed and added addresses. - */ - public UpdateLinkPropertyResult updateLinkPropertiesDataCallStateSync(DataCallState newState) { - Message response = - sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState); - if ((response != null) && - (response.what == RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE)) { - return rspUpdateLinkPropertiesDataCallState(response); - } else { - log("getLinkProperties error response=" + response); - return new UpdateLinkPropertyResult(new LinkProperties()); - } - } - - /** - * Request the connections LinkCapabilities. - * Response {@link #rspLinkCapabilities} - */ - public void reqLinkCapabilities() { - sendMessage(REQ_GET_LINK_CAPABILITIES); - if (DBG) log("reqLinkCapabilities"); - } - - /** - * Evaluate RSP_GET_LINK_CAPABILITIES - * - * @param response - * @return LinkCapabilites, maybe null. - */ - public LinkCapabilities rspLinkCapabilities(Message response) { - LinkCapabilities retVal = (LinkCapabilities) response.obj; - if (DBG) log("rspLinkCapabilities=" + retVal); - return retVal; - } - - /** - * Get the connections LinkCapabilities. - * - * @return LinkCapabilities or null if an error - */ - public LinkCapabilities getLinkCapabilitiesSync() { - Message response = sendMessageSynchronously(REQ_GET_LINK_CAPABILITIES); - if ((response != null) && (response.what == RSP_GET_LINK_CAPABILITIES)) { - return rspLinkCapabilities(response); - } else { - log("getLinkCapabilities error response=" + response); - return null; - } - } - - /** - * Request the connections LinkCapabilities. - * Response RSP_RESET when complete - */ - public void reqReset() { - sendMessage(REQ_RESET); - if (DBG) log("reqReset"); - } - - /** - * Reset the connection and wait for it to complete. - */ - public void resetSync() { - Message response = sendMessageSynchronously(REQ_RESET); - if ((response != null) && (response.what == RSP_RESET)) { - if (DBG) log("restSync ok"); - } else { - log("restSync error response=" + response); - } - } - - /** - * Request to add ApnContext association. - * Response RSP_ADD_APNCONTEXT when complete. - */ - public void reqAddApnContext(ApnContext apnContext) { - Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext); - if (DBG) log("reqAddApnContext"); - } - - /** - * Add ApnContext association synchronoulsy. - * - * @param ApnContext to associate - */ - public void addApnContextSync(ApnContext apnContext) { - Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext); - if ((response != null) && (response.what == RSP_ADD_APNCONTEXT)) { - if (DBG) log("addApnContext ok"); - } else { - log("addApnContext error response=" + response); - } - } - - /** - * Request to remove ApnContext association. - * Response RSP_REMOVE_APNCONTEXT when complete. - */ - public void reqRemomveApnContext(ApnContext apnContext) { - Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext); - if (DBG) log("reqRemomveApnContext"); - } - - /** - * Remove ApnContext associateion. - * - * @param ApnContext to dissociate - */ - public void removeApnContextSync(ApnContext apnContext) { - Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext); - if ((response != null) && (response.what == RSP_REMOVE_APNCONTEXT)) { - if (DBG) log("removeApnContext ok"); - } else { - log("removeApnContext error response=" + response); - } - } - - /** - * Request to retrive ApnContext List associated with DC. - * Response RSP_GET_APNCONTEXT_LIST when complete. - */ - public void reqGetApnList(ApnContext apnContext) { - Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST); - if (DBG) log("reqGetApnList"); - } - - /** - * Retrieve Collection of ApnContext from the response message. - * - * @param Message sent from DC in response to REQ_GET_APNCONTEXT_LIST. - * @return Collection of ApnContext - */ - public Collection rspApnList(Message response) { - Collection retVal = (Collection)response.obj; - if (retVal == null) retVal = new ArrayList(); - return retVal; - } - - /** - * Retrieve collection of ApnContext currently associated with - * the DataConnectionA synchronously. - * - * @return Collection of ApnContext - */ - public Collection getApnListSync() { - Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST); - if ((response != null) && (response.what == RSP_GET_APNCONTEXT_LIST)) { - if (DBG) log("getApnList ok"); - return rspApnList(response); - } else { - log("getApnList error response=" + response); - // return dummy list with no entry - return new ArrayList(); - } - } - - /** - * Request to set Pending ReconnectIntent to DC. - * Response RSP_SET_RECONNECT_INTENT when complete. - */ - public void reqSetReconnectIntent(PendingIntent intent) { - Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent); - if (DBG) log("reqSetReconnectIntent"); - } - - /** - * Set pending reconnect intent to DC synchronously. - * - * @param PendingIntent to set. - */ - public void setReconnectIntentSync(PendingIntent intent) { - Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent); - if ((response != null) && (response.what == RSP_SET_RECONNECT_INTENT)) { - if (DBG) log("setReconnectIntent ok"); - } else { - log("setReconnectIntent error response=" + response); - } - } - - /** - * Request to get Pending ReconnectIntent to DC. - * Response RSP_GET_RECONNECT_INTENT when complete. - */ - public void reqGetReconnectIntent() { - Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT); - if (DBG) log("reqGetReconnectIntent"); - } - - /** - * Retrieve reconnect intent from response message from DC. - * - * @param Message which contains the reconnect intent. - * @return PendingIntent from the response. - */ - public PendingIntent rspReconnectIntent(Message response) { - PendingIntent retVal = (PendingIntent) response.obj; - return retVal; - } - - /** - * Retrieve reconnect intent currently set in DC synchronously. - * - * @return PendingIntent reconnect intent current ly set in DC - */ - public PendingIntent getReconnectIntentSync() { - Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT); - if ((response != null) && (response.what == RSP_GET_RECONNECT_INTENT)) { - if (DBG) log("getReconnectIntent ok"); - return rspReconnectIntent(response); - } else { - log("getReconnectIntent error response=" + response); - return null; - } - } - - @Override - public String toString() { - return dataConnection.getName(); - } - - private void log(String s) { - android.util.Log.d(mLogTag, "DataConnectionAc " + s); - } -} diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java deleted file mode 100644 index 588515bbd134..000000000000 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ /dev/null @@ -1,1285 +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; - -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.net.NetworkInfo; -import android.net.TrafficStats; -import android.net.wifi.WifiManager; -import android.os.AsyncResult; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.R; -import com.android.internal.telephony.DataConnection.FailCause; -import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Protocol; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * {@hide} - */ -public abstract class DataConnectionTracker extends Handler { - protected static final boolean DBG = true; - protected static final boolean VDBG = false; - - /** - * 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 - * DISCONNECTING: Connection.disconnect() has been called, but PDP - * context is not yet deactivated - * 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 or DISCONNECTING - */ - public enum State { - IDLE, - INITING, - CONNECTING, - SCANNING, - CONNECTED, - DISCONNECTING, - FAILED - } - - public enum Activity { - NONE, - DATAIN, - DATAOUT, - DATAINANDOUT, - DORMANT - } - - public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER = - "com.android.internal.telephony"; - public static String EXTRA_MESSENGER = "EXTRA_MESSENGER"; - - /***** Event Codes *****/ - protected static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER; - protected static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0; - protected static final int EVENT_RADIO_AVAILABLE = BASE + 1; - protected static final int EVENT_RECORDS_LOADED = BASE + 2; - protected static final int EVENT_TRY_SETUP_DATA = BASE + 3; - protected static final int EVENT_DATA_STATE_CHANGED = BASE + 4; - protected static final int EVENT_POLL_PDP = BASE + 5; - protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6; - protected static final int EVENT_VOICE_CALL_STARTED = BASE + 7; - protected static final int EVENT_VOICE_CALL_ENDED = BASE + 8; - protected static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9; - protected static final int EVENT_LINK_STATE_CHANGED = BASE + 10; - protected static final int EVENT_ROAMING_ON = BASE + 11; - protected static final int EVENT_ROAMING_OFF = BASE + 12; - protected static final int EVENT_ENABLE_NEW_APN = BASE + 13; - protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14; - protected static final int EVENT_DISCONNECT_DONE = BASE + 15; - protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16; - protected static final int EVENT_DATA_STALL_ALARM = BASE + 17; - protected static final int EVENT_DO_RECOVERY = BASE + 18; - protected static final int EVENT_APN_CHANGED = BASE + 19; - protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20; - protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21; - protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22; - protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23; - public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24; - protected static final int EVENT_CDMA_OTA_PROVISION = BASE + 25; - protected static final int EVENT_RESTART_RADIO = BASE + 26; - protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27; - protected static final int EVENT_RESET_DONE = BASE + 28; - public static final int CMD_SET_USER_DATA_ENABLE = BASE + 29; - public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30; - public static final int CMD_SET_DEPENDENCY_MET = BASE + 31; - public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32; - - /***** Constants *****/ - - protected static final int APN_INVALID_ID = -1; - protected static final int APN_DEFAULT_ID = 0; - protected static final int APN_MMS_ID = 1; - protected static final int APN_SUPL_ID = 2; - protected static final int APN_DUN_ID = 3; - protected static final int APN_HIPRI_ID = 4; - protected static final int APN_IMS_ID = 5; - protected static final int APN_FOTA_ID = 6; - protected static final int APN_CBS_ID = 7; - protected static final int APN_NUM_TYPES = 8; - - public static final int DISABLED = 0; - public static final int ENABLED = 1; - - public static final String APN_TYPE_KEY = "apnType"; - - /** Delay between APN attempts. - Note the property override mechanism is there just for testing purpose only. */ - protected static final int APN_DELAY_MILLIS = - SystemProperties.getInt("persist.radio.apn_delay", 5000); - - protected Object mDataEnabledLock = new Object(); - - // responds to the setInternalDataEnabled call - used internally to turn off data - // for example during emergency calls - protected boolean mInternalDataEnabled = true; - - // responds to public (user) API to enable/disable data use - // independent of mInternalDataEnabled and requests for APN access - // persisted - protected boolean mUserDataEnabled = true; - - // TODO: move away from static state once 5587429 is fixed. - protected static boolean sPolicyDataEnabled = true; - - private boolean[] dataEnabled = new boolean[APN_NUM_TYPES]; - - private int enabledCount = 0; - - /* Currently requested APN type (TODO: This should probably be a parameter not a member) */ - protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT; - - /** Retry configuration: A doubling of retry times from 5secs to 30minutes */ - protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000," - + "5000,10000,20000,40000,80000:5000,160000:5000," - + "320000:5000,640000:5000,1280000:5000,1800000:5000"; - - /** Retry configuration for secondary networks: 4 tries in 20 sec */ - protected static final String SECONDARY_DATA_RETRY_CONFIG = - "max_retries=3, 5000, 5000, 5000"; - - /** Slow poll when attempting connection recovery. */ - protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000; - /** Default max failure count before attempting to network re-registration. */ - protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3; - - /** - * After detecting a potential connection problem, this is the max number - * of subsequent polls before attempting recovery. - */ - 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; - // Default sent packets without ack which triggers initial recovery steps - 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"; - - // Default for the data stall alarm while non-aggressive stall detection - protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6; - // Default for the data stall alarm for aggressive stall detection - protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60; - // If attempt is less than this value we're doing first level recovery - protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1; - // Tag for tracking stale alarms - protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag"; - - // TODO: See if we can remove INTENT_RECONNECT_ALARM - // having to have different values for GSM and - // CDMA. If so we can then remove the need for - // getActionIntentReconnectAlarm. - protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = - "reconnect_alarm_extra_reason"; - - // Used for debugging. Send the INTENT with an optional counter value with the number - // of times the setup is to fail before succeeding. If the counter isn't passed the - // setup will fail once. Example fail two times with FailCause.SIGNAL_LOST(-3) - // adb shell am broadcast \ - // -a com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter \ - // --ei fail_data_setup_counter 3 --ei fail_data_setup_fail_cause -3 - protected static final String INTENT_SET_FAIL_DATA_SETUP_COUNTER = - "com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter"; - protected static final String FAIL_DATA_SETUP_COUNTER = "fail_data_setup_counter"; - protected int mFailDataSetupCounter = 0; - protected static final String FAIL_DATA_SETUP_FAIL_CAUSE = "fail_data_setup_fail_cause"; - protected FailCause mFailDataSetupFailCause = FailCause.ERROR_UNSPECIFIED; - - protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot"; - - // member variables - protected PhoneBase mPhone; - protected Activity mActivity = Activity.NONE; - protected State mState = State.IDLE; - protected Handler mDataConnectionTracker = null; - - - protected long mTxPkts; - protected long mRxPkts; - protected int mNetStatPollPeriod; - protected boolean mNetStatPollEnabled = false; - - protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0); - // Used to track stale data stall alarms. - protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime(); - // The current data stall alarm intent - protected PendingIntent mDataStallAlarmIntent = null; - // Number of packets sent since the last received packet - protected long mSentSinceLastRecv; - // Controls when a simple recovery attempt it to be tried - protected int mNoRecvPollCount = 0; - - // wifi connection status will be updated by sticky intent - protected boolean mIsWifiConnected = false; - - /** Intent sent when the reconnect alarm fires. */ - protected PendingIntent mReconnectIntent = null; - - /** CID of active data connection */ - protected int mCidActive; - - // When false we will not auto attach and manually attaching is required. - protected boolean mAutoAttachOnCreation = false; - - // State of screen - // (TODO: Reconsider tying directly to screen, maybe this is - // really a lower power mode") - protected boolean mIsScreenOn = true; - - /** Allows the generation of unique Id's for DataConnection objects */ - protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0); - - /** The data connections. */ - protected HashMap mDataConnections = - new HashMap(); - - /** The data connection async channels */ - protected HashMap mDataConnectionAsyncChannels = - new HashMap(); - - /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */ - protected HashMap mApnToDataConnectionId = - new HashMap(); - - /** Phone.APN_TYPE_* ===> ApnContext */ - protected ConcurrentHashMap mApnContexts; - - /* Currently active APN */ - protected ApnSetting mActiveApn; - - /** allApns holds all apns */ - protected ArrayList mAllApns = null; - - /** preferred apn */ - protected ApnSetting mPreferredApn = null; - - /** Is packet service restricted by network */ - protected boolean mIsPsRestricted = false; - - /* Once disposed dont handle any messages */ - protected boolean mIsDisposed = false; - - protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver () - { - @Override - public void onReceive(Context context, Intent intent) - { - String action = intent.getAction(); - if (DBG) log("onReceive: action=" + action); - if (action.equals(Intent.ACTION_SCREEN_ON)) { - mIsScreenOn = true; - stopNetStatPoll(); - startNetStatPoll(); - restartDataStallAlarm(); - } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { - mIsScreenOn = false; - stopNetStatPoll(); - startNetStatPoll(); - restartDataStallAlarm(); - } else if (action.startsWith(getActionIntentReconnectAlarm())) { - log("Reconnect alarm. Previous state was " + mState); - onActionIntentReconnectAlarm(intent); - } else if (action.equals(getActionIntentDataStallAlarm())) { - onActionIntentDataStallAlarm(intent); - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - final android.net.NetworkInfo networkInfo = (NetworkInfo) - intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - mIsWifiConnected = (networkInfo != null && networkInfo.isConnected()); - } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; - - if (!enabled) { - // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION - // quit and won't report disconnected until next enabling. - mIsWifiConnected = false; - } - } else if (action.equals(INTENT_SET_FAIL_DATA_SETUP_COUNTER)) { - mFailDataSetupCounter = intent.getIntExtra(FAIL_DATA_SETUP_COUNTER, 1); - mFailDataSetupFailCause = FailCause.fromInt( - intent.getIntExtra(FAIL_DATA_SETUP_FAIL_CAUSE, - FailCause.ERROR_UNSPECIFIED.getErrorCode())); - if (DBG) log("set mFailDataSetupCounter=" + mFailDataSetupCounter + - " mFailDataSetupFailCause=" + mFailDataSetupFailCause); - } - } - }; - - private final DataRoamingSettingObserver mDataRoamingSettingObserver; - - private class DataRoamingSettingObserver extends ContentObserver { - public DataRoamingSettingObserver(Handler handler) { - super(handler); - } - - public void register(Context context) { - final ContentResolver resolver = context.getContentResolver(); - resolver.registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.DATA_ROAMING), false, this); - } - - public void unregister(Context context) { - final ContentResolver resolver = context.getContentResolver(); - resolver.unregisterContentObserver(this); - } - - @Override - public void onChange(boolean selfChange) { - // already running on mPhone handler thread - handleDataOnRoamingChange(); - } - } - - /** - * Maintian the sum of transmit and receive packets. - * - * The packet counts are initizlied and reset to -1 and - * remain -1 until they can be updated. - */ - public class TxRxSum { - public long txPkts; - public long rxPkts; - - public TxRxSum() { - reset(); - } - - public TxRxSum(long txPkts, long rxPkts) { - this.txPkts = txPkts; - this.rxPkts = rxPkts; - } - - public TxRxSum(TxRxSum sum) { - txPkts = sum.txPkts; - rxPkts = sum.rxPkts; - } - - public void reset() { - txPkts = -1; - rxPkts = -1; - } - - public String toString() { - return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}"; - } - - public void updateTxRxSum() { - boolean txUpdated = false, rxUpdated = false; - long txSum = 0, rxSum = 0; - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getState() == State.CONNECTED) { - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (dcac == null) continue; - - LinkProperties linkProp = dcac.getLinkPropertiesSync(); - if (linkProp == null) continue; - - String iface = linkProp.getInterfaceName(); - - if (iface != null) { - long stats = TrafficStats.getTxPackets(iface); - if (stats > 0) { - txUpdated = true; - txSum += stats; - } - stats = TrafficStats.getRxPackets(iface); - if (stats > 0) { - rxUpdated = true; - rxSum += stats; - } - } - } - } - if (txUpdated) this.txPkts = txSum; - if (rxUpdated) this.rxPkts = rxSum; - } - } - - protected boolean isDataSetupCompleteOk(AsyncResult ar) { - if (ar.exception != null) { - if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result); - return false; - } - if (mFailDataSetupCounter <= 0) { - if (DBG) log("isDataSetupCompleteOk return true"); - return true; - } - ar.result = mFailDataSetupFailCause; - if (DBG) { - log("isDataSetupCompleteOk return false" + - " mFailDataSetupCounter=" + mFailDataSetupCounter + - " mFailDataSetupFailCause=" + mFailDataSetupFailCause); - } - mFailDataSetupCounter -= 1; - return false; - } - - protected void onActionIntentReconnectAlarm(Intent intent) { - String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON); - if (mState == State.FAILED) { - Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION); - msg.arg1 = 0; // tearDown is false - msg.arg2 = 0; - msg.obj = reason; - sendMessage(msg); - } - sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA)); - } - - protected void onActionIntentDataStallAlarm(Intent intent) { - if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction()); - Message msg = obtainMessage(EVENT_DATA_STALL_ALARM, intent.getAction()); - msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0); - sendMessage(msg); - } - - /** - * Default constructor - */ - protected DataConnectionTracker(PhoneBase phone) { - super(); - if (DBG) log("DCT.constructor"); - mPhone = phone; - - IntentFilter filter = new IntentFilter(); - filter.addAction(getActionIntentReconnectAlarm()); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER); - - mUserDataEnabled = Settings.Secure.getInt( - mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1; - - // TODO: Why is this registering the phone as the receiver of the intent - // and not its own handler? - mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); - - // This preference tells us 1) initial condition for "dataEnabled", - // and 2) whether the RIL will setup the baseband to auto-PS attach. - - dataEnabled[APN_DEFAULT_ID] = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, - true); - if (dataEnabled[APN_DEFAULT_ID]) { - enabledCount++; - } - - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); - mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false); - - // watch for changes to Settings.Secure.DATA_ROAMING - mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone); - mDataRoamingSettingObserver.register(mPhone.getContext()); - } - - public void dispose() { - if (DBG) log("DCT.dispose"); - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - dcac.disconnect(); - } - mDataConnectionAsyncChannels.clear(); - mIsDisposed = true; - mPhone.getContext().unregisterReceiver(this.mIntentReceiver); - mDataRoamingSettingObserver.unregister(mPhone.getContext()); - } - - protected void broadcastMessenger() { - Intent intent = new Intent(ACTION_DATA_CONNECTION_TRACKER_MESSENGER); - intent.putExtra(EXTRA_MESSENGER, new Messenger(this)); - mPhone.getContext().sendBroadcast(intent); - } - - public Activity getActivity() { - return mActivity; - } - - public boolean isApnTypeActive(String type) { - // TODO: support simultaneous with List instead - if (Phone.APN_TYPE_DUN.equals(type)) { - ApnSetting dunApn = fetchDunApn(); - if (dunApn != null) { - return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString()))); - } - } - return mActiveApn != null && mActiveApn.canHandleType(type); - } - - protected ApnSetting fetchDunApn() { - if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) { - log("fetchDunApn: net.tethering.noprovisioning=true ret: null"); - return null; - } - Context c = mPhone.getContext(); - String apnData = Settings.Secure.getString(c.getContentResolver(), - Settings.Secure.TETHER_DUN_APN); - ApnSetting dunSetting = ApnSetting.fromString(apnData); - if (dunSetting != null) { - if (VDBG) log("fetchDunApn: secure TETHER_DUN_APN dunSetting=" + dunSetting); - return dunSetting; - } - - apnData = c.getResources().getString(R.string.config_tether_apndata); - dunSetting = ApnSetting.fromString(apnData); - if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting); - return dunSetting; - } - - public String[] getActiveApnTypes() { - String[] result; - if (mActiveApn != null) { - result = mActiveApn.types; - } else { - result = new String[1]; - result[0] = Phone.APN_TYPE_DEFAULT; - } - return result; - } - - /** TODO: See if we can remove */ - public String getActiveApnString(String apnType) { - String result = null; - if (mActiveApn != null) { - result = mActiveApn.apn; - } - return result; - } - - /** - * Modify {@link Settings.Secure#DATA_ROAMING} value. - */ - public void setDataOnRoamingEnabled(boolean enabled) { - if (getDataOnRoamingEnabled() != enabled) { - final ContentResolver resolver = mPhone.getContext().getContentResolver(); - Settings.Secure.putInt(resolver, Settings.Secure.DATA_ROAMING, enabled ? 1 : 0); - // will trigger handleDataOnRoamingChange() through observer - } - } - - /** - * Return current {@link Settings.Secure#DATA_ROAMING} value. - */ - public boolean getDataOnRoamingEnabled() { - try { - final ContentResolver resolver = mPhone.getContext().getContentResolver(); - return Settings.Secure.getInt(resolver, Settings.Secure.DATA_ROAMING) != 0; - } catch (SettingNotFoundException snfe) { - return false; - } - } - - private void handleDataOnRoamingChange() { - if (mPhone.getServiceState().getRoaming()) { - if (getDataOnRoamingEnabled()) { - resetAllRetryCounts(); - } - sendMessage(obtainMessage(EVENT_ROAMING_ON)); - } - } - - // abstract methods - protected abstract String getActionIntentReconnectAlarm(); - protected abstract String getActionIntentDataStallAlarm(); - protected abstract void startNetStatPoll(); - protected abstract void stopNetStatPoll(); - protected abstract void restartDataStallAlarm(); - protected abstract void restartRadio(); - protected abstract void log(String s); - protected abstract void loge(String s); - protected abstract boolean isDataAllowed(); - protected abstract boolean isApnTypeAvailable(String type); - public abstract State getState(String apnType); - protected abstract void setState(State s); - protected abstract void gotoIdleAndNotifyDataConnection(String reason); - - protected abstract boolean onTrySetupData(String reason); - 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(int connId, AsyncResult ar); - protected abstract void onVoiceCallStarted(); - protected abstract void onVoiceCallEnded(); - protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason); - protected abstract void onCleanUpAllConnections(String cause); - protected abstract boolean isDataPossible(String apnType); - - protected void onDataStallAlarm(int tag) { - loge("onDataStallAlarm: not impleted tag=" + tag); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { - log("DISCONNECTED_CONNECTED: msg=" + msg); - DataConnectionAc dcac = (DataConnectionAc) msg.obj; - mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId()); - dcac.disconnected(); - break; - } - case EVENT_ENABLE_NEW_APN: - onEnableApn(msg.arg1, msg.arg2); - break; - - case EVENT_TRY_SETUP_DATA: - String reason = null; - if (msg.obj instanceof String) { - reason = (String) msg.obj; - } - onTrySetupData(reason); - break; - - case EVENT_DATA_STALL_ALARM: - onDataStallAlarm(msg.arg1); - break; - - case EVENT_ROAMING_OFF: - if (getDataOnRoamingEnabled() == false) { - resetAllRetryCounts(); - } - 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: - mCidActive = msg.arg1; - onDataSetupComplete((AsyncResult) msg.obj); - break; - - case EVENT_DISCONNECT_DONE: - log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg); - onDisconnectDone(msg.arg1, (AsyncResult) msg.obj); - break; - - case EVENT_VOICE_CALL_STARTED: - onVoiceCallStarted(); - break; - - case EVENT_VOICE_CALL_ENDED: - onVoiceCallEnded(); - break; - - case EVENT_CLEAN_UP_ALL_CONNECTIONS: { - onCleanUpAllConnections((String) msg.obj); - break; - } - case EVENT_CLEAN_UP_CONNECTION: { - boolean tearDown = (msg.arg1 == 0) ? false : true; - onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj); - break; - } - case EVENT_SET_INTERNAL_DATA_ENABLE: { - boolean enabled = (msg.arg1 == ENABLED) ? true : false; - onSetInternalDataEnabled(enabled); - break; - } - case EVENT_RESET_DONE: { - if (DBG) log("EVENT_RESET_DONE"); - onResetDone((AsyncResult) msg.obj); - break; - } - case CMD_SET_USER_DATA_ENABLE: { - final boolean enabled = (msg.arg1 == ENABLED) ? true : false; - if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled); - onSetUserDataEnabled(enabled); - break; - } - case CMD_SET_DEPENDENCY_MET: { - boolean met = (msg.arg1 == ENABLED) ? true : false; - if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met); - Bundle bundle = msg.getData(); - if (bundle != null) { - String apnType = (String)bundle.get(APN_TYPE_KEY); - if (apnType != null) { - onSetDependencyMet(apnType, met); - } - } - break; - } - case CMD_SET_POLICY_DATA_ENABLE: { - final boolean enabled = (msg.arg1 == ENABLED) ? true : false; - onSetPolicyDataEnabled(enabled); - break; - } - default: - Log.e("DATA", "Unidentified event msg=" + msg); - break; - } - } - - /** - * Report on whether data connectivity is enabled - * - * @return {@code false} if data connectivity has been explicitly disabled, - * {@code true} otherwise. - */ - public boolean getAnyDataEnabled() { - final boolean result; - synchronized (mDataEnabledLock) { - result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled - && (enabledCount != 0)); - } - if (!result && DBG) log("getAnyDataEnabled " + result); - return result; - } - - protected boolean isEmergency() { - final boolean result; - synchronized (mDataEnabledLock) { - result = mPhone.isInEcm() || mPhone.isInEmergencyCall(); - } - log("isEmergency: result=" + result); - return result; - } - - protected int apnTypeToId(String type) { - if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) { - return APN_DEFAULT_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) { - return APN_MMS_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) { - return APN_SUPL_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) { - return APN_DUN_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) { - return APN_HIPRI_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_IMS)) { - return APN_IMS_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_FOTA)) { - return APN_FOTA_ID; - } else if (TextUtils.equals(type, Phone.APN_TYPE_CBS)) { - return APN_CBS_ID; - } else { - return APN_INVALID_ID; - } - } - - protected String apnIdToType(int id) { - switch (id) { - case APN_DEFAULT_ID: - return Phone.APN_TYPE_DEFAULT; - case APN_MMS_ID: - return Phone.APN_TYPE_MMS; - case APN_SUPL_ID: - return Phone.APN_TYPE_SUPL; - case APN_DUN_ID: - return Phone.APN_TYPE_DUN; - case APN_HIPRI_ID: - return Phone.APN_TYPE_HIPRI; - case APN_IMS_ID: - return Phone.APN_TYPE_IMS; - case APN_FOTA_ID: - return Phone.APN_TYPE_FOTA; - case APN_CBS_ID: - return Phone.APN_TYPE_CBS; - default: - log("Unknown id (" + id + ") in apnIdToType"); - return Phone.APN_TYPE_DEFAULT; - } - } - - protected LinkProperties getLinkProperties(String apnType) { - int id = apnTypeToId(apnType); - - if (isApnIdEnabled(id)) { - // TODO - remove this cdma-only hack and support multiple DCs. - DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0); - return dcac.getLinkPropertiesSync(); - } else { - return new LinkProperties(); - } - } - - protected LinkCapabilities getLinkCapabilities(String apnType) { - int id = apnTypeToId(apnType); - if (isApnIdEnabled(id)) { - // TODO - remove this cdma-only hack and support multiple DCs. - DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0); - return dcac.getLinkCapabilitiesSync(); - } else { - return new LinkCapabilities(); - } - } - - // tell all active apns of the current condition - protected void notifyDataConnection(String reason) { - for (int id = 0; id < APN_NUM_TYPES; id++) { - if (dataEnabled[id]) { - mPhone.notifyDataConnection(reason, apnIdToType(id)); - } - } - notifyOffApnsOfAvailability(reason); - } - - // a new APN has gone active and needs to send events to catch up with the - // current condition - private void notifyApnIdUpToCurrent(String reason, int apnId) { - switch (mState) { - case IDLE: - case INITING: - break; - case CONNECTING: - case SCANNING: - mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); - break; - case CONNECTED: - case DISCONNECTING: - mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); - mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED); - break; - } - } - - // since we normally don't send info to a disconnected APN, we need to do this specially - private void notifyApnIdDisconnected(String reason, int apnId) { - mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED); - } - - // disabled apn's still need avail/unavail notificiations - send them out - protected void notifyOffApnsOfAvailability(String reason) { - if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason); - for (int id = 0; id < APN_NUM_TYPES; id++) { - if (!isApnIdEnabled(id)) { - notifyApnIdDisconnected(reason, id); - } - } - } - - public boolean isApnTypeEnabled(String apnType) { - if (apnType == null) { - return false; - } else { - return isApnIdEnabled(apnTypeToId(apnType)); - } - } - - protected synchronized boolean isApnIdEnabled(int id) { - if (id != APN_INVALID_ID) { - return dataEnabled[id]; - } - return false; - } - - /** - * Ensure that we are connected to an APN of the specified type. - * - * @param type the APN type (currently the only valid values are - * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}) - * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or - * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a - * broadcast will be sent by the ConnectivityManager when a - * connection to the APN has been established. - */ - public synchronized int enableApnType(String type) { - int id = apnTypeToId(type); - if (id == APN_INVALID_ID) { - return Phone.APN_REQUEST_FAILED; - } - - if (DBG) { - log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type) - + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState); - } - - if (!isApnTypeAvailable(type)) { - if (DBG) log("type not available"); - return Phone.APN_TYPE_NOT_AVAILABLE; - } - - if (isApnIdEnabled(id)) { - return Phone.APN_ALREADY_ACTIVE; - } else { - setEnabled(id, true); - } - return Phone.APN_REQUEST_STARTED; - } - - /** - * The APN of the specified type is no longer needed. Ensure that if use of - * the default APN has not been explicitly disabled, we are connected to the - * default APN. - * - * @param type the APN type. The only valid values are currently - * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}. - * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or - * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a - * broadcast will be sent by the ConnectivityManager when a - * connection to the APN has been disconnected. A {@code - * Phone.APN_REQUEST_FAILED} is returned if the type parameter is - * invalid or if the apn wasn't enabled. - */ - public synchronized int disableApnType(String type) { - if (DBG) log("disableApnType(" + type + ")"); - int id = apnTypeToId(type); - if (id == APN_INVALID_ID) { - return Phone.APN_REQUEST_FAILED; - } - if (isApnIdEnabled(id)) { - setEnabled(id, false); - if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { - if (dataEnabled[APN_DEFAULT_ID]) { - return Phone.APN_ALREADY_ACTIVE; - } else { - return Phone.APN_REQUEST_STARTED; - } - } else { - return Phone.APN_REQUEST_STARTED; - } - } else { - return Phone.APN_REQUEST_FAILED; - } - } - - protected void setEnabled(int id, boolean enable) { - if (DBG) { - log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id] - + " and enabledCount = " + enabledCount); - } - Message msg = obtainMessage(EVENT_ENABLE_NEW_APN); - msg.arg1 = id; - msg.arg2 = (enable ? ENABLED : DISABLED); - sendMessage(msg); - } - - protected void onEnableApn(int apnId, int enabled) { - if (DBG) { - log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) + - ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] + - ", enabledCount = " + enabledCount + ", isApnTypeActive = " + - isApnTypeActive(apnIdToType(apnId))); - } - if (enabled == ENABLED) { - synchronized (this) { - if (!dataEnabled[apnId]) { - dataEnabled[apnId] = true; - enabledCount++; - } - } - String type = apnIdToType(apnId); - if (!isApnTypeActive(type)) { - mRequestedApnType = type; - onEnableNewApn(); - } else { - notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId); - } - } else { - // disable - boolean didDisable = false; - synchronized (this) { - if (dataEnabled[apnId]) { - dataEnabled[apnId] = false; - enabledCount--; - didDisable = true; - } - } - if (didDisable) { - if ((enabledCount == 0) || (apnId == APN_DUN_ID)) { - mRequestedApnType = Phone.APN_TYPE_DEFAULT; - onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED); - } - - // send the disconnect msg manually, since the normal route wont send - // it (it's not enabled) - notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId); - if (dataEnabled[APN_DEFAULT_ID] == true - && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { - // TODO - this is an ugly way to restore the default conn - should be done - // by a real contention manager and policy that disconnects the lower pri - // stuff as enable requests come in and pops them back on as we disable back - // down to the lower pri stuff - mRequestedApnType = Phone.APN_TYPE_DEFAULT; - onEnableNewApn(); - } - } - } - } - - /** - * Called when we switch APNs. - * - * mRequestedApnType is set prior to call - * To be overridden. - */ - protected void onEnableNewApn() { - } - - /** - * Called when EVENT_RESET_DONE is received so goto - * IDLE state and send notifications to those interested. - * - * TODO - currently unused. Needs to be hooked into DataConnection cleanup - * TODO - needs to pass some notion of which connection is reset.. - */ - protected void onResetDone(AsyncResult ar) { - if (DBG) log("EVENT_RESET_DONE"); - String reason = null; - if (ar.userObj instanceof String) { - reason = (String) ar.userObj; - } - gotoIdleAndNotifyDataConnection(reason); - } - - /** - * 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 boolean setInternalDataEnabled(boolean enable) { - if (DBG) - log("setInternalDataEnabled(" + enable + ")"); - - Message msg = obtainMessage(EVENT_SET_INTERNAL_DATA_ENABLE); - msg.arg1 = (enable ? ENABLED : DISABLED); - sendMessage(msg); - return true; - } - - protected void onSetInternalDataEnabled(boolean enabled) { - synchronized (mDataEnabledLock) { - mInternalDataEnabled = enabled; - if (enabled) { - log("onSetInternalDataEnabled: changed to enabled, try to setup data call"); - resetAllRetryCounts(); - onTrySetupData(Phone.REASON_DATA_ENABLED); - } else { - log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections"); - cleanUpAllConnections(null); - } - } - } - - public void cleanUpAllConnections(String cause) { - Message msg = obtainMessage(EVENT_CLEAN_UP_ALL_CONNECTIONS); - msg.obj = cause; - sendMessage(msg); - } - - public abstract boolean isDisconnected(); - - protected void onSetUserDataEnabled(boolean enabled) { - synchronized (mDataEnabledLock) { - final boolean prevEnabled = getAnyDataEnabled(); - if (mUserDataEnabled != enabled) { - mUserDataEnabled = enabled; - Settings.Secure.putInt(mPhone.getContext().getContentResolver(), - Settings.Secure.MOBILE_DATA, enabled ? 1 : 0); - if (getDataOnRoamingEnabled() == false && - mPhone.getServiceState().getRoaming() == true) { - if (enabled) { - notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON); - } else { - notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED); - } - } - if (prevEnabled != getAnyDataEnabled()) { - if (!prevEnabled) { - resetAllRetryCounts(); - onTrySetupData(Phone.REASON_DATA_ENABLED); - } else { - onCleanUpAllConnections(Phone.REASON_DATA_DISABLED); - } - } - } - } - } - - protected void onSetDependencyMet(String apnType, boolean met) { - } - - protected void onSetPolicyDataEnabled(boolean enabled) { - synchronized (mDataEnabledLock) { - final boolean prevEnabled = getAnyDataEnabled(); - if (sPolicyDataEnabled != enabled) { - sPolicyDataEnabled = enabled; - if (prevEnabled != getAnyDataEnabled()) { - if (!prevEnabled) { - resetAllRetryCounts(); - onTrySetupData(Phone.REASON_DATA_ENABLED); - } else { - onCleanUpAllConnections(Phone.REASON_DATA_DISABLED); - } - } - } - } - } - - protected String getReryConfig(boolean forDefault) { - int nt = mPhone.getServiceState().getNetworkType(); - - if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) || - (nt == TelephonyManager.NETWORK_TYPE_1xRTT) || - (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) || - (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) || - (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) || - (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) { - // CDMA variant - return SystemProperties.get("ro.cdma.data_retry_config"); - } else { - // Use GSM varient for all others. - if (forDefault) { - return SystemProperties.get("ro.gsm.data_retry_config"); - } else { - return SystemProperties.get("ro.gsm.2nd_data_retry_config"); - } - } - } - - protected void resetAllRetryCounts() { - for (DataConnection dc : mDataConnections.values()) { - dc.resetRetryCount(); - } - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("DataConnectionTracker:"); - pw.println(" mInternalDataEnabled=" + mInternalDataEnabled); - pw.println(" mUserDataEnabled=" + mUserDataEnabled); - pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled); - pw.println(" dataEnabled:"); - for(int i=0; i < dataEnabled.length; i++) { - pw.printf(" dataEnabled[%d]=%b\n", i, dataEnabled[i]); - } - pw.flush(); - pw.println(" enabledCount=" + enabledCount); - pw.println(" mRequestedApnType=" + mRequestedApnType); - pw.println(" mPhone=" + mPhone.getPhoneName()); - pw.println(" mActivity=" + mActivity); - pw.println(" mState=" + mState); - pw.println(" mTxPkts=" + mTxPkts); - pw.println(" mRxPkts=" + mRxPkts); - pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod); - pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled); - pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum); - pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag); - pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv); - pw.println(" mNoRecvPollCount=" + mNoRecvPollCount); - pw.println(" mIsWifiConnected=" + mIsWifiConnected); - pw.println(" mReconnectIntent=" + mReconnectIntent); - pw.println(" mCidActive=" + mCidActive); - pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation); - pw.println(" mIsScreenOn=" + mIsScreenOn); - pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator); - pw.flush(); - pw.println(" ***************************************"); - Set > mDcSet = mDataConnections.entrySet(); - pw.println(" mDataConnections: count=" + mDcSet.size()); - for (Entry entry : mDcSet) { - pw.printf(" *** mDataConnection[%d] \n", entry.getKey()); - entry.getValue().dump(fd, pw, args); - } - pw.println(" ***************************************"); - pw.flush(); - Set> mApnToDcIdSet = mApnToDataConnectionId.entrySet(); - pw.println(" mApnToDataConnectonId size=" + mApnToDcIdSet.size()); - for (Entry entry : mApnToDcIdSet) { - pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue()); - } - pw.println(" ***************************************"); - pw.flush(); - if (mApnContexts != null) { - Set> mApnContextsSet = mApnContexts.entrySet(); - pw.println(" mApnContexts size=" + mApnContextsSet.size()); - for (Entry entry : mApnContextsSet) { - entry.getValue().dump(fd, pw, args); - } - pw.println(" ***************************************"); - } else { - pw.println(" mApnContexts=null"); - } - pw.flush(); - pw.println(" mActiveApn=" + mActiveApn); - if (mAllApns != null) { - pw.println(" mAllApns size=" + mAllApns.size()); - for (int i=0; i < mAllApns.size(); i++) { - pw.printf(" mAllApns[%d]: %s\n", i, mAllApns.get(i)); - } - pw.flush(); - } else { - pw.println(" mAllApns=null"); - } - pw.println(" mPreferredApn=" + mPreferredApn); - pw.println(" mIsPsRestricted=" + mIsPsRestricted); - pw.println(" mIsDisposed=" + mIsDisposed); - pw.println(" mIntentReceiver=" + mIntentReceiver); - pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver); - pw.flush(); - } -} diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java new file mode 100644 index 000000000000..79872f32c0b0 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2012 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 com.android.internal.util.Protocol; + +/** + * @hide + */ +public class DctConstants { + /** + * 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 + * DISCONNECTING: Connection.disconnect() has been called, but PDP + * context is not yet deactivated + * 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 or DISCONNECTING + */ + public enum State { + IDLE, + INITING, + CONNECTING, + SCANNING, + CONNECTED, + DISCONNECTING, + FAILED + } + + public enum Activity { + NONE, + DATAIN, + DATAOUT, + DATAINANDOUT, + DORMANT + } + + /***** Event Codes *****/ + public static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER; + public static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0; + public static final int EVENT_RADIO_AVAILABLE = BASE + 1; + public static final int EVENT_RECORDS_LOADED = BASE + 2; + public static final int EVENT_TRY_SETUP_DATA = BASE + 3; + public static final int EVENT_DATA_STATE_CHANGED = BASE + 4; + public static final int EVENT_POLL_PDP = BASE + 5; + public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6; + public static final int EVENT_VOICE_CALL_STARTED = BASE + 7; + public static final int EVENT_VOICE_CALL_ENDED = BASE + 8; + public static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9; + public static final int EVENT_LINK_STATE_CHANGED = BASE + 10; + public static final int EVENT_ROAMING_ON = BASE + 11; + public static final int EVENT_ROAMING_OFF = BASE + 12; + public static final int EVENT_ENABLE_NEW_APN = BASE + 13; + public static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14; + public static final int EVENT_DISCONNECT_DONE = BASE + 15; + public static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16; + public static final int EVENT_DATA_STALL_ALARM = BASE + 17; + public static final int EVENT_DO_RECOVERY = BASE + 18; + public static final int EVENT_APN_CHANGED = BASE + 19; + public static final int EVENT_CDMA_DATA_DETACHED = BASE + 20; + public static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21; + public static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22; + public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23; + public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24; + public static final int EVENT_CDMA_OTA_PROVISION = BASE + 25; + public static final int EVENT_RESTART_RADIO = BASE + 26; + public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27; + public static final int EVENT_RESET_DONE = BASE + 28; + public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29; + public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30; + public static final int CMD_SET_DEPENDENCY_MET = BASE + 31; + public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32; + + /***** Constants *****/ + + public static final int APN_INVALID_ID = -1; + public static final int APN_DEFAULT_ID = 0; + public static final int APN_MMS_ID = 1; + public static final int APN_SUPL_ID = 2; + public static final int APN_DUN_ID = 3; + public static final int APN_HIPRI_ID = 4; + public static final int APN_IMS_ID = 5; + public static final int APN_FOTA_ID = 6; + public static final int APN_CBS_ID = 7; + public static final int APN_NUM_TYPES = 8; + + public static final int DISABLED = 0; + public static final int ENABLED = 1; + + public static final String APN_TYPE_KEY = "apnType"; + public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER = + "com.android.internal.telephony"; + public static String EXTRA_MESSENGER = "EXTRA_MESSENGER"; +} + diff --git a/telephony/java/com/android/internal/telephony/DebugService.java b/telephony/java/com/android/internal/telephony/DebugService.java deleted file mode 100644 index 29fea6e83fcd..000000000000 --- a/telephony/java/com/android/internal/telephony/DebugService.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2012 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 java.io.FileDescriptor; -import java.io.PrintWriter; - -/** - * A debug service that will dump telephony's state - * - * Currently this "Service" has a proxy in the phone app - * com.android.phone.TelephonyDebugService which actually - * invokes the dump method. - */ -public class DebugService { - private static String TAG = "DebugService"; - - /** Constructor */ - public DebugService() { - log("DebugService:"); - } - - /** - * Dump the state of various objects, add calls to other objects as desired. - */ - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - log("dump: +"); - PhoneProxy phoneProxy = null; - PhoneBase phoneBase = null; - - try { - phoneProxy = (PhoneProxy) PhoneFactory.getDefaultPhone(); - } catch (Exception e) { - pw.println("Telephony DebugService: Could not getDefaultPhone e=" + e); - return; - } - try { - phoneBase = (PhoneBase)phoneProxy.getActivePhone(); - } catch (Exception e) { - pw.println("Telephony DebugService: Could not PhoneBase e=" + e); - return; - } - - /** - * Surround each of the sub dump's with try/catch so even - * if one fails we'll be able to dump the next ones. - */ - pw.println(); - pw.println("++++++++++++++++++++++++++++++++"); - pw.flush(); - try { - phoneBase.dump(fd, pw, args); - } catch (Exception e) { - e.printStackTrace(); - } - pw.flush(); - pw.println("++++++++++++++++++++++++++++++++"); - try { - phoneBase.mDataConnectionTracker.dump(fd, pw, args); - } catch (Exception e) { - e.printStackTrace(); - } - pw.flush(); - pw.println("++++++++++++++++++++++++++++++++"); - try { - phoneBase.getServiceStateTracker().dump(fd, pw, args); - } catch (Exception e) { - e.printStackTrace(); - } - pw.flush(); - pw.println("++++++++++++++++++++++++++++++++"); - try { - phoneBase.getCallTracker().dump(fd, pw, args); - } catch (Exception e) { - e.printStackTrace(); - } - pw.flush(); - pw.println("++++++++++++++++++++++++++++++++"); - try { - ((RIL)phoneBase.mCM).dump(fd, pw, args); - } catch (Exception e) { - e.printStackTrace(); - } - pw.flush(); - pw.println("++++++++++++++++++++++++++++++++"); - log("dump: -"); - } - - private static void log(String s) { - Log.d(TAG, "DebugService " + s); - } -} diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java deleted file mode 100644 index eb78a53eb990..000000000000 --- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java +++ /dev/null @@ -1,281 +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; - -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.telephony.CellInfo; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.util.Log; - -import com.android.internal.telephony.ITelephonyRegistry; - -/** - * broadcast intents - */ -public class DefaultPhoneNotifier implements PhoneNotifier { - - static final String LOG_TAG = "GSM"; - private static final boolean DBG = true; - private ITelephonyRegistry mRegistry; - - /*package*/ - DefaultPhoneNotifier() { - mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - } - - public void notifyPhoneState(Phone sender) { - Call ringingCall = sender.getRingingCall(); - String incomingNumber = ""; - if (ringingCall != null && ringingCall.getEarliestConnection() != null){ - incomingNumber = ringingCall.getEarliestConnection().getAddress(); - } - try { - mRegistry.notifyCallState(convertCallState(sender.getState()), incomingNumber); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyServiceState(Phone sender) { - ServiceState ss = sender.getServiceState(); - if (ss == null) { - ss = new ServiceState(); - ss.setStateOutOfService(); - } - try { - mRegistry.notifyServiceState(ss); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifySignalStrength(Phone sender) { - try { - mRegistry.notifySignalStrength(sender.getSignalStrength()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyMessageWaitingChanged(Phone sender) { - try { - mRegistry.notifyMessageWaitingChanged(sender.getMessageWaitingIndicator()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyCallForwardingChanged(Phone sender) { - try { - mRegistry.notifyCallForwardingChanged(sender.getCallForwardingIndicator()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataActivity(Phone sender) { - try { - mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState())); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataConnection(Phone sender, String reason, String apnType, - Phone.DataState state) { - doNotifyDataConnection(sender, reason, apnType, state); - } - - private void doNotifyDataConnection(Phone sender, String reason, String apnType, - Phone.DataState state) { - // TODO - // use apnType as the key to which connection we're talking about. - // pass apnType back up to fetch particular for this one. - TelephonyManager telephony = TelephonyManager.getDefault(); - LinkProperties linkProperties = null; - LinkCapabilities linkCapabilities = null; - boolean roaming = false; - - if (state == Phone.DataState.CONNECTED) { - linkProperties = sender.getLinkProperties(apnType); - linkCapabilities = sender.getLinkCapabilities(apnType); - } - ServiceState ss = sender.getServiceState(); - if (ss != null) roaming = ss.getRoaming(); - - try { - mRegistry.notifyDataConnection( - convertDataState(state), - sender.isDataConnectivityPossible(apnType), reason, - sender.getActiveApnHost(apnType), - apnType, - linkProperties, - linkCapabilities, - ((telephony!=null) ? telephony.getNetworkType() : - TelephonyManager.NETWORK_TYPE_UNKNOWN), - roaming); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { - try { - mRegistry.notifyDataConnectionFailed(reason, apnType); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyCellLocation(Phone sender) { - Bundle data = new Bundle(); - sender.getCellLocation().fillInNotifierBundle(data); - try { - mRegistry.notifyCellLocation(data); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyCellInfo(Phone sender, CellInfo cellInfo) { - try { - mRegistry.notifyCellInfo(cellInfo); - } catch (RemoteException ex) { - - } - } - - public void notifyOtaspChanged(Phone sender, int otaspMode) { - try { - mRegistry.notifyOtaspChanged(otaspMode); - } catch (RemoteException ex) { - // system process is dead - } - } - - private void log(String s) { - Log.d(LOG_TAG, "[PhoneNotifier] " + s); - } - - /** - * Convert the {@link State} enum into the TelephonyManager.CALL_STATE_* constants - * for the public API. - */ - public static int convertCallState(Phone.State state) { - switch (state) { - case RINGING: - return TelephonyManager.CALL_STATE_RINGING; - case OFFHOOK: - return TelephonyManager.CALL_STATE_OFFHOOK; - default: - return TelephonyManager.CALL_STATE_IDLE; - } - } - - /** - * Convert the TelephonyManager.CALL_STATE_* constants into the {@link State} enum - * for the public API. - */ - public static Phone.State convertCallState(int state) { - switch (state) { - case TelephonyManager.CALL_STATE_RINGING: - return Phone.State.RINGING; - case TelephonyManager.CALL_STATE_OFFHOOK: - return Phone.State.OFFHOOK; - default: - return Phone.State.IDLE; - } - } - - /** - * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants - * for the public API. - */ - public static int convertDataState(Phone.DataState state) { - switch (state) { - case CONNECTING: - return TelephonyManager.DATA_CONNECTING; - case CONNECTED: - return TelephonyManager.DATA_CONNECTED; - case SUSPENDED: - return TelephonyManager.DATA_SUSPENDED; - default: - return TelephonyManager.DATA_DISCONNECTED; - } - } - - /** - * Convert the TelephonyManager.DATA_* constants into {@link DataState} enum - * for the public API. - */ - public static Phone.DataState convertDataState(int state) { - switch (state) { - case TelephonyManager.DATA_CONNECTING: - return Phone.DataState.CONNECTING; - case TelephonyManager.DATA_CONNECTED: - return Phone.DataState.CONNECTED; - case TelephonyManager.DATA_SUSPENDED: - return Phone.DataState.SUSPENDED; - default: - return Phone.DataState.DISCONNECTED; - } - } - - /** - * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants - * for the public API. - */ - public static int convertDataActivityState(Phone.DataActivityState state) { - switch (state) { - case DATAIN: - return TelephonyManager.DATA_ACTIVITY_IN; - case DATAOUT: - return TelephonyManager.DATA_ACTIVITY_OUT; - case DATAINANDOUT: - return TelephonyManager.DATA_ACTIVITY_INOUT; - case DORMANT: - return TelephonyManager.DATA_ACTIVITY_DORMANT; - default: - return TelephonyManager.DATA_ACTIVITY_NONE; - } - } - - /** - * Convert the TelephonyManager.DATA_* constants into the {@link DataState} enum - * for the public API. - */ - public static Phone.DataActivityState convertDataActivityState(int state) { - switch (state) { - case TelephonyManager.DATA_ACTIVITY_IN: - return Phone.DataActivityState.DATAIN; - case TelephonyManager.DATA_ACTIVITY_OUT: - return Phone.DataActivityState.DATAOUT; - case TelephonyManager.DATA_ACTIVITY_INOUT: - return Phone.DataActivityState.DATAINANDOUT; - case TelephonyManager.DATA_ACTIVITY_DORMANT: - return Phone.DataActivityState.DORMANT; - default: - return Phone.DataActivityState.NONE; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java deleted file mode 100644 index 663c2842a793..000000000000 --- a/telephony/java/com/android/internal/telephony/DriverCall.java +++ /dev/null @@ -1,162 +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; -//import com.android.internal.telephony.*; -import android.util.Log; -import java.lang.Comparable; -import android.telephony.PhoneNumberUtils; - -/** - * {@hide} - */ -public class DriverCall implements Comparable { - static final String LOG_TAG = "RILB"; - - public enum State { - ACTIVE, - HOLDING, - DIALING, // MO call only - ALERTING, // MO call only - INCOMING, // MT call only - WAITING; // MT call only - // If you add a state, make sure to look for the switch() - // statements that use this enum - } - - public int index; - public boolean isMT; - public State state; // May be null if unavail - public boolean isMpty; - public String number; - public int TOA; - public boolean isVoice; - public boolean isVoicePrivacy; - public int als; - public int numberPresentation; - public String name; - public int namePresentation; - public UUSInfo uusInfo; - - /** returns null on error */ - static DriverCall - fromCLCCLine(String line) { - DriverCall ret = new DriverCall(); - - //+CLCC: 1,0,2,0,0,\"+18005551212\",145 - // index,isMT,state,mode,isMpty(,number,TOA)? - ATResponseParser p = new ATResponseParser(line); - - try { - ret.index = p.nextInt(); - ret.isMT = p.nextBoolean(); - ret.state = stateFromCLCC(p.nextInt()); - - ret.isVoice = (0 == p.nextInt()); - ret.isMpty = p.nextBoolean(); - - // use ALLOWED as default presentation while parsing CLCC - ret.numberPresentation = Connection.PRESENTATION_ALLOWED; - - if (p.hasMore()) { - // Some lame implementations return strings - // like "NOT AVAILABLE" in the CLCC line - ret.number = PhoneNumberUtils.extractNetworkPortionAlt(p.nextString()); - - if (ret.number.length() == 0) { - ret.number = null; - } - - ret.TOA = p.nextInt(); - - // Make sure there's a leading + on addresses with a TOA - // of 145 - - ret.number = PhoneNumberUtils.stringFromStringAndTOA( - ret.number, ret.TOA); - - } - } catch (ATParseEx ex) { - Log.e(LOG_TAG,"Invalid CLCC line: '" + line + "'"); - return null; - } - - return ret; - } - - public - DriverCall() { - } - - public String - toString() { - return "id=" + index + "," - + state + "," - + "toa=" + TOA + "," - + (isMpty ? "conf" : "norm") + "," - + (isMT ? "mt" : "mo") + "," - + als + "," - + (isVoice ? "voc" : "nonvoc") + "," - + (isVoicePrivacy ? "evp" : "noevp") + "," - /*+ "number=" + number */ + ",cli=" + numberPresentation + "," - /*+ "name="+ name */ + "," + namePresentation; - } - - public static State - stateFromCLCC(int state) throws ATParseEx { - switch(state) { - case 0: return State.ACTIVE; - case 1: return State.HOLDING; - case 2: return State.DIALING; - case 3: return State.ALERTING; - case 4: return State.INCOMING; - case 5: return State.WAITING; - default: - throw new ATParseEx("illegal call state " + state); - } - } - - public static int - presentationFromCLIP(int cli) throws ATParseEx - { - switch(cli) { - case 0: return Connection.PRESENTATION_ALLOWED; - case 1: return Connection.PRESENTATION_RESTRICTED; - case 2: return Connection.PRESENTATION_UNKNOWN; - case 3: return Connection.PRESENTATION_PAYPHONE; - default: - throw new ATParseEx("illegal presentation " + cli); - } - } - - //***** Comparable Implementation - - /** For sorting by index */ - public int - compareTo (Object o) { - DriverCall dc; - - dc = (DriverCall)o; - - if (index < dc.index) { - return -1; - } else if (index == dc.index) { - return 0; - } else { /*index > dc.index*/ - return 1; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/EventLogTags.logtags b/telephony/java/com/android/internal/telephony/EventLogTags.logtags deleted file mode 100644 index 427e5dafa732..000000000000 --- a/telephony/java/com/android/internal/telephony/EventLogTags.logtags +++ /dev/null @@ -1,73 +0,0 @@ -# See system/core/logcat/event.logtags for a description of the format of this file. - -option java_package com.android.internal.telephony; - -# PDP Context has a bad DNS address -50100 pdp_bad_dns_address (dns_address|3) - -# For data connection on PDP context, reached the data-out-without-data-in -# packet count that triggers a countdown to radio restart -50101 pdp_radio_reset_countdown_triggered (out_packet_count|1|1) - -# Radio restart - timed out with no incoming packets. -50102 pdp_radio_reset (out_packet_count|1|1) - -# PDP context reset - timed out with no incoming packets. -50103 pdp_context_reset (out_packet_count|1|1) - -# Reregister to data network - timed out with no incoming packets. -50104 pdp_reregister_network (out_packet_count|1|1) - -# PDP Setup failures -50105 pdp_setup_fail (cause|1|5), (cid|1|5), (network_type|1|5) - -# Call drops -50106 call_drop (cause|1|5), (cid|1|5), (network_type|1|5) - -# Data network registration failed after successful voice registration -50107 data_network_registration_fail (op_numeric|1|5), (cid|1|5) - -# Suspicious status of data connection while radio poweroff -50108 data_network_status_on_radio_off (dc_state|3), (enable|1|5) - -# PDP drop caused by network -50109 pdp_network_drop (cid|1|5), (network_type|1|5) - -# CDMA data network setup failure -50110 cdma_data_setup_failed (cause|1|5), (cid|1|5), (network_type|1|5) - -# CDMA data network drop -50111 cdma_data_drop (cid|1|5), (network_type|1|5) - -# GSM radio access technology switched -50112 gsm_rat_switched (cid|1|5), (network_from|1|5), (network_to|1|5) - -# GSM data connection state transition -50113 gsm_data_state_change (oldState|3), (newState|3) - -# GSM service state transition -50114 gsm_service_state_change (oldState|1|5), (oldGprsState|1|5), (newState|1|5), (newGprsState|1|5) - -# CDMA data connection state transition -50115 cdma_data_state_change (oldState|3), (newState|3) - -# CDMA service state transition -50116 cdma_service_state_change (oldState|1|5), (oldDataState|1|5), (newState|1|5), (newDataState|1|5) - -# Bad IP address -50117 bad_ip_address (ip_address|3) - -# Data Stall Recovery mode DATA_STALL_RECOVERY_GET_DATA_CALL_LIST -50118 data_stall_recovery_get_data_call_list (out_packet_count|1|1) - -# Data Stall Recovery mode DATA_STALL_RECOVERY_CLEANUP -50119 data_stall_recovery_cleanup (out_packet_count|1|1) - -# Data Stall Recovery mode DATA_STALL_RECOVERY_REREGISTER -50120 data_stall_recovery_reregister (out_packet_count|1|1) - -# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART -50121 data_stall_recovery_radio_restart (out_packet_count|1|1) - -# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP -50122 data_stall_recovery_radio_restart_with_prop (out_packet_count|1|1) diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java index 25647ac8ad1f..04b12208b253 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java @@ -24,15 +24,12 @@ import android.util.Log; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import com.android.internal.telephony.SmsConstants; import com.android.internal.R; import java.util.ArrayList; import java.util.List; -import static android.telephony.SmsMessage.ENCODING_7BIT; -import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS; -import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER; - /** * This class implements the character set mapping between * the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1 @@ -45,8 +42,6 @@ public class GsmAlphabet { private GsmAlphabet() { } - //***** Constants - /** * This escapes extended characters, and when present indicates that the * following character should be looked up in the "extended" table. @@ -80,6 +75,60 @@ public class GsmAlphabet { */ public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; + /** + * For a specific text string, this object describes protocol + * properties of encoding it for transmission as message user + * data. + */ + public static class TextEncodingDetails { + /** + *The number of SMS's required to encode the text. + */ + public int msgCount; + + /** + * The number of code units consumed so far, where code units + * are basically characters in the encoding -- for example, + * septets for the standard ASCII and GSM encodings, and 16 + * bits for Unicode. + */ + public int codeUnitCount; + + /** + * How many code units are still available without spilling + * into an additional message. + */ + public int codeUnitsRemaining; + + /** + * The encoding code unit size (specified using + * android.telephony.SmsMessage ENCODING_*). + */ + public int codeUnitSize; + + /** + * The GSM national language table to use, or 0 for the default 7-bit alphabet. + */ + public int languageTable; + + /** + * The GSM national language shift table to use, or 0 for the default 7-bit extension table. + */ + public int languageShiftTable; + + @Override + public String toString() { + return "TextEncodingDetails " + + "{ msgCount=" + msgCount + + ", codeUnitCount=" + codeUnitCount + + ", codeUnitsRemaining=" + codeUnitsRemaining + + ", codeUnitSize=" + codeUnitSize + + ", languageTable=" + languageTable + + ", languageShiftTable=" + languageShiftTable + + " }"; + } + } + /** * Converts a char to a GSM 7 bit table index. * Returns ' ' in GSM alphabet if there's no possible match. Returns @@ -752,27 +801,27 @@ public class GsmAlphabet { * character counts for the most efficient 7-bit encoding, * or null if there are no suitable language tables to encode the string. */ - public static SmsMessageBase.TextEncodingDetails + public static TextEncodingDetails countGsmSeptets(CharSequence s, boolean use7bitOnly) { // fast path for common case where no national language shift tables are enabled if (sEnabledSingleShiftTables.length + sEnabledLockingShiftTables.length == 0) { - SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails(); + TextEncodingDetails ted = new TextEncodingDetails(); int septets = GsmAlphabet.countGsmSeptetsUsingTables(s, use7bitOnly, 0, 0); if (septets == -1) { return null; } - ted.codeUnitSize = ENCODING_7BIT; + ted.codeUnitSize = SmsConstants.ENCODING_7BIT; ted.codeUnitCount = septets; - if (septets > MAX_USER_DATA_SEPTETS) { - ted.msgCount = (septets + (MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) / - MAX_USER_DATA_SEPTETS_WITH_HEADER; + if (septets > SmsConstants.MAX_USER_DATA_SEPTETS) { + ted.msgCount = (septets + (SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) / + SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER; ted.codeUnitsRemaining = (ted.msgCount * - MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets; + SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets; } else { ted.msgCount = 1; - ted.codeUnitsRemaining = MAX_USER_DATA_SEPTETS - septets; + ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets; } - ted.codeUnitSize = ENCODING_7BIT; + ted.codeUnitSize = SmsConstants.ENCODING_7BIT; return ted; } @@ -832,9 +881,9 @@ public class GsmAlphabet { } // find the least cost encoding (lowest message count and most code units remaining) - SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails(); + TextEncodingDetails ted = new TextEncodingDetails(); ted.msgCount = Integer.MAX_VALUE; - ted.codeUnitSize = ENCODING_7BIT; + ted.codeUnitSize = SmsConstants.ENCODING_7BIT; int minUnencodableCount = Integer.MAX_VALUE; for (LanguagePairCount lpc : lpcList) { for (int shiftTable = 0; shiftTable <= maxSingleShiftCode; shiftTable++) { @@ -852,17 +901,17 @@ public class GsmAlphabet { } int msgCount; int septetsRemaining; - if (septets + udhLength > MAX_USER_DATA_SEPTETS) { + if (septets + udhLength > SmsConstants.MAX_USER_DATA_SEPTETS) { if (udhLength == 0) { udhLength = UDH_SEPTET_COST_LENGTH; } udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE; - int septetsPerMessage = MAX_USER_DATA_SEPTETS - udhLength; + int septetsPerMessage = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength; msgCount = (septets + septetsPerMessage - 1) / septetsPerMessage; septetsRemaining = (msgCount * septetsPerMessage) - septets; } else { msgCount = 1; - septetsRemaining = MAX_USER_DATA_SEPTETS - udhLength - septets; + septetsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength - septets; } // for 7-bit only mode, use language pair with the least unencodable chars int unencodableCount = lpc.unencodableCounts[shiftTable]; diff --git a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl b/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl deleted file mode 100644 index f700dfefcb2a..000000000000 --- a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl +++ /dev/null @@ -1,101 +0,0 @@ -/* -** 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; - -import com.android.internal.telephony.AdnRecord; - - - -/** Interface for applications to access the ICC phone book. - * - *

The following code snippet demonstrates a static method to - * retrieve the IIccPhoneBook interface from Android:

- *
private static IIccPhoneBook getSimPhoneBookInterface()
-            throws DeadObjectException {
-    IServiceManager sm = ServiceManagerNative.getDefault();
-    IIccPhoneBook spb;
-    spb = IIccPhoneBook.Stub.asInterface(sm.getService("iccphonebook"));
-    return spb;
-}
- * 
- */ - -interface IIccPhoneBook { - - /** - * Loads the AdnRecords in efid and returns them as a - * List of AdnRecords - * - * @param efid the EF id of a ADN-like SIM - * @return List of AdnRecord - */ - List getAdnRecordsInEf(int efid); - - /** - * 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 - * - * @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 - */ - boolean updateAdnRecordsInEfBySearch(int efid, - String oldTag, String oldPhoneNumber, - String newTag, String newPhoneNumber, - String pin2); - - /** - * 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 - * - * @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 - */ - boolean updateAdnRecordsInEfByIndex(int efid, String newTag, - String newPhoneNumber, int index, - String pin2); - - /** - * Get the max munber 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 - */ - int[] getAdnRecordsSize(int efid); - -} diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl old mode 100755 new mode 100644 diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl deleted file mode 100644 index 735f986917bc..000000000000 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ /dev/null @@ -1,201 +0,0 @@ -/* -** 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; - -import android.app.PendingIntent; -import com.android.internal.telephony.SmsRawData; - -/** Interface for applications to access the ICC phone book. - * - *

The following code snippet demonstrates a static method to - * retrieve the ISms interface from Android:

- *
private static ISms getSmsInterface()
-            throws DeadObjectException {
-    IServiceManager sm = ServiceManagerNative.getDefault();
-    ISms ss;
-    ss = ISms.Stub.asInterface(sm.getService("isms"));
-    return ss;
-}
- * 
- */ - -interface ISms { - /** - * Retrieves all messages currently stored on ICC. - * - * @return list of SmsRawData of all sms on ICC - */ - List getAllMessagesFromIccEf(); - - /** - * 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 success or not - * - */ - boolean updateMessageOnIccEf(int messageIndex, int newStatus, - in byte[] pdu); - - /** - * Copy a raw SMS PDU to the ICC. - * - * @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 - * - */ - boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc); - - /** - * Send a data SMS. - * - * @param smsc the SMSC to send the message through, or NULL for the - * default SMSC - * @param data the body of the message to send - * @param sentIntent if not NULL this PendingIntent is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - void sendData(in String destAddr, in String scAddr, in int destPort, - in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent); - - /** - * Send an SMS. - * - * @param smsc the SMSC to send the message through, or NULL for the - * default SMSC - * @param text the body of the message to send - * @param sentIntent if not NULL this PendingIntent is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - void sendText(in String destAddr, in String scAddr, in String text, - in PendingIntent sentIntent, in PendingIntent 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 ArrayList of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an ArrayList of - * PendingIntents (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU. - * @param deliveryIntents if not null, an ArrayList of - * PendingIntents (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(in String destinationAddress, in String scAddress, - in List parts, in List sentIntents, - in List deliveryIntents); - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. - * - * @param messageIdentifier Message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #disableCellBroadcast(int) - */ - boolean enableCellBroadcast(int messageIdentifier); - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier. Note that if two different clients enable the same - * message identifier, they must both disable it for the device to stop - * receiving those messages. - * - * @param messageIdentifier Message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #enableCellBroadcast(int) - */ - boolean disableCellBroadcast(int messageIdentifier); - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range. Note that if two different clients enable - * a message identifier range, they must both disable it for the device - * to stop receiving those messages. - * - * @param startMessageId first message identifier as specified in TS 23.041 - * @param endMessageId last message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #disableCellBroadcastRange(int, int) - */ - boolean enableCellBroadcastRange(int startMessageId, int endMessageId); - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range. Note that if two different clients enable - * a message identifier range, they must both disable it for the device - * to stop receiving those messages. - * - * @param startMessageId first message identifier as specified in TS 23.041 - * @param endMessageId last message identifier as specified in TS 23.041 - * @return true if successful, false otherwise - * - * @see #enableCellBroadcastRange(int, int) - */ - boolean disableCellBroadcastRange(int startMessageId, int endMessageId); - -} diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java deleted file mode 100644 index fcf2f929b1c8..000000000000 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ /dev/null @@ -1,1002 +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; - -import static android.Manifest.permission.READ_PHONE_STATE; -import android.app.ActivityManagerNative; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.RegistrantList; -import android.util.Log; -import android.view.WindowManager; - -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.CommandsInterface.RadioState; -import com.android.internal.telephony.gsm.SIMFileHandler; -import com.android.internal.telephony.gsm.SIMRecords; -import com.android.internal.telephony.cat.CatService; -import com.android.internal.telephony.cdma.CDMALTEPhone; -import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler; -import com.android.internal.telephony.cdma.CdmaLteUiccRecords; -import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; -import com.android.internal.telephony.cdma.RuimFileHandler; -import com.android.internal.telephony.cdma.RuimRecords; - -import android.os.SystemProperties; - -import com.android.internal.R; - -/** - * {@hide} - */ -public class IccCard { - protected String mLogTag; - protected boolean mDbg; - - protected IccCardStatus mIccCardStatus = null; - protected State mState = null; - private final Object mStateMonitor = new Object(); - - protected boolean is3gpp = true; - protected boolean isSubscriptionFromIccCard = true; - protected CdmaSubscriptionSourceManager mCdmaSSM = null; - protected PhoneBase mPhone; - private IccRecords mIccRecords; - private IccFileHandler mIccFileHandler; - private CatService mCatService; - - private RegistrantList mAbsentRegistrants = new RegistrantList(); - private RegistrantList mPinLockedRegistrants = new RegistrantList(); - private RegistrantList mNetworkLockedRegistrants = new RegistrantList(); - protected RegistrantList mReadyRegistrants = new RegistrantList(); - protected RegistrantList mRuimReadyRegistrants = new RegistrantList(); - - private boolean mDesiredPinLocked; - private boolean mDesiredFdnEnabled; - private boolean mIccPinLocked = true; // Default to locked - private boolean mIccFdnEnabled = false; // Default to disabled. - // Will be updated when SIM_READY. - - /* Parameter is3gpp's values to be passed to constructor */ - public final static boolean CARD_IS_3GPP = true; - public final static boolean CARD_IS_NOT_3GPP = false; - - - /* 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) */ - static public final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY"; - /* ABSENT means ICC is missing */ - static public final String INTENT_VALUE_ICC_ABSENT = "ABSENT"; - /* LOCKED means ICC is locked by pin or by network */ - static public final String INTENT_VALUE_ICC_LOCKED = "LOCKED"; - /* READY means ICC is ready to access */ - static public final String INTENT_VALUE_ICC_READY = "READY"; - /* IMSI means ICC IMSI is ready in property */ - static public final String INTENT_VALUE_ICC_IMSI = "IMSI"; - /* LOADED means all ICC records, including IMSI, are loaded */ - static public final String INTENT_VALUE_ICC_LOADED = "LOADED"; - /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */ - static public final String INTENT_KEY_LOCKED_REASON = "reason"; - /* PIN means ICC is locked on PIN1 */ - static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN"; - /* PUK means ICC is locked on PUK1 */ - static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK"; - /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */ - static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK"; - /* PERM_DISABLED means ICC is permanently disabled due to puk fails */ - static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED"; - - - protected static final int EVENT_ICC_LOCKED = 1; - private static final int EVENT_GET_ICC_STATUS_DONE = 2; - protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3; - private static final int EVENT_PINPUK_DONE = 4; - private static final int EVENT_REPOLL_STATUS_DONE = 5; - protected static final int EVENT_ICC_READY = 6; - private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7; - private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8; - private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9; - private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10; - private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11; - private static final int EVENT_ICC_STATUS_CHANGED = 12; - private static final int EVENT_CARD_REMOVED = 13; - private static final int EVENT_CARD_ADDED = 14; - protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 15; - protected static final int EVENT_RADIO_ON = 16; - - /* - UNKNOWN is a transient state, for example, after uesr inputs ICC pin under - PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it - turns to READY - */ - public enum State { - UNKNOWN, - ABSENT, - PIN_REQUIRED, - PUK_REQUIRED, - NETWORK_LOCKED, - READY, - NOT_READY, - PERM_DISABLED; - - public boolean isPinLocked() { - return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)); - } - - public boolean iccCardExist() { - return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED) - || (this == NETWORK_LOCKED) || (this == READY) - || (this == PERM_DISABLED)); - } - } - - public State getState() { - if (mState == null) { - switch(mPhone.mCM.getRadioState()) { - /* This switch block must not return anything in - * State.isLocked() or State.ABSENT. - * If it does, handleSimStatus() may break - */ - case RADIO_OFF: - case RADIO_UNAVAILABLE: - return State.UNKNOWN; - default: - if (!is3gpp && !isSubscriptionFromIccCard) { - // CDMA can get subscription from NV. In that case, - // subscription is ready as soon as Radio is ON. - return State.READY; - } - } - } else { - return mState; - } - - return State.UNKNOWN; - } - - public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) { - mLogTag = logTag; - mDbg = dbg; - if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2")); - mPhone = phone; - this.is3gpp = is3gpp; - mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(), - mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); - if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE - && phone instanceof CDMALTEPhone) { - mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM); - mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM); - } else { - // Correct aid will be set later (when GET_SIM_STATUS returns) - mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) : - new RuimFileHandler(this, "", mPhone.mCM); - mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) : - new RuimRecords(this, mPhone.mContext, mPhone.mCM); - } - mCatService = CatService.getInstance(mPhone.mCM, mIccRecords, - mPhone.mContext, mIccFileHandler, this); - mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null); - mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null); - } - - public void dispose() { - if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2")); - mPhone.mCM.unregisterForIccStatusChanged(mHandler); - mPhone.mCM.unregisterForOffOrNotAvailable(mHandler); - mPhone.mCM.unregisterForOn(mHandler); - mCatService.dispose(); - mCdmaSSM.dispose(mHandler); - mIccRecords.dispose(); - mIccFileHandler.dispose(); - } - - protected void finalize() { - if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2")); - } - - public IccRecords getIccRecords() { - return mIccRecords; - } - - public IccFileHandler getIccFileHandler() { - return mIccFileHandler; - } - - /** - * Notifies handler of any transition into State.ABSENT - */ - public void registerForAbsent(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mAbsentRegistrants.add(r); - - if (getState() == State.ABSENT) { - r.notifyRegistrant(); - } - } - - public void unregisterForAbsent(Handler h) { - mAbsentRegistrants.remove(h); - } - - /** - * Notifies handler of any transition into State.NETWORK_LOCKED - */ - public void registerForNetworkLocked(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mNetworkLockedRegistrants.add(r); - - if (getState() == State.NETWORK_LOCKED) { - r.notifyRegistrant(); - } - } - - public void unregisterForNetworkLocked(Handler h) { - mNetworkLockedRegistrants.remove(h); - } - - /** - * Notifies handler of any transition into State.isPinLocked() - */ - public void registerForLocked(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - mPinLockedRegistrants.add(r); - - if (getState().isPinLocked()) { - r.notifyRegistrant(); - } - } - - public void unregisterForLocked(Handler h) { - mPinLockedRegistrants.remove(h); - } - - public void registerForReady(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mReadyRegistrants.add(r); - - if (getState() == State.READY) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void unregisterForReady(Handler h) { - synchronized (mStateMonitor) { - mReadyRegistrants.remove(h); - } - } - - public State getRuimState() { - if(mIccCardStatus != null) { - return getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex()); - } else { - return State.UNKNOWN; - } - } - - public void registerForRuimReady(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mRuimReadyRegistrants.add(r); - - if (getState() == State.READY && getRuimState() == State.READY ) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void unregisterForRuimReady(Handler h) { - synchronized (mStateMonitor) { - mRuimReadyRegistrants.remove(h); - } - } - - /** - * Supply the ICC PIN to the ICC - * - * When the operation is complete, onComplete will be sent to its - * Handler. - * - * onComplete.obj will be an AsyncResult - * - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - * - * If the supplied PIN is incorrect: - * ((AsyncResult)onComplete.obj).exception != null - * && ((AsyncResult)onComplete.obj).exception - * instanceof com.android.internal.telephony.gsm.CommandException) - * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) - * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT - * - * - */ - - public void supplyPin (String pin, Message onComplete) { - mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyPuk (String puk, String newPin, Message onComplete) { - mPhone.mCM.supplyIccPuk(puk, newPin, - mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyPin2 (String pin2, Message onComplete) { - mPhone.mCM.supplyIccPin2(pin2, - mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyPuk2 (String puk2, String newPin2, Message onComplete) { - mPhone.mCM.supplyIccPuk2(puk2, newPin2, - mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyNetworkDepersonalization (String pin, Message onComplete) { - mPhone.mCM.supplyNetworkDepersonalization(pin, - mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - /** - * Check whether ICC pin lock is enabled - * This is a sync call which returns the cached pin enabled state - * - * @return true for ICC locked enabled - * false for ICC locked disabled - */ - public boolean getIccLockEnabled() { - return mIccPinLocked; - } - - /** - * Check whether ICC fdn (fixed dialing number) is enabled - * This is a sync call which returns the cached pin enabled state - * - * @return true for ICC fdn enabled - * false for ICC fdn disabled - */ - public boolean getIccFdnEnabled() { - return mIccFdnEnabled; - } - - /** - * Set the ICC pin lock enabled or disabled - * When the operation is complete, onComplete will be sent to its handler - * - * @param enabled "true" for locked "false" for unlocked. - * @param password needed to change the ICC pin state, aka. Pin1 - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setIccLockEnabled (boolean enabled, - String password, Message onComplete) { - int serviceClassX; - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX; - - mDesiredPinLocked = enabled; - - mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM, - enabled, password, serviceClassX, - mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete)); - } - - /** - * Set the ICC fdn enabled or disabled - * When the operation is complete, onComplete will be sent to its handler - * - * @param enabled "true" for locked "false" for unlocked. - * @param password needed to change the ICC fdn enable, aka Pin2 - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setIccFdnEnabled (boolean enabled, - String password, Message onComplete) { - int serviceClassX; - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX + - CommandsInterface.SERVICE_CLASS_SMS; - - mDesiredFdnEnabled = enabled; - - mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD, - enabled, password, serviceClassX, - mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete)); - } - - /** - * Change the ICC password used in ICC pin lock - * When the operation is complete, onComplete will be sent to its handler - * - * @param oldPassword is the old password - * @param newPassword is the new password - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void changeIccLockPassword(String oldPassword, String newPassword, - Message onComplete) { - mPhone.mCM.changeIccPin(oldPassword, newPassword, - mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete)); - - } - - /** - * Change the ICC password used in ICC fdn enable - * When the operation is complete, onComplete will be sent to its handler - * - * @param oldPassword is the old password - * @param newPassword is the new password - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void changeIccFdnPassword(String oldPassword, String newPassword, - Message onComplete) { - mPhone.mCM.changeIccPin2(oldPassword, newPassword, - mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete)); - - } - - - /** - * Returns service provider name stored in ICC card. - * If there is no service provider name associated or the record is not - * yet available, null will be returned

- * - * Please use this value when display Service Provider Name in idle mode

- * - * Usage of this provider name in the UI is a common carrier requirement. - * - * Also available via Android property "gsm.sim.operator.alpha" - * - * @return Service Provider Name stored in ICC card - * null if no service provider name associated or the record is not - * yet available - * - */ - public String getServiceProviderName () { - return mPhone.mIccRecords.getServiceProviderName(); - } - - protected void updateStateProperty() { - mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString()); - } - - private void getIccCardStatusDone(AsyncResult ar) { - if (ar.exception != null) { - Log.e(mLogTag,"Error getting ICC status. " - + "RIL_REQUEST_GET_ICC_STATUS should " - + "never return an error", ar.exception); - return; - } - handleIccCardStatus((IccCardStatus) ar.result); - } - - private void handleIccCardStatus(IccCardStatus newCardStatus) { - boolean transitionedIntoPinLocked; - boolean transitionedIntoAbsent; - boolean transitionedIntoNetworkLocked; - boolean transitionedIntoPermBlocked; - boolean isIccCardRemoved; - boolean isIccCardAdded; - - State oldState, newState; - State oldRuimState = getRuimState(); - - oldState = mState; - mIccCardStatus = newCardStatus; - newState = getIccCardState(); - - synchronized (mStateMonitor) { - mState = newState; - updateStateProperty(); - if (oldState != State.READY && newState == State.READY) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_READY)); - mReadyRegistrants.notifyRegistrants(); - } else if (newState.isPinLocked()) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_LOCKED)); - } - if (oldRuimState != State.READY && getRuimState() == State.READY) { - mRuimReadyRegistrants.notifyRegistrants(); - } - } - - transitionedIntoPinLocked = ( - (oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED) - || (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED)); - transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT); - transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED - && newState == State.NETWORK_LOCKED); - transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED - && newState == State.PERM_DISABLED); - isIccCardRemoved = (oldState != null && - oldState.iccCardExist() && newState == State.ABSENT); - isIccCardAdded = (oldState == State.ABSENT && - newState != null && newState.iccCardExist()); - - if (transitionedIntoPinLocked) { - if (mDbg) log("Notify SIM pin or puk locked."); - mPinLockedRegistrants.notifyRegistrants(); - broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED, - (newState == State.PIN_REQUIRED) ? - INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK); - } else if (transitionedIntoAbsent) { - if (mDbg) log("Notify SIM missing."); - mAbsentRegistrants.notifyRegistrants(); - broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, null); - } else if (transitionedIntoNetworkLocked) { - if (mDbg) log("Notify SIM network locked."); - mNetworkLockedRegistrants.notifyRegistrants(); - broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED, - INTENT_VALUE_LOCKED_NETWORK); - } else if (transitionedIntoPermBlocked) { - if (mDbg) log("Notify SIM permanently disabled."); - broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, - INTENT_VALUE_ABSENT_ON_PERM_DISABLED); - } - - if (isIccCardRemoved) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); - } else if (isIccCardAdded) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); - } - - // Call onReady Record(s) on the IccCard becomes ready (not NV) - if (oldState != State.READY && newState == State.READY && - (is3gpp || isSubscriptionFromIccCard)) { - if (!(mIccFileHandler instanceof CdmaLteUiccFileHandler)) { - // CdmaLteUicc File Handler deals with both USIM and CSIM. - // Do not lock onto one AID for now. - mIccFileHandler.setAid(getAid()); - } - mIccRecords.onReady(); - } - } - - private void onIccSwap(boolean isAdded) { - // TODO: Here we assume the device can't handle SIM hot-swap - // and has to reboot. We may want to add a property, - // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support - // hot-swap. - DialogInterface.OnClickListener listener = null; - - - // TODO: SimRecords is not reset while SIM ABSENT (only reset while - // Radio_off_or_not_available). Have to reset in both both - // added or removed situation. - listener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - if (mDbg) log("Reboot due to SIM swap"); - PowerManager pm = (PowerManager) mPhone.getContext() - .getSystemService(Context.POWER_SERVICE); - pm.reboot("SIM is added."); - } - } - - }; - - Resources r = Resources.getSystem(); - - String title = (isAdded) ? r.getString(R.string.sim_added_title) : - r.getString(R.string.sim_removed_title); - String message = (isAdded) ? r.getString(R.string.sim_added_message) : - r.getString(R.string.sim_removed_message); - String buttonTxt = r.getString(R.string.sim_restart_button); - - AlertDialog dialog = new AlertDialog.Builder(mPhone.getContext()) - .setTitle(title) - .setMessage(message) - .setPositiveButton(buttonTxt, listener) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - dialog.show(); - } - - /** - * Interperate EVENT_QUERY_FACILITY_LOCK_DONE - * @param ar is asyncResult of Query_Facility_Locked - */ - private void onQueryFdnEnabled(AsyncResult ar) { - if(ar.exception != null) { - if(mDbg) log("Error in querying facility lock:" + ar.exception); - return; - } - - int[] ints = (int[])ar.result; - if(ints.length != 0) { - mIccFdnEnabled = (0!=ints[0]); - if(mDbg) log("Query facility lock : " + mIccFdnEnabled); - } else { - Log.e(mLogTag, "[IccCard] Bogus facility lock response"); - } - } - - /** - * Interperate EVENT_QUERY_FACILITY_LOCK_DONE - * @param ar is asyncResult of Query_Facility_Locked - */ - private void onQueryFacilityLock(AsyncResult ar) { - if(ar.exception != null) { - if (mDbg) log("Error in querying facility lock:" + ar.exception); - return; - } - - int[] ints = (int[])ar.result; - if(ints.length != 0) { - mIccPinLocked = (0!=ints[0]); - if(mDbg) log("Query facility lock : " + mIccPinLocked); - } else { - Log.e(mLogTag, "[IccCard] Bogus facility lock response"); - } - } - - public void broadcastIccStateChangedIntent(String value, String reason) { - Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName()); - intent.putExtra(INTENT_KEY_ICC_STATE, value); - intent.putExtra(INTENT_KEY_LOCKED_REASON, reason); - if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value - + " reason " + reason); - ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE); - } - - protected Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg){ - AsyncResult ar; - int serviceClassX; - - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX; - - if (!mPhone.mIsTheCurrentActivePhone) { - Log.e(mLogTag, "Received message " + msg + "[" + msg.what - + "] while being destroyed. Ignoring."); - return; - } - - switch (msg.what) { - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - mState = null; - updateStateProperty(); - broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null); - break; - case EVENT_RADIO_ON: - if (!is3gpp) { - handleCdmaSubscriptionSource(); - } - mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE)); - break; - case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: - handleCdmaSubscriptionSource(); - break; - case EVENT_ICC_READY: - if(isSubscriptionFromIccCard) { - mPhone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE)); - mPhone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE)); - } - break; - case EVENT_ICC_LOCKED: - mPhone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE)); - break; - case EVENT_GET_ICC_STATUS_DONE: - ar = (AsyncResult)msg.obj; - - getIccCardStatusDone(ar); - break; - case EVENT_PINPUK_DONE: - // a PIN/PUK/PIN2/PUK2/Network Personalization - // request has completed. ar.userObj is the response Message - // Repoll before returning - ar = (AsyncResult)msg.obj; - // TODO should abstract these exceptions - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - mPhone.mCM.getIccCardStatus( - obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj)); - break; - case EVENT_REPOLL_STATUS_DONE: - // Finished repolling status after PIN operation - // ar.userObj is the response messaeg - // ar.userObj.obj is already an AsyncResult with an - // appropriate exception filled in if applicable - - ar = (AsyncResult)msg.obj; - getIccCardStatusDone(ar); - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_QUERY_FACILITY_LOCK_DONE: - ar = (AsyncResult)msg.obj; - onQueryFacilityLock(ar); - break; - case EVENT_QUERY_FACILITY_FDN_DONE: - ar = (AsyncResult)msg.obj; - onQueryFdnEnabled(ar); - break; - case EVENT_CHANGE_FACILITY_LOCK_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - mIccPinLocked = mDesiredPinLocked; - if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " + - "mIccPinLocked= " + mIccPinLocked); - } else { - Log.e(mLogTag, "Error change facility lock with exception " - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_CHANGE_FACILITY_FDN_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception == null) { - mIccFdnEnabled = mDesiredFdnEnabled; - if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " + - "mIccFdnEnabled=" + mIccFdnEnabled); - } else { - Log.e(mLogTag, "Error change facility fdn with exception " - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_CHANGE_ICC_PASSWORD_DONE: - ar = (AsyncResult)msg.obj; - if(ar.exception != null) { - Log.e(mLogTag, "Error in change sim password with exception" - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_ICC_STATUS_CHANGED: - Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED"); - mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE)); - break; - case EVENT_CARD_REMOVED: - onIccSwap(false); - break; - case EVENT_CARD_ADDED: - onIccSwap(true); - break; - default: - Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what); - } - } - }; - - private void handleCdmaSubscriptionSource() { - if(mCdmaSSM != null) { - int newSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource(); - - Log.d(mLogTag, "Received Cdma subscription source: " + newSubscriptionSource); - - boolean isNewSubFromRuim = - (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM); - - if (isNewSubFromRuim != isSubscriptionFromIccCard) { - isSubscriptionFromIccCard = isNewSubFromRuim; - // Parse the Stored IccCardStatus Message to set mState correctly. - handleIccCardStatus(mIccCardStatus); - } - } - } - - public State getIccCardState() { - if(!is3gpp && !isSubscriptionFromIccCard) { - // CDMA can get subscription from NV. In that case, - // subscription is ready as soon as Radio is ON. - return State.READY; - } - - if (mIccCardStatus == null) { - Log.e(mLogTag, "[IccCard] IccCardStatus is null"); - return IccCard.State.ABSENT; - } - - // this is common for all radio technologies - if (!mIccCardStatus.getCardState().isCardPresent()) { - return IccCard.State.ABSENT; - } - - RadioState currentRadioState = mPhone.mCM.getRadioState(); - // check radio technology - if( currentRadioState == RadioState.RADIO_OFF || - currentRadioState == RadioState.RADIO_UNAVAILABLE) { - return IccCard.State.NOT_READY; - } - - if( currentRadioState == RadioState.RADIO_ON ) { - State csimState = - getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex()); - State usimState = - getAppState(mIccCardStatus.getGsmUmtsSubscriptionAppIndex()); - - if(mDbg) log("USIM=" + usimState + " CSIM=" + csimState); - - if (mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) { - // UICC card contains both USIM and CSIM - // Return consolidated status - return getConsolidatedState(csimState, usimState, csimState); - } - - // check for CDMA radio technology - if (!is3gpp) { - return csimState; - } - return usimState; - } - - return IccCard.State.ABSENT; - } - - private State getAppState(int appIndex) { - IccCardApplication app; - if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) { - app = mIccCardStatus.getApplication(appIndex); - } else { - Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + appIndex); - return IccCard.State.ABSENT; - } - - if (app == null) { - Log.e(mLogTag, "[IccCard] Subscription Application in not present"); - return IccCard.State.ABSENT; - } - - // check if PIN required - if (app.pin1.isPermBlocked()) { - return IccCard.State.PERM_DISABLED; - } - if (app.app_state.isPinRequired()) { - return IccCard.State.PIN_REQUIRED; - } - if (app.app_state.isPukRequired()) { - return IccCard.State.PUK_REQUIRED; - } - if (app.app_state.isSubscriptionPersoEnabled()) { - return IccCard.State.NETWORK_LOCKED; - } - if (app.app_state.isAppReady()) { - return IccCard.State.READY; - } - if (app.app_state.isAppNotReady()) { - return IccCard.State.NOT_READY; - } - return IccCard.State.NOT_READY; - } - - private State getConsolidatedState(State left, State right, State preferredState) { - // Check if either is absent. - if (right == IccCard.State.ABSENT) return left; - if (left == IccCard.State.ABSENT) return right; - - // Only if both are ready, return ready - if ((left == IccCard.State.READY) && (right == IccCard.State.READY)) { - return State.READY; - } - - // Case one is ready, but the other is not. - if (((right == IccCard.State.NOT_READY) && (left == IccCard.State.READY)) || - ((left == IccCard.State.NOT_READY) && (right == IccCard.State.READY))) { - return IccCard.State.NOT_READY; - } - - // At this point, the other state is assumed to be one of locked state - if (right == IccCard.State.NOT_READY) return left; - if (left == IccCard.State.NOT_READY) return right; - - // At this point, FW currently just assumes the status will be - // consistent across the applications... - return preferredState; - } - - public boolean isApplicationOnIcc(IccCardApplication.AppType type) { - if (mIccCardStatus == null) return false; - - for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) { - IccCardApplication app = mIccCardStatus.getApplication(i); - if (app != null && app.app_type == type) { - return true; - } - } - return false; - } - - /** - * @return true if a ICC card is present - */ - public boolean hasIccCard() { - if (mIccCardStatus == null) { - return false; - } else { - // Returns ICC card status for both GSM and CDMA mode - return mIccCardStatus.getCardState().isCardPresent(); - } - } - - private void log(String msg) { - Log.d(mLogTag, "[IccCard] " + msg); - } - - protected int getCurrentApplicationIndex() { - if (is3gpp) { - return mIccCardStatus.getGsmUmtsSubscriptionAppIndex(); - } else { - return mIccCardStatus.getCdmaSubscriptionAppIndex(); - } - } - - public String getAid() { - String aid = ""; - if (mIccCardStatus == null) { - return aid; - } - - int appIndex = getCurrentApplicationIndex(); - - if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) { - IccCardApplication app = mIccCardStatus.getApplication(appIndex); - if (app != null) { - aid = app.aid; - } else { - Log.e(mLogTag, "[IccCard] getAid: no current application index=" + appIndex); - } - } else { - Log.e(mLogTag, "[IccCard] getAid: Invalid Subscription Application index=" + appIndex); - } - - return aid; - } -} diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java deleted file mode 100644 index abb740ef0c32..000000000000 --- a/telephony/java/com/android/internal/telephony/IccCardApplication.java +++ /dev/null @@ -1,226 +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; - -import com.android.internal.telephony.IccCardStatus.PinState; - - -/** - * See also RIL_AppStatus in include/telephony/ril.h - * - * {@hide} - */ -public class IccCardApplication { - public enum AppType{ - APPTYPE_UNKNOWN, - APPTYPE_SIM, - APPTYPE_USIM, - APPTYPE_RUIM, - APPTYPE_CSIM, - APPTYPE_ISIM - }; - - public enum AppState{ - APPSTATE_UNKNOWN, - APPSTATE_DETECTED, - APPSTATE_PIN, - 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; - } - - boolean isAppReady() { - return this == APPSTATE_READY; - } - - boolean isAppNotReady() { - return this == APPSTATE_UNKNOWN || - this == APPSTATE_DETECTED; - } - }; - - public enum PersoSubState{ - PERSOSUBSTATE_UNKNOWN, - PERSOSUBSTATE_IN_PROGRESS, - PERSOSUBSTATE_READY, - PERSOSUBSTATE_SIM_NETWORK, - PERSOSUBSTATE_SIM_NETWORK_SUBSET, - PERSOSUBSTATE_SIM_CORPORATE, - PERSOSUBSTATE_SIM_SERVICE_PROVIDER, - PERSOSUBSTATE_SIM_SIM, - PERSOSUBSTATE_SIM_NETWORK_PUK, - PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK, - PERSOSUBSTATE_SIM_CORPORATE_PUK, - PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK, - PERSOSUBSTATE_SIM_SIM_PUK, - PERSOSUBSTATE_RUIM_NETWORK1, - PERSOSUBSTATE_RUIM_NETWORK2, - PERSOSUBSTATE_RUIM_HRPD, - PERSOSUBSTATE_RUIM_CORPORATE, - PERSOSUBSTATE_RUIM_SERVICE_PROVIDER, - PERSOSUBSTATE_RUIM_RUIM, - PERSOSUBSTATE_RUIM_NETWORK1_PUK, - PERSOSUBSTATE_RUIM_NETWORK2_PUK, - PERSOSUBSTATE_RUIM_HRPD_PUK, - 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; - // 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 */ - public String aid; - // null terminated string - public String app_label; - // applicable to USIM and CSIM - public int pin1_replaced; - public PinState pin1; - public PinState pin2; - - AppType AppTypeFromRILInt(int type) { - AppType newType; - /* RIL_AppType ril.h */ - switch(type) { - case 0: newType = AppType.APPTYPE_UNKNOWN; break; - case 1: newType = AppType.APPTYPE_SIM; break; - case 2: newType = AppType.APPTYPE_USIM; break; - case 3: newType = AppType.APPTYPE_RUIM; break; - case 4: newType = AppType.APPTYPE_CSIM; break; - case 5: newType = AppType.APPTYPE_ISIM; break; - default: - throw new RuntimeException( - "Unrecognized RIL_AppType: " +type); - } - return newType; - } - - AppState AppStateFromRILInt(int state) { - AppState newState; - /* RIL_AppState ril.h */ - switch(state) { - case 0: newState = AppState.APPSTATE_UNKNOWN; break; - case 1: newState = AppState.APPSTATE_DETECTED; break; - case 2: newState = AppState.APPSTATE_PIN; break; - case 3: newState = AppState.APPSTATE_PUK; break; - case 4: newState = AppState.APPSTATE_SUBSCRIPTION_PERSO; break; - case 5: newState = AppState.APPSTATE_READY; break; - default: - throw new RuntimeException( - "Unrecognized RIL_AppState: " +state); - } - return newState; - } - - PersoSubState PersoSubstateFromRILInt(int substate) { - PersoSubState newSubState; - /* RIL_PeroSubstate ril.h */ - switch(substate) { - case 0: newSubState = PersoSubState.PERSOSUBSTATE_UNKNOWN; break; - case 1: newSubState = PersoSubState.PERSOSUBSTATE_IN_PROGRESS; break; - case 2: newSubState = PersoSubState.PERSOSUBSTATE_READY; break; - case 3: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK; break; - case 4: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET; break; - case 5: newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE; break; - case 6: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER; break; - case 7: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM; break; - case 8: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_PUK; break; - case 9: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK; break; - case 10: newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE_PUK; break; - case 11: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK; break; - case 12: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM_PUK; break; - case 13: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1; break; - 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 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; - case 21: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD_PUK ; break; - 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: - throw new RuntimeException( - "Unrecognized RIL_PersoSubstate: " +substate); - } - return newSubState; - } - - PinState PinStateFromRILInt(int state) { - PinState newPinState; - switch(state) { - case 0: - newPinState = PinState.PINSTATE_UNKNOWN; - break; - case 1: - newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; - break; - case 2: - newPinState = PinState.PINSTATE_ENABLED_VERIFIED; - break; - case 3: - newPinState = PinState.PINSTATE_DISABLED; - break; - case 4: - newPinState = PinState.PINSTATE_ENABLED_BLOCKED; - break; - case 5: - newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; - break; - default: - throw new RuntimeException("Unrecognized RIL_PinState: " + state); - } - return newPinState; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("{").append(app_type).append(",").append(app_state); - if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) { - sb.append(",").append(perso_substate); - } - if (app_type == AppType.APPTYPE_CSIM || - app_type == AppType.APPTYPE_USIM || - app_type == AppType.APPTYPE_ISIM) { - sb.append(",pin1=").append(pin1); - sb.append(",pin2=").append(pin2); - } - sb.append("}"); - return sb.toString(); - } -} diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java new file mode 100644 index 000000000000..20439bc40a17 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 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; + +/** + * {@hide} + */ +public class IccCardConstants { + + /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */ + public static final String INTENT_KEY_ICC_STATE = "ss"; + /* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */ + public static final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY"; + /* ABSENT means ICC is missing */ + public static final String INTENT_VALUE_ICC_ABSENT = "ABSENT"; + /* LOCKED means ICC is locked by pin or by network */ + public static final String INTENT_VALUE_ICC_LOCKED = "LOCKED"; + /* READY means ICC is ready to access */ + public static final String INTENT_VALUE_ICC_READY = "READY"; + /* IMSI means ICC IMSI is ready in property */ + public static final String INTENT_VALUE_ICC_IMSI = "IMSI"; + /* LOADED means all ICC records, including IMSI, are loaded */ + public static final String INTENT_VALUE_ICC_LOADED = "LOADED"; + /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */ + public static final String INTENT_KEY_LOCKED_REASON = "reason"; + /* PIN means ICC is locked on PIN1 */ + public static final String INTENT_VALUE_LOCKED_ON_PIN = "PIN"; + /* PUK means ICC is locked on PUK1 */ + public static final String INTENT_VALUE_LOCKED_ON_PUK = "PUK"; + /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */ + public static final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK"; + /* PERM_DISABLED means ICC is permanently disabled due to puk fails */ + public static final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED"; + + /* + UNKNOWN is a transient state, for example, after uesr inputs ICC pin under + PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it + turns to READY + */ + public enum State { + UNKNOWN, + ABSENT, + PIN_REQUIRED, + PUK_REQUIRED, + NETWORK_LOCKED, + READY, + NOT_READY, + PERM_DISABLED; + + public boolean isPinLocked() { + return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)); + } + + public boolean iccCardExist() { + return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED) + || (this == NETWORK_LOCKED) || (this == READY) + || (this == PERM_DISABLED)); + } + } +} diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java deleted file mode 100644 index a3bdd76b6e00..000000000000 --- a/telephony/java/com/android/internal/telephony/IccCardStatus.java +++ /dev/null @@ -1,188 +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; - -import java.util.ArrayList; - -/** - * See also RIL_CardStatus in include/telephony/ril.h - * - * {@hide} - */ -public class IccCardStatus { - public static final int CARD_MAX_APPS = 8; - - public enum CardState { - CARDSTATE_ABSENT, - CARDSTATE_PRESENT, - CARDSTATE_ERROR; - - boolean isCardPresent() { - return this == CARDSTATE_PRESENT; - } - } - - public enum PinState { - PINSTATE_UNKNOWN, - PINSTATE_ENABLED_NOT_VERIFIED, - PINSTATE_ENABLED_VERIFIED, - PINSTATE_DISABLED, - PINSTATE_ENABLED_BLOCKED, - PINSTATE_ENABLED_PERM_BLOCKED; - - boolean isPermBlocked() { - return this == PINSTATE_ENABLED_PERM_BLOCKED; - } - - boolean isPinRequired() { - return this == PINSTATE_ENABLED_NOT_VERIFIED; - } - - boolean isPukRequired() { - return this == PINSTATE_ENABLED_BLOCKED; - } - } - - private CardState mCardState; - private PinState mUniversalPinState; - private int mGsmUmtsSubscriptionAppIndex; - private int mCdmaSubscriptionAppIndex; - private int mImsSubscriptionAppIndex; - private int mNumApplications; - - private ArrayList mApplications = - new ArrayList(CARD_MAX_APPS); - - public CardState getCardState() { - return mCardState; - } - - public void setCardState(int state) { - switch(state) { - case 0: - mCardState = CardState.CARDSTATE_ABSENT; - break; - case 1: - mCardState = CardState.CARDSTATE_PRESENT; - break; - case 2: - mCardState = CardState.CARDSTATE_ERROR; - break; - default: - throw new RuntimeException("Unrecognized RIL_CardState: " + state); - } - } - - public PinState getUniversalPinState() { - return mUniversalPinState; - } - - public void setUniversalPinState(int state) { - switch(state) { - case 0: - mUniversalPinState = PinState.PINSTATE_UNKNOWN; - break; - case 1: - mUniversalPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; - break; - case 2: - mUniversalPinState = PinState.PINSTATE_ENABLED_VERIFIED; - break; - case 3: - mUniversalPinState = PinState.PINSTATE_DISABLED; - break; - case 4: - mUniversalPinState = PinState.PINSTATE_ENABLED_BLOCKED; - break; - case 5: - mUniversalPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; - break; - default: - throw new RuntimeException("Unrecognized RIL_PinState: " + state); - } - } - - public int getGsmUmtsSubscriptionAppIndex() { - return mGsmUmtsSubscriptionAppIndex; - } - - public void setGsmUmtsSubscriptionAppIndex(int gsmUmtsSubscriptionAppIndex) { - mGsmUmtsSubscriptionAppIndex = gsmUmtsSubscriptionAppIndex; - } - - public int getCdmaSubscriptionAppIndex() { - return mCdmaSubscriptionAppIndex; - } - - public void setCdmaSubscriptionAppIndex(int cdmaSubscriptionAppIndex) { - mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex; - } - - public int getImsSubscriptionAppIndex() { - return mImsSubscriptionAppIndex; - } - - public void setImsSubscriptionAppIndex(int imsSubscriptionAppIndex) { - mImsSubscriptionAppIndex = imsSubscriptionAppIndex; - } - - public int getNumApplications() { - return mNumApplications; - } - - public void setNumApplications(int numApplications) { - mNumApplications = numApplications; - } - - public void addApplication(IccCardApplication application) { - mApplications.add(application); - } - - public IccCardApplication getApplication(int index) { - return mApplications.get(index); - } - - @Override - public String toString() { - IccCardApplication app; - - StringBuilder sb = new StringBuilder(); - sb.append("IccCardState {").append(mCardState).append(",") - .append(mUniversalPinState) - .append(",num_apps=").append(mNumApplications) - .append(",gsm_id=").append(mGsmUmtsSubscriptionAppIndex); - if (mGsmUmtsSubscriptionAppIndex >=0 - && mGsmUmtsSubscriptionAppIndex 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(IccCard card, String aid, CommandsInterface ci) { - mParentCard = card; - mAid = aid; - mCi = ci; - } - - 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)); - - mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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)); - - // TODO(): Verify when path changes are done. - mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img", - recordNum, READ_RECORD_MODE_ABSOLUTE, - GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, mAid, 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)); - mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); - } - - /** - * Load all records from a SIM Linear Fixed EF - * - * @param fileid EF id - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is an ArrayList - * - */ - public void loadEFLinearFixedAll(int fileid, Message onLoaded) { - Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, - new LoadLinearFixedContext(fileid,onLoaded)); - - mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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); - - mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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); - - mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset, - length, null, null, mAid, 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) { - mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid), - recordNum, READ_RECORD_MODE_ABSOLUTE, data.length, - IccUtils.bytesToHexString(data), pin2, mAid, 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) { - mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid), - 0, 0, data.length, - IccUtils.bytesToHexString(data), null, mAid, onComplete); - } - - - //***** Abstract Methods - - - //***** 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(lc.countRecords); - } - - mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid), - lc.recordNum, - READ_RECORD_MODE_ABSOLUTE, - lc.recordSize, null, null, mAid, - 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); - - mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), - 0, 0, size, null, null, mAid, - 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 { - mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid), - lc.recordNum, - READ_RECORD_MODE_ABSOLUTE, - lc.recordSize, null, null, mAid, - 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); - } - } - } - - /** - * Returns the root path of the EF file. - * i.e returns MasterFile + DFfile as a string. - * Ex: For EF_ADN on a SIM, it will return "3F007F10" - * This function handles only EFids that are common to - * RUIM, SIM, USIM and other types of Icc cards. - * - * @param efId - * @return root path of the file. - */ - protected String getCommonIccEFPath(int efid) { - switch(efid) { - case EF_ADN: - case EF_FDN: - case EF_MSISDN: - case EF_SDN: - case EF_EXT1: - case EF_EXT2: - case EF_EXT3: - return MF_SIM + DF_TELECOM; - - case EF_ICCID: - case EF_PL: - return MF_SIM; - case EF_IMG: - return MF_SIM + DF_TELECOM + DF_GRAPHICS; - } - return null; - } - - protected abstract String getEFPath(int efid); - protected abstract void logd(String s); - - protected abstract void loge(String s); - protected void setAid(String aid) { - mAid = aid; - } - -} diff --git a/telephony/java/com/android/internal/telephony/IccFileNotFound.java b/telephony/java/com/android/internal/telephony/IccFileNotFound.java deleted file mode 100644 index 915cea688284..000000000000 --- a/telephony/java/com/android/internal/telephony/IccFileNotFound.java +++ /dev/null @@ -1,34 +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; - -/** - * {@hide} - */ -public class IccFileNotFound extends IccException { - IccFileNotFound() { - - } - - IccFileNotFound(String s) { - super(s); - } - - IccFileNotFound(int ef) { - super("ICC EF Not Found 0x" + Integer.toHexString(ef)); - } -} diff --git a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java b/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java deleted file mode 100644 index 66fcfa9d568d..000000000000 --- a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java +++ /dev/null @@ -1,30 +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; - -/** - * {@hide} - */ -public class IccFileTypeMismatch extends IccException { - public IccFileTypeMismatch() { - - } - - public IccFileTypeMismatch(String s) { - super(s); - } -} diff --git a/telephony/java/com/android/internal/telephony/IccIoResult.java b/telephony/java/com/android/internal/telephony/IccIoResult.java deleted file mode 100644 index 7043da53f0e0..000000000000 --- a/telephony/java/com/android/internal/telephony/IccIoResult.java +++ /dev/null @@ -1,70 +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; - -/** - * {@hide} - */ -public class -IccIoResult { - public int sw1; - public int sw2; - - public byte[] payload; - - public IccIoResult(int sw1, int sw2, byte[] payload) { - this.sw1 = sw1; - this.sw2 = sw2; - this.payload = payload; - } - - public IccIoResult(int sw1, int sw2, String hexString) { - this(sw1, sw2, IccUtils.hexStringToBytes(hexString)); - } - - public String toString() { - return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x" - + Integer.toHexString(sw2); - } - - /** - * true if this operation was successful - * See GSM 11.11 Section 9.4 - * (the fun stuff is absent in 51.011) - */ - public boolean success() { - return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f; - } - - /** - * Returns exception on error or null if success - */ - public IccException getException() { - if (success()) return null; - - switch (sw1) { - case 0x94: - if (sw2 == 0x08) { - return new IccFileTypeMismatch(); - } else { - return new IccFileNotFound(); - } - default: - return new IccException("sw1:" + sw1 + " sw2:" + sw2); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java deleted file mode 100644 index 45562ca96e44..000000000000 --- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java +++ /dev/null @@ -1,289 +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; - -import android.content.pm.PackageManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.ServiceManager; - -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * SimPhoneBookInterfaceManager to provide an inter-process communication to - * 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 final Object mLock = new Object(); - protected int recordSize[]; - protected boolean success; - protected List 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]); - } - notifyPending(ar); - } - break; - case EVENT_UPDATE_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - success = (ar.exception == null); - notifyPending(ar); - } - break; - case EVENT_LOAD_DONE: - ar = (AsyncResult)msg.obj; - synchronized (mLock) { - if (ar.exception == null) { - records = (List) ar.result; - } else { - if(DBG) logd("Cannot load ADN records"); - if (records != null) { - records.clear(); - } - } - notifyPending(ar); - } - break; - } - } - - private void notifyPending(AsyncResult ar) { - if (ar.userObj == null) { - return; - } - AtomicBoolean status = (AtomicBoolean) ar.userObj; - status.set(true); - mLock.notifyAll(); - } - }; - - 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. Currently the email field - * if set in the ADN record is ignored. - * 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); - - efid = updateEfForIccType(efid); - - synchronized(mLock) { - checkThread(); - success = false; - AtomicBoolean status = new AtomicBoolean(false); - Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status); - AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber); - AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber); - adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response); - waitForResult(status); - } - 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. Currently the email field - * if set in the ADN record is ignored. - * 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; - AtomicBoolean status = new AtomicBoolean(false); - Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status); - AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber); - adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response); - waitForResult(status); - } - 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 getAdnRecordsInEf(int efid) { - - if (phone.getContext().checkCallingOrSelfPermission( - android.Manifest.permission.READ_CONTACTS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "Requires android.permission.READ_CONTACTS permission"); - } - - efid = updateEfForIccType(efid); - if (DBG) logd("getAdnRecordsInEF: efid=" + efid); - - synchronized(mLock) { - checkThread(); - AtomicBoolean status = new AtomicBoolean(false); - Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status); - adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response); - waitForResult(status); - } - 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."); - } - } - } - - protected void waitForResult(AtomicBoolean status) { - while (!status.get()) { - try { - mLock.wait(); - } catch (InterruptedException e) { - logd("interrupted while trying to update by search"); - } - } - } - - private int updateEfForIccType(int efid) { - // Check if we are trying to read ADN records - if (efid == IccConstants.EF_ADN) { - if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) { - return IccConstants.EF_PBR; - } - } - return efid; - } -} - diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java deleted file mode 100644 index 1c0fc52e78eb..000000000000 --- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.content.pm.PackageManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.ServiceManager; -import android.telephony.PhoneNumberUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - - -/** - * SimPhoneBookInterfaceManager to provide an inter-process communication to - * access ADN-like SIM records. - */ -public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub { - private IccPhoneBookInterfaceManager mIccPhoneBookInterfaceManager; - - public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager - iccPhoneBookInterfaceManager) { - mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager; - if(ServiceManager.getService("simphonebook") == null) { - ServiceManager.addService("simphonebook", this); - } - } - - public void setmIccPhoneBookInterfaceManager( - IccPhoneBookInterfaceManager iccPhoneBookInterfaceManager) { - this.mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager; - } - - public boolean - updateAdnRecordsInEfBySearch (int efid, - String oldTag, String oldPhoneNumber, - String newTag, String newPhoneNumber, - String pin2) throws android.os.RemoteException { - return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfBySearch( - efid, oldTag, oldPhoneNumber, newTag, newPhoneNumber, pin2); - } - - public boolean - updateAdnRecordsInEfByIndex(int efid, String newTag, - String newPhoneNumber, int index, String pin2) throws android.os.RemoteException { - return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfByIndex(efid, - newTag, newPhoneNumber, index, pin2); - } - - public int[] getAdnRecordsSize(int efid) throws android.os.RemoteException { - return mIccPhoneBookInterfaceManager.getAdnRecordsSize(efid); - } - - public List 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 deleted file mode 100644 index a66e19d15231..000000000000 --- a/telephony/java/com/android/internal/telephony/IccProvider.java +++ /dev/null @@ -1,431 +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; - -import android.content.ContentProvider; -import android.content.UriMatcher; -import android.content.ContentValues; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.text.TextUtils; -import android.util.Log; - -import java.util.List; - -import com.android.internal.telephony.IccConstants; -import com.android.internal.telephony.AdnRecord; -import com.android.internal.telephony.IIccPhoneBook; - - -/** - * {@hide} - */ -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", - "number", - "emails", - "_id" - }; - - private static final int ADN = 1; - private static final int FDN = 2; - private static final int SDN = 3; - - private static final String STR_TAG = "tag"; - private static final String STR_NUMBER = "number"; - private static final String STR_EMAILS = "emails"; - private static final String STR_PIN2 = "pin2"; - - private static final UriMatcher URL_MATCHER = - new UriMatcher(UriMatcher.NO_MATCH); - - static { - URL_MATCHER.addURI("icc", "adn", ADN); - URL_MATCHER.addURI("icc", "fdn", FDN); - URL_MATCHER.addURI("icc", "sdn", SDN); - } - - - @Override - public boolean onCreate() { - return true; - } - - @Override - public Cursor query(Uri url, String[] projection, String selection, - String[] selectionArgs, String sort) { - switch (URL_MATCHER.match(url)) { - case ADN: - return loadFromEf(IccConstants.EF_ADN); - - case FDN: - return loadFromEf(IccConstants.EF_FDN); - - case SDN: - return loadFromEf(IccConstants.EF_SDN); - - default: - throw new IllegalArgumentException("Unknown URL " + url); - } - } - - @Override - public String getType(Uri url) { - switch (URL_MATCHER.match(url)) { - case ADN: - case FDN: - case SDN: - return "vnd.android.cursor.dir/sim-contact"; - - default: - throw new IllegalArgumentException("Unknown URL " + url); - } - } - - @Override - public Uri insert(Uri url, ContentValues initialValues) { - Uri resultUri; - int efType; - String pin2 = null; - - if (DBG) log("insert"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = IccConstants.EF_ADN; - break; - - case FDN: - efType = IccConstants.EF_FDN; - pin2 = initialValues.getAsString("pin2"); - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - String tag = initialValues.getAsString("tag"); - String number = initialValues.getAsString("number"); - // TODO(): Read email instead of sending null. - boolean success = addIccRecordToEf(efType, tag, number, null, pin2); - - if (!success) { - return null; - } - - StringBuilder buf = new StringBuilder("content://icc/"); - switch (match) { - case ADN: - buf.append("adn/"); - break; - - case FDN: - buf.append("fdn/"); - break; - } - - // TODO: we need to find out the rowId for the newly added record - buf.append(0); - - resultUri = Uri.parse(buf.toString()); - - /* - // notify interested parties that an insertion happened - getContext().getContentResolver().notifyInsert( - resultUri, rowID, null); - */ - - return resultUri; - } - - private String normalizeValue(String inVal) { - int len = inVal.length(); - String retVal = inVal; - - if (inVal.charAt(0) == '\'' && inVal.charAt(len-1) == '\'') { - retVal = inVal.substring(1, len-1); - } - - return retVal; - } - - @Override - public int delete(Uri url, String where, String[] whereArgs) { - int efType; - - if (DBG) log("delete"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = IccConstants.EF_ADN; - break; - - case FDN: - efType = IccConstants.EF_FDN; - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - // parse where clause - String tag = null; - String number = null; - String[] emails = null; - String pin2 = null; - - String[] tokens = where.split("AND"); - int n = tokens.length; - - while (--n >= 0) { - String param = tokens[n]; - if (DBG) log("parsing '" + param + "'"); - - String[] pair = param.split("="); - - if (pair.length != 2) { - Log.e(TAG, "resolve: bad whereClause parameter: " + param); - continue; - } - - String key = pair[0].trim(); - String val = pair[1].trim(); - - if (STR_TAG.equals(key)) { - tag = normalizeValue(val); - } else if (STR_NUMBER.equals(key)) { - number = normalizeValue(val); - } else if (STR_EMAILS.equals(key)) { - //TODO(): Email is null. - emails = null; - } else if (STR_PIN2.equals(key)) { - pin2 = normalizeValue(val); - } - } - - if (TextUtils.isEmpty(number)) { - return 0; - } - - if (efType == IccConstants.EF_FDN && TextUtils.isEmpty(pin2)) { - return 0; - } - - boolean success = deleteIccRecordFromEf(efType, tag, number, emails, pin2); - if (!success) { - return 0; - } - - return 1; - } - - @Override - public int update(Uri url, ContentValues values, String where, String[] whereArgs) { - int efType; - String pin2 = null; - - if (DBG) log("update"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = IccConstants.EF_ADN; - break; - - case FDN: - efType = IccConstants.EF_FDN; - pin2 = values.getAsString("pin2"); - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - String tag = values.getAsString("tag"); - String number = values.getAsString("number"); - String[] emails = null; - String newTag = values.getAsString("newTag"); - String newNumber = values.getAsString("newNumber"); - String[] newEmails = null; - // TODO(): Update for email. - boolean success = updateIccRecordInEf(efType, tag, number, - newTag, newNumber, pin2); - - if (!success) { - return 0; - } - - return 1; - } - - private MatrixCursor loadFromEf(int efType) { - if (DBG) log("loadFromEf: efType=" + efType); - - List adnRecords = null; - try { - IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (iccIpb != null) { - adnRecords = iccIpb.getAdnRecordsInEf(efType); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - - if (adnRecords != null) { - // Load the results - final int N = adnRecords.size(); - final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N); - if (DBG) log("adnRecords.size=" + N); - for (int i = 0; i < N ; i++) { - loadRecord(adnRecords.get(i), cursor, i); - } - return cursor; - } else { - // No results to load - Log.w(TAG, "Cannot load ADN records"); - return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES); - } - } - - private boolean - addIccRecordToEf(int efType, String name, String number, String[] emails, String pin2) { - if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name + - ", number=" + number + ", emails=" + emails); - - boolean success = false; - - // TODO: do we need to call getAdnRecordsInEf() before calling - // updateAdnRecordsInEfBySearch()? In any case, we will leave - // the UI level logic to fill that prereq if necessary. But - // hopefully, we can remove this requirement. - - try { - IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (iccIpb != null) { - success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "", - name, number, pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - if (DBG) log("addIccRecordToEf: " + success); - return success; - } - - private boolean - updateIccRecordInEf(int efType, String oldName, String oldNumber, - String newName, String newNumber, String pin2) { - if (DBG) log("updateIccRecordInEf: efType=" + efType + - ", oldname=" + oldName + ", oldnumber=" + oldNumber + - ", newname=" + newName + ", newnumber=" + newNumber); - boolean success = false; - - try { - IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (iccIpb != null) { - success = iccIpb.updateAdnRecordsInEfBySearch(efType, - oldName, oldNumber, newName, newNumber, pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - if (DBG) log("updateIccRecordInEf: " + success); - return success; - } - - - private boolean deleteIccRecordFromEf(int efType, String name, String number, String[] emails, - String pin2) { - if (DBG) log("deleteIccRecordFromEf: efType=" + efType + - ", name=" + name + ", number=" + number + ", emails=" + emails + ", pin2=" + pin2); - - boolean success = false; - - try { - IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (iccIpb != null) { - success = iccIpb.updateAdnRecordsInEfBySearch(efType, - name, number, "", "", pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - if (DBG) log("deleteIccRecordFromEf: " + success); - return success; - } - - /** - * Loads an AdnRecord into a MatrixCursor. Must be called with mLock held. - * - * @param record the ADN record to load from - * @param cursor the cursor to receive the results - */ - private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) { - if (!record.isEmpty()) { - Object[] contact = new Object[4]; - String alphaTag = record.getAlphaTag(); - String number = record.getNumber(); - - if (DBG) log("loadRecord: " + alphaTag + ", " + number + ","); - contact[0] = alphaTag; - contact[1] = number; - - String[] emails = record.getEmails(); - if (emails != null) { - StringBuilder emailString = new StringBuilder(); - for (String email: emails) { - if (DBG) log("Adding email:" + email); - emailString.append(email); - emailString.append(","); - } - contact[2] = emailString.toString(); - } - contact[3] = id; - cursor.addRow(contact); - } - } - - private void log(String msg) { - Log.d(TAG, "[IccProvider] " + msg); - } - -} diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java deleted file mode 100644 index 41c9d5ad1c2e..000000000000 --- a/telephony/java/com/android/internal/telephony/IccRecords.java +++ /dev/null @@ -1,422 +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; - -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; - -import com.android.internal.telephony.gsm.UsimServiceTable; -import com.android.internal.telephony.ims.IsimRecords; - -/** - * {@hide} - */ -public abstract class IccRecords extends Handler implements IccConstants { - - protected static final boolean DBG = true; - // ***** Instance Variables - protected boolean mDestroyed = false; // set to true once this object needs to be disposed of - protected Context mContext; - protected CommandsInterface mCi; - protected IccFileHandler mFh; - protected IccCard mParentCard; - - protected RegistrantList recordsLoadedRegistrants = new RegistrantList(); - protected RegistrantList mRecordsEventsRegistrants = new RegistrantList(); - protected RegistrantList mNewSmsRegistrants = new RegistrantList(); - protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList(); - - protected int recordsToLoad; // number of pending load requests - - protected AdnRecordCache adnCache; - - // ***** Cached SIM State; cleared on channel close - - 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; - - protected int mncLength = UNINITIALIZED; - protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated - - protected String spn; - - // ***** Constants - - // Markers for mncLength - protected static final int UNINITIALIZED = -1; - protected static final int UNKNOWN = 0; - - // Bitmasks for SPN display rules. - protected static final int SPN_RULE_SHOW_SPN = 0x01; - protected static final int SPN_RULE_SHOW_PLMN = 0x02; - - // ***** Event Constants - protected static final int EVENT_SET_MSISDN_DONE = 30; - public static final int EVENT_MWI = 0; - public static final int EVENT_CFI = 1; - public static final int EVENT_SPN = 2; - - public static final int EVENT_GET_ICC_RECORD_DONE = 100; - - /** - * Generic ICC record loaded callback. Subclasses can call EF load methods on - * {@link IccFileHandler} passing a Message for onLoaded with the what field set to - * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance - * of this interface. The {@link #handleMessage} method in this class will print a - * log message using {@link #getEfName()} and decrement {@link #recordsToLoad}. - * - * If the record load was successful, {@link #onRecordLoaded} will be called with the result. - * Otherwise, an error log message will be output by {@link #handleMessage} and - * {@link #onRecordLoaded} will not be called. - */ - public interface IccRecordLoaded { - String getEfName(); - void onRecordLoaded(AsyncResult ar); - } - - // ***** Constructor - public IccRecords(IccCard card, Context c, CommandsInterface ci) { - mContext = c; - mCi = ci; - mFh = card.getIccFileHandler(); - mParentCard = card; - } - - /** - * Call when the IccRecords object is no longer going to be used. - */ - public void dispose() { - mDestroyed = true; - mParentCard = null; - mFh = null; - mCi = null; - mContext = null; - } - - protected abstract void onRadioOffOrNotAvailable(); - public abstract void onReady(); - - //***** Public Methods - public AdnRecordCache getAdnCache() { - return adnCache; - } - - public IccCard getIccCard() { - return mParentCard; - } - - public void registerForRecordsLoaded(Handler h, int what, Object obj) { - if (mDestroyed) { - return; - } - - Registrant r = new Registrant(h, what, obj); - recordsLoadedRegistrants.add(r); - - if (recordsToLoad == 0 && recordsRequested == true) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - public void unregisterForRecordsLoaded(Handler h) { - recordsLoadedRegistrants.remove(h); - } - - public void registerForRecordsEvents(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mRecordsEventsRegistrants.add(r); - } - public void unregisterForRecordsEvents(Handler h) { - mRecordsEventsRegistrants.remove(h); - } - - public void registerForNewSms(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mNewSmsRegistrants.add(r); - } - public void unregisterForNewSms(Handler h) { - mNewSmsRegistrants.remove(h); - } - - public void registerForNetworkSelectionModeAutomatic( - Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mNetworkSelectionModeAutomaticRegistrants.add(r); - } - public void unregisterForNetworkSelectionModeAutomatic(Handler h) { - mNetworkSelectionModeAutomaticRegistrants.remove(h); - } - - /** - * Get the International Mobile Subscriber ID (IMSI) on a SIM - * for GSM, UMTS and like networks. Default is null if IMSI is - * not supported or unavailable. - * - * @return null if SIM is not yet ready or unavailable - */ - public String getIMSI() { - return null; - } - - public String getMsisdnNumber() { - return msisdn; - } - - /** - * Set subscriber number to SIM record - * - * The subscriber number is stored in EF_MSISDN (TS 51.011) - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters) - * @param number dailing nubmer (up to 20 digits) - * if the number starts with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setMsisdnNumber(String alphaTag, String number, - Message onComplete) { - - msisdn = number; - msisdnTag = alphaTag; - - if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn); - - - AdnRecord adn = new AdnRecord(msisdnTag, msisdn); - - new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null, - obtainMessage(EVENT_SET_MSISDN_DONE, onComplete)); - } - - public String getMsisdnAlphaTag() { - return msisdnTag; - } - - public String getVoiceMailNumber() { - return voiceMailNum; - } - - /** - * 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 getServiceProviderName() { - 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 - * - * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail. - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters) - * @param voiceNumber dailing nubmer (upto 20 digits) - * if the number is start with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber, - Message onComplete); - - public String getVoiceMailAlphaTag() { - return voiceMailTag; - } - - /** - * 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 - * messages are waiting - */ - public abstract void setVoiceMessageWaiting(int line, int countWaiting); - - /** @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 getVoiceMessageCount() { - return countVoiceMessages; - } - - /** - * Called by STK Service when REFRESH is received. - * @param fileChanged indicates whether any files changed - * @param fileList if non-null, a list of EF files that changed - */ - public abstract void onRefresh(boolean fileChanged, int[] fileList); - - - public boolean getRecordsLoaded() { - if (recordsToLoad == 0 && recordsRequested == true) { - return true; - } else { - return false; - } - } - - //***** Overridden from Handler - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_GET_ICC_RECORD_DONE: - try { - AsyncResult ar = (AsyncResult) msg.obj; - IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj; - if (DBG) log(recordLoaded.getEfName() + " LOADED"); - - if (ar.exception != null) { - loge("Record Load Exception: " + ar.exception); - } else { - recordLoaded.onRecordLoaded(ar); - } - }catch (RuntimeException exc) { - // I don't want these exceptions to be fatal - loge("Exception parsing SIM record: " + exc); - } finally { - // Count up record load responses even if they are fails - onRecordLoaded(); - } - break; - - default: - super.handleMessage(msg); - } - } - - protected abstract void onRecordLoaded(); - - protected abstract void onAllRecordsLoaded(); - - /** - * Returns the SpnDisplayRule based on settings on the SIM and the - * specified plmn (currently-registered PLMN). See TS 22.101 Annex A - * and TS 51.011 10.3.11 for details. - * - * If the SPN is not found on the SIM, the rule is always PLMN_ONLY. - * Generally used for GSM/UMTS and the like SIMs. - */ - public abstract int getDisplayRule(String plmn); - - /** - * Return true if "Restriction of menu options for manual PLMN selection" - * bit is set or EF_CSP data is unavailable, return false otherwise. - * Generally used for GSM/UMTS and the like SIMs. - */ - public boolean isCspPlmnEnabled() { - return false; - } - - /** - * Returns the 5 or 6 digit MCC/MNC of the operator that - * provided the SIM card. Returns null of SIM is not yet ready - * or is not valid for the type of IccCard. Generally used for - * GSM/UMTS and the like SIMS - */ - public String getOperatorNumeric() { - return null; - } - - /** - * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs - * - * @return true if enabled - */ - public boolean getVoiceCallForwardingFlag() { - return false; - } - - /** - * Set the voice call forwarding flag for GSM/UMTS and the like SIMs - * - * @param line to enable/disable - * @param enable - */ - public void setVoiceCallForwardingFlag(int line, boolean enable) { - } - - /** - * Indicates wether SIM is in provisioned state or not. - * Overridden only if SIM can be dynamically provisioned via OTA. - * - * @return true if provisioned - */ - public boolean isProvisioned () { - return true; - } - - /** - * Write string to log file - * - * @param s is the string to write - */ - protected abstract void log(String s); - - /** - * Write error string to log file. - * - * @param s is the string to write - */ - protected abstract void loge(String s); - - /** - * Return an interface to retrieve the ISIM records for IMS, if available. - * @return the interface to retrieve the ISIM records, or null if not supported - */ - public IsimRecords getIsimRecords() { - return null; - } - - public UsimServiceTable getUsimServiceTable() { - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java b/telephony/java/com/android/internal/telephony/IccRefreshResponse.java deleted file mode 100644 index 680670311cf3..000000000000 --- a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011 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; - -/** - * See also RIL_SimRefresh in include/telephony/ril.h - * - * {@hide} - */ - -public class IccRefreshResponse { - - public static final int REFRESH_RESULT_FILE_UPDATE = 0; /* Single file was updated */ - public static final int REFRESH_RESULT_INIT = 1; /* The Icc has been initialized */ - public static final int REFRESH_RESULT_RESET = 2; /* The Icc was reset */ - - public int refreshResult; /* Sim Refresh result */ - public int efId; /* EFID */ - public String aid; /* null terminated string, e.g., - from 0xA0, 0x00 -> 0x41, - 0x30, 0x30, 0x30 */ - /* Example: a0000000871002f310ffff89080000ff */ - - @Override - public String toString() { - return "{" + refreshResult + ", " + aid +", " + efId + "}"; - } -} diff --git a/telephony/java/com/android/internal/telephony/IccServiceTable.java b/telephony/java/com/android/internal/telephony/IccServiceTable.java deleted file mode 100644 index ed74a1175b6b..000000000000 --- a/telephony/java/com/android/internal/telephony/IccServiceTable.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2011 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; - -/** - * Wrapper class for an ICC EF containing a bit field of enabled services. - */ -public abstract class IccServiceTable { - protected final byte[] mServiceTable; - - protected IccServiceTable(byte[] table) { - mServiceTable = table; - } - - // Get the class name to use for log strings - protected abstract String getTag(); - - // Get the array of enums to use for toString - protected abstract Object[] getValues(); - - /** - * Returns if the specified service is available. - * @param service the service number as a zero-based offset (the enum ordinal) - * @return true if the service is available; false otherwise - */ - protected boolean isAvailable(int service) { - int offset = service / 8; - if (offset >= mServiceTable.length) { - // Note: Enums are zero-based, but the TS service numbering is one-based - Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " + - (mServiceTable.length * 8)); - return false; - } - int bit = service % 8; - return (mServiceTable[offset] & (1 << bit)) != 0; - } - - public String toString() { - Object[] values = getValues(); - int numBytes = mServiceTable.length; - StringBuilder builder = new StringBuilder(getTag()).append('[') - .append(numBytes * 8).append("]={ "); - - boolean addComma = false; - for (int i = 0; i < numBytes; i++) { - byte currentByte = mServiceTable[i]; - for (int bit = 0; bit < 8; bit++) { - if ((currentByte & (1 << bit)) != 0) { - if (addComma) { - builder.append(", "); - } else { - addComma = true; - } - int ordinal = (i * 8) + bit; - if (ordinal < values.length) { - builder.append(values[ordinal]); - } else { - builder.append('#').append(ordinal + 1); // service number (one-based) - } - } - } - } - return builder.append(" }").toString(); - } -} diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java deleted file mode 100644 index 5fef6de70a25..000000000000 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.app.PendingIntent; -import android.content.Context; -import android.util.Log; - -import com.android.internal.util.HexDump; - -import java.util.ArrayList; -import java.util.List; - -import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; - -/** - * IccSmsInterfaceManager to provide an inter-process communication to - * access Sms in Icc. - */ -public abstract class IccSmsInterfaceManager extends ISms.Stub { - 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 data based SMS to a specific application port. - * - * @param destAddr the address to send the message to - * @param scAddr is the service center address or null to use - * the current default SMSC - * @param destPort the port to deliver the message to - * @param data the body of the message to send - * @param sentIntent if not NULL this PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent 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 sendData(String destAddr, String scAddr, int destPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mPhone.getContext().enforceCallingPermission( - "android.permission.SEND_SMS", - "Sending SMS message"); - if (Log.isLoggable("SMS", Log.VERBOSE)) { - log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + - destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + - sentIntent + " deliveryIntent=" + deliveryIntent); - } - mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); - } - - /** - * Send a text based SMS. - * - * @param destAddr the address to send the message to - * @param scAddr 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 PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent 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 sendText(String destAddr, String scAddr, - String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mPhone.getContext().enforceCallingPermission( - "android.permission.SEND_SMS", - "Sending SMS message"); - if (Log.isLoggable("SMS", Log.VERBOSE)) { - log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + - " text='"+ text + "' sentIntent=" + - sentIntent + " deliveryIntent=" + deliveryIntent); - } - mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); - } - - /** - * Send a multi-part text based SMS. - * - * @param destAddr the address to send the message to - * @param scAddr is the service center address or null to use - * the current default SMSC - * @param parts an ArrayList of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an ArrayList of - * PendingIntents (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU. - * 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 deliveryIntents if not null, an ArrayList of - * PendingIntents (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 destAddr, String scAddr, List parts, - List sentIntents, List deliveryIntents) { - mPhone.getContext().enforceCallingPermission( - "android.permission.SEND_SMS", - "Sending SMS message"); - if (Log.isLoggable("SMS", Log.VERBOSE)) { - int i = 0; - for (String part : parts) { - log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr + - ", part[" + (i++) + "]=" + part); - } - } - mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList) parts, - (ArrayList) sentIntents, (ArrayList) 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 buildValidRawData(ArrayList messages) { - int count = messages.size(); - ArrayList ret; - - ret = new ArrayList(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 deleted file mode 100644 index 54de508c04de..000000000000 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.app.PendingIntent; -import android.os.ServiceManager; - -import java.util.List; - -public class IccSmsInterfaceManagerProxy extends ISms.Stub { - private IccSmsInterfaceManager mIccSmsInterfaceManager; - - public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager - iccSmsInterfaceManager) { - this.mIccSmsInterfaceManager = iccSmsInterfaceManager; - if(ServiceManager.getService("isms") == null) { - ServiceManager.addService("isms", this); - } - } - - public void setmIccSmsInterfaceManager(IccSmsInterfaceManager iccSmsInterfaceManager) { - this.mIccSmsInterfaceManager = iccSmsInterfaceManager; - } - - public boolean - updateMessageOnIccEf(int index, int status, byte[] pdu) throws android.os.RemoteException { - return mIccSmsInterfaceManager.updateMessageOnIccEf(index, status, pdu); - } - - public boolean copyMessageToIccEf(int status, byte[] pdu, - byte[] smsc) throws android.os.RemoteException { - return mIccSmsInterfaceManager.copyMessageToIccEf(status, pdu, smsc); - } - - public List getAllMessagesFromIccEf() throws android.os.RemoteException { - return mIccSmsInterfaceManager.getAllMessagesFromIccEf(); - } - - public void sendData(String destAddr, String scAddr, int destPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data, - sentIntent, deliveryIntent); - } - - public void sendText(String destAddr, String scAddr, - String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { - mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); - } - - public void sendMultipartText(String destAddr, String scAddr, - List parts, List sentIntents, - List deliveryIntents) throws android.os.RemoteException { - mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr, - parts, sentIntents, deliveryIntents); - } - - public boolean enableCellBroadcast(int messageIdentifier) throws android.os.RemoteException { - return mIccSmsInterfaceManager.enableCellBroadcast(messageIdentifier); - } - - public boolean disableCellBroadcast(int messageIdentifier) throws android.os.RemoteException { - return mIccSmsInterfaceManager.disableCellBroadcast(messageIdentifier); - } - - public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) - throws android.os.RemoteException { - return mIccSmsInterfaceManager.enableCellBroadcastRange(startMessageId, endMessageId); - } - - public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) - throws android.os.RemoteException { - return mIccSmsInterfaceManager.disableCellBroadcastRange(startMessageId, endMessageId); - } -} diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java deleted file mode 100644 index a966f7694f09..000000000000 --- a/telephony/java/com/android/internal/telephony/IccUtils.java +++ /dev/null @@ -1,530 +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; - -import android.content.res.Resources; -import android.content.res.Resources.NotFoundException; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.util.Log; - -import com.android.internal.telephony.GsmAlphabet; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; - -/** - * Various methods, useful for dealing with SIM data. - */ -public class IccUtils { - static final String LOG_TAG="IccUtils"; - - /** - * 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; - // Some PLMNs have 'f' as high nibble, ignore it - if (v == 0xf) continue; - if (v > 9) break; - ret.append((char)('0' + v)); - } - - return ret.toString(); - } - - /** - * Decode cdma byte into String. - */ - public static String - cdmaBcdToString(byte[] data, int offset, int length) { - StringBuilder ret = new StringBuilder(length); - - int count = 0; - for (int i = offset; count < length; i++) { - int v; - v = data[i] & 0xf; - if (v > 9) v = 0; - ret.append((char)('0' + v)); - - if (++count == length) break; - - v = (data[i] >> 4) & 0xf; - if (v > 9) v = 0; - ret.append((char)('0' + v)); - ++count; - } - 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 - gsmBcdByteToInt(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 CDMA style BCD byte like {@link gsmBcdByteToInt}, but - * opposite nibble format. The least significant BCD digit - * is in the least significant nibble and the most significant - * is in the most significant nibble. - */ - public static int - cdmaBcdByteToInt(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 - * 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 == 0) { - return ""; - } - 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(); - } - - Resources resource = Resources.getSystem(); - String defaultCharset = ""; - try { - defaultCharset = - resource.getString(com.android.internal.R.string.gsm_alphabet_default_charset); - } catch (NotFoundException e) { - // Ignore Exception and defaultCharset is set to a empty string. - } - return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim()); - } - - static int - 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 > 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; - } - - /** - * Convert a TS 131.102 image instance of code scheme '11' into Bitmap - * @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; - int height = data[valueIndex++] & 0xFF; - int numOfPixels = width*height; - - int[] pixels = new int[numOfPixels]; - - int pixelIndex = 0; - int bitIndex = 7; - byte currentByte = 0x00; - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (pixelIndex % 8 == 0) { - currentByte = data[valueIndex++]; - bitIndex = 7; - } - pixels[pixelIndex++] = bitToRGB((currentByte >> bitIndex-- ) & 0x01); - }; - - if (pixelIndex != numOfPixels) { - Log.e(LOG_TAG, "parse end and size error"); - } - return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); - } - - private static int bitToRGB(int bit){ - if(bit == 1){ - return Color.WHITE; - } else { - return Color.BLACK; - } - } - - /** - * 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 - * @return The color bitmap - */ - public static Bitmap parseToRGB(byte[] data, int length, - boolean transparency) { - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int bits = data[valueIndex++] & 0xFF; - int colorNumber = data[valueIndex++] & 0xFF; - int clutOffset = ((data[valueIndex++] & 0xFF) << 8) - | (data[valueIndex++] & 0xFF); - - int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber); - if (true == transparency) { - colorIndexArray[colorNumber - 1] = Color.TRANSPARENT; - } - - int[] resultArray = null; - if (0 == (8 % bits)) { - resultArray = mapTo2OrderBitColor(data, valueIndex, - (width * height), colorIndexArray, bits); - } else { - resultArray = mapToNon2OrderBitColor(data, valueIndex, - (width * height), colorIndexArray, bits); - } - - return Bitmap.createBitmap(resultArray, width, height, - Bitmap.Config.RGB_565); - } - - private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex, - int length, int[] colorArray, int bits) { - if (0 != (8 % bits)) { - Log.e(LOG_TAG, "not event number of color"); - return mapToNon2OrderBitColor(data, valueIndex, length, colorArray, - bits); - } - - int mask = 0x01; - switch (bits) { - case 1: - mask = 0x01; - break; - case 2: - mask = 0x03; - break; - case 4: - mask = 0x0F; - break; - case 8: - mask = 0xFF; - break; - } - - int[] resultArray = new int[length]; - int resultIndex = 0; - int run = 8 / bits; - while (resultIndex < length) { - byte tempByte = data[valueIndex++]; - for (int runIndex = 0; runIndex < run; ++runIndex) { - int offset = run - runIndex - 1; - resultArray[resultIndex++] = colorArray[(tempByte >> (offset * bits)) - & mask]; - } - } - return resultArray; - } - - private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex, - int length, int[] colorArray, int bits) { - if (0 == (8 % bits)) { - Log.e(LOG_TAG, "not odd number of color"); - return mapTo2OrderBitColor(data, valueIndex, length, colorArray, - bits); - } - - int[] resultArray = new int[length]; - // TODO fix me: - return resultArray; - } - - private static int[] getCLUT(byte[] rawData, int offset, int number) { - if (null == rawData) { - return null; - } - - int[] result = new int[number]; - int endIndex = offset + (number * 3); // 1 color use 3 bytes - int valueIndex = offset; - int colorIndex = 0; - int alpha = 0xff << 24; - do { - result[colorIndex++] = alpha - | ((rawData[valueIndex++] & 0xFF) << 16) - | ((rawData[valueIndex++] & 0xFF) << 8) - | ((rawData[valueIndex++] & 0xFF)); - } while (valueIndex < endIndex); - return result; - } -} diff --git a/telephony/java/com/android/internal/telephony/IccVmFixedException.java b/telephony/java/com/android/internal/telephony/IccVmFixedException.java deleted file mode 100644 index a75496ff69a1..000000000000 --- a/telephony/java/com/android/internal/telephony/IccVmFixedException.java +++ /dev/null @@ -1,32 +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; - -/** - * {@hide} - */ -public final class IccVmFixedException extends IccException { - IccVmFixedException() - { - - } - - public IccVmFixedException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java deleted file mode 100644 index 3c9d12689acd..000000000000 --- a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java +++ /dev/null @@ -1,32 +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; - -/** - * {@hide} - */ -public final class IccVmNotSupportedException extends IccException { - IccVmNotSupportedException() - { - - } - - public IccVmNotSupportedException(String s) - { - super(s); - } -} diff --git a/telephony/java/com/android/internal/telephony/IntRangeManager.java b/telephony/java/com/android/internal/telephony/IntRangeManager.java deleted file mode 100644 index cc7774d66c3e..000000000000 --- a/telephony/java/com/android/internal/telephony/IntRangeManager.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (C) 2011 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 java.util.ArrayList; -import java.util.Iterator; - -/** - * Clients can enable reception of SMS-CB messages for specific ranges of - * message identifiers (channels). This class keeps track of the currently - * enabled message identifiers and calls abstract methods to update the - * radio when the range of enabled message identifiers changes. - * - * An update is a call to {@link #startUpdate} followed by zero or more - * calls to {@link #addRange} followed by a call to {@link #finishUpdate}. - * Calls to {@link #enableRange} and {@link #disableRange} will perform - * an incremental update operation if the enabled ranges have changed. - * A full update operation (i.e. after a radio reset) can be performed - * by a call to {@link #updateRanges}. - * - * Clients are identified by String (the name associated with the User ID - * of the caller) so that a call to remove a range can be mapped to the - * client that enabled that range (or else rejected). - */ -public abstract class IntRangeManager { - - /** - * Initial capacity for IntRange clients array list. There will be - * few cell broadcast listeners on a typical device, so this can be small. - */ - private static final int INITIAL_CLIENTS_ARRAY_SIZE = 4; - - /** - * One or more clients forming the continuous range [startId, endId]. - *

When a client is added, the IntRange may merge with one or more - * adjacent IntRanges to form a single combined IntRange. - *

When a client is removed, the IntRange may divide into several - * non-contiguous IntRanges. - */ - private class IntRange { - int startId; - int endId; - // sorted by earliest start id - final ArrayList clients; - - /** - * Create a new IntRange with a single client. - * @param startId the first id included in the range - * @param endId the last id included in the range - * @param client the client requesting the enabled range - */ - IntRange(int startId, int endId, String client) { - this.startId = startId; - this.endId = endId; - clients = new ArrayList(INITIAL_CLIENTS_ARRAY_SIZE); - clients.add(new ClientRange(startId, endId, client)); - } - - /** - * Create a new IntRange for an existing ClientRange. - * @param clientRange the initial ClientRange to add - */ - IntRange(ClientRange clientRange) { - startId = clientRange.startId; - endId = clientRange.endId; - clients = new ArrayList(INITIAL_CLIENTS_ARRAY_SIZE); - clients.add(clientRange); - } - - /** - * Create a new IntRange from an existing IntRange. This is used for - * removing a ClientRange, because new IntRanges may need to be created - * for any gaps that open up after the ClientRange is removed. A copy - * is made of the elements of the original IntRange preceding the element - * that is being removed. The following elements will be added to this - * IntRange or to a new IntRange when a gap is found. - * @param intRange the original IntRange to copy elements from - * @param numElements the number of elements to copy from the original - */ - IntRange(IntRange intRange, int numElements) { - this.startId = intRange.startId; - this.endId = intRange.endId; - this.clients = new ArrayList(intRange.clients.size()); - for (int i=0; i < numElements; i++) { - this.clients.add(intRange.clients.get(i)); - } - } - - /** - * Insert new ClientRange in order by start id. - *

If the new ClientRange is known to be sorted before or after the - * existing ClientRanges, or at a particular index, it can be added - * to the clients array list directly, instead of via this method. - *

Note that this can be changed from linear to binary search if the - * number of clients grows large enough that it would make a difference. - * @param range the new ClientRange to insert - */ - void insert(ClientRange range) { - int len = clients.size(); - for (int i=0; i < len; i++) { - ClientRange nextRange = clients.get(i); - if (range.startId <= nextRange.startId) { - // ignore duplicate ranges from the same client - if (!range.equals(nextRange)) { - clients.add(i, range); - } - return; - } - } - clients.add(range); // append to end of list - } - } - - /** - * The message id range for a single client. - */ - private class ClientRange { - final int startId; - final int endId; - final String client; - - ClientRange(int startId, int endId, String client) { - this.startId = startId; - this.endId = endId; - this.client = client; - } - - @Override - public boolean equals(Object o) { - if (o != null && o instanceof ClientRange) { - ClientRange other = (ClientRange) o; - return startId == other.startId && - endId == other.endId && - client.equals(other.client); - } else { - return false; - } - } - - @Override - public int hashCode() { - return (startId * 31 + endId) * 31 + client.hashCode(); - } - } - - /** - * List of integer ranges, one per client, sorted by start id. - */ - private ArrayList mRanges = new ArrayList(); - - protected IntRangeManager() {} - - /** - * Enable a range for the specified client and update ranges - * if necessary. If {@link #finishUpdate} returns failure, - * false is returned and the range is not added. - * - * @param startId the first id included in the range - * @param endId the last id included in the range - * @param client the client requesting the enabled range - * @return true if successful, false otherwise - */ - public synchronized boolean enableRange(int startId, int endId, String client) { - int len = mRanges.size(); - - // empty range list: add the initial IntRange - if (len == 0) { - if (tryAddSingleRange(startId, endId, true)) { - mRanges.add(new IntRange(startId, endId, client)); - return true; - } else { - return false; // failed to update radio - } - } - - for (int startIndex = 0; startIndex < len; startIndex++) { - IntRange range = mRanges.get(startIndex); - if (startId < range.startId) { - // test if new range completely precedes this range - // note that [1, 4] and [5, 6] coalesce to [1, 6] - if ((endId + 1) < range.startId) { - // insert new int range before previous first range - if (tryAddSingleRange(startId, endId, true)) { - mRanges.add(startIndex, new IntRange(startId, endId, client)); - return true; - } else { - return false; // failed to update radio - } - } else if (endId <= range.endId) { - // extend the start of this range - if (tryAddSingleRange(startId, range.startId - 1, true)) { - range.startId = startId; - range.clients.add(0, new ClientRange(startId, endId, client)); - return true; - } else { - return false; // failed to update radio - } - } else { - // find last range that can coalesce into the new combined range - for (int endIndex = startIndex+1; endIndex < len; endIndex++) { - IntRange endRange = mRanges.get(endIndex); - if ((endId + 1) < endRange.startId) { - // try to add entire new range - if (tryAddSingleRange(startId, endId, true)) { - range.startId = startId; - range.endId = endId; - // insert new ClientRange before existing ranges - range.clients.add(0, new ClientRange(startId, endId, client)); - // coalesce range with following ranges up to endIndex-1 - // remove each range after adding its elements, so the index - // of the next range to join is always startIndex+1. - // i is the index if no elements were removed: we only care - // about the number of loop iterations, not the value of i. - int joinIndex = startIndex + 1; - for (int i = joinIndex; i < endIndex; i++) { - IntRange joinRange = mRanges.get(joinIndex); - range.clients.addAll(joinRange.clients); - mRanges.remove(joinRange); - } - return true; - } else { - return false; // failed to update radio - } - } else if (endId <= endRange.endId) { - // add range from start id to start of last overlapping range, - // values from endRange.startId to endId are already enabled - if (tryAddSingleRange(startId, endRange.startId - 1, true)) { - range.startId = startId; - range.endId = endRange.endId; - // insert new ClientRange before existing ranges - range.clients.add(0, new ClientRange(startId, endId, client)); - // coalesce range with following ranges up to endIndex - // remove each range after adding its elements, so the index - // of the next range to join is always startIndex+1. - // i is the index if no elements were removed: we only care - // about the number of loop iterations, not the value of i. - int joinIndex = startIndex + 1; - for (int i = joinIndex; i <= endIndex; i++) { - IntRange joinRange = mRanges.get(joinIndex); - range.clients.addAll(joinRange.clients); - mRanges.remove(joinRange); - } - return true; - } else { - return false; // failed to update radio - } - } - } - - // endId extends past all existing IntRanges: combine them all together - if (tryAddSingleRange(startId, endId, true)) { - range.startId = startId; - range.endId = endId; - // insert new ClientRange before existing ranges - range.clients.add(0, new ClientRange(startId, endId, client)); - // coalesce range with following ranges up to len-1 - // remove each range after adding its elements, so the index - // of the next range to join is always startIndex+1. - // i is the index if no elements were removed: we only care - // about the number of loop iterations, not the value of i. - int joinIndex = startIndex + 1; - for (int i = joinIndex; i < len; i++) { - IntRange joinRange = mRanges.get(joinIndex); - range.clients.addAll(joinRange.clients); - mRanges.remove(joinRange); - } - return true; - } else { - return false; // failed to update radio - } - } - } else if ((startId + 1) <= range.endId) { - if (endId <= range.endId) { - // completely contained in existing range; no radio changes - range.insert(new ClientRange(startId, endId, client)); - return true; - } else { - // find last range that can coalesce into the new combined range - int endIndex = startIndex; - for (int testIndex = startIndex+1; testIndex < len; testIndex++) { - IntRange testRange = mRanges.get(testIndex); - if ((endId + 1) < testRange.startId) { - break; - } else { - endIndex = testIndex; - } - } - // no adjacent IntRanges to combine - if (endIndex == startIndex) { - // add range from range.endId+1 to endId, - // values from startId to range.endId are already enabled - if (tryAddSingleRange(range.endId + 1, endId, true)) { - range.endId = endId; - range.insert(new ClientRange(startId, endId, client)); - return true; - } else { - return false; // failed to update radio - } - } - // get last range to coalesce into start range - IntRange endRange = mRanges.get(endIndex); - // Values from startId to range.endId have already been enabled. - // if endId > endRange.endId, then enable range from range.endId+1 to endId, - // else enable range from range.endId+1 to endRange.startId-1, because - // values from endRange.startId to endId have already been added. - int newRangeEndId = (endId <= endRange.endId) ? endRange.startId - 1 : endId; - if (tryAddSingleRange(range.endId + 1, newRangeEndId, true)) { - range.endId = endId; - // insert new ClientRange in place - range.insert(new ClientRange(startId, endId, client)); - // coalesce range with following ranges up to endIndex-1 - // remove each range after adding its elements, so the index - // of the next range to join is always startIndex+1 (joinIndex). - // i is the index if no elements had been removed: we only care - // about the number of loop iterations, not the value of i. - int joinIndex = startIndex + 1; - for (int i = joinIndex; i < endIndex; i++) { - IntRange joinRange = mRanges.get(joinIndex); - range.clients.addAll(joinRange.clients); - mRanges.remove(joinRange); - } - return true; - } else { - return false; // failed to update radio - } - } - } - } - - // append new range after existing IntRanges - if (tryAddSingleRange(startId, endId, true)) { - mRanges.add(new IntRange(startId, endId, client)); - return true; - } else { - return false; // failed to update radio - } - } - - /** - * Disable a range for the specified client and update ranges - * if necessary. If {@link #finishUpdate} returns failure, - * false is returned and the range is not removed. - * - * @param startId the first id included in the range - * @param endId the last id included in the range - * @param client the client requesting to disable the range - * @return true if successful, false otherwise - */ - public synchronized boolean disableRange(int startId, int endId, String client) { - int len = mRanges.size(); - - for (int i=0; i < len; i++) { - IntRange range = mRanges.get(i); - if (startId < range.startId) { - return false; // not found - } else if (endId <= range.endId) { - // found the IntRange that encloses the client range, if any - // search for it in the clients list - ArrayList clients = range.clients; - - // handle common case of IntRange containing one ClientRange - int crLength = clients.size(); - if (crLength == 1) { - ClientRange cr = clients.get(0); - if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) { - // disable range in radio then remove the entire IntRange - if (tryAddSingleRange(startId, endId, false)) { - mRanges.remove(i); - return true; - } else { - return false; // failed to update radio - } - } else { - return false; // not found - } - } - - // several ClientRanges: remove one, potentially splitting into many IntRanges. - // Save the original start and end id for the original IntRange - // in case the radio update fails and we have to revert it. If the - // update succeeds, we remove the client range and insert the new IntRanges. - int largestEndId = Integer.MIN_VALUE; // largest end identifier found - boolean updateStarted = false; - - for (int crIndex=0; crIndex < crLength; crIndex++) { - ClientRange cr = clients.get(crIndex); - if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) { - // found the ClientRange to remove, check if it's the last in the list - if (crIndex == crLength - 1) { - if (range.endId == largestEndId) { - // no channels to remove from radio; return success - clients.remove(crIndex); - return true; - } else { - // disable the channels at the end and lower the end id - if (tryAddSingleRange(largestEndId + 1, range.endId, false)) { - clients.remove(crIndex); - range.endId = largestEndId; - return true; - } else { - return false; - } - } - } - - // copy the IntRange so that we can remove elements and modify the - // start and end id's in the copy, leaving the original unmodified - // until after the radio update succeeds - IntRange rangeCopy = new IntRange(range, crIndex); - - if (crIndex == 0) { - // removing the first ClientRange, so we may need to increase - // the start id of the IntRange. - // We know there are at least two ClientRanges in the list, - // so clients.get(1) should always succeed. - int nextStartId = clients.get(1).startId; - if (nextStartId != range.startId) { - startUpdate(); - updateStarted = true; - addRange(range.startId, nextStartId - 1, false); - rangeCopy.startId = nextStartId; - } - // init largestEndId - largestEndId = clients.get(1).endId; - } - - // go through remaining ClientRanges, creating new IntRanges when - // there is a gap in the sequence. After radio update succeeds, - // remove the original IntRange and append newRanges to mRanges. - // Otherwise, leave the original IntRange in mRanges and return false. - ArrayList newRanges = new ArrayList(); - - IntRange currentRange = rangeCopy; - for (int nextIndex = crIndex + 1; nextIndex < crLength; nextIndex++) { - ClientRange nextCr = clients.get(nextIndex); - if (nextCr.startId > largestEndId + 1) { - if (!updateStarted) { - startUpdate(); - updateStarted = true; - } - addRange(largestEndId + 1, nextCr.startId - 1, false); - currentRange.endId = largestEndId; - newRanges.add(currentRange); - currentRange = new IntRange(nextCr); - } else { - currentRange.clients.add(nextCr); - } - if (nextCr.endId > largestEndId) { - largestEndId = nextCr.endId; - } - } - - // remove any channels between largestEndId and endId - if (largestEndId < endId) { - if (!updateStarted) { - startUpdate(); - updateStarted = true; - } - addRange(largestEndId + 1, endId, false); - currentRange.endId = largestEndId; - } - newRanges.add(currentRange); - - if (updateStarted && !finishUpdate()) { - return false; // failed to update radio - } - - // replace the original IntRange with newRanges - mRanges.remove(i); - mRanges.addAll(i, newRanges); - return true; - } else { - // not the ClientRange to remove; save highest end ID seen so far - if (cr.endId > largestEndId) { - largestEndId = cr.endId; - } - } - } - } - } - - return false; // not found - } - - /** - * Perform a complete update operation (enable all ranges). Useful - * after a radio reset. Calls {@link #startUpdate}, followed by zero or - * more calls to {@link #addRange}, followed by {@link #finishUpdate}. - * @return true if successful, false otherwise - */ - public boolean updateRanges() { - startUpdate(); - Iterator iterator = mRanges.iterator(); - if (iterator.hasNext()) { - IntRange range = iterator.next(); - int start = range.startId; - int end = range.endId; - // accumulate ranges of [startId, endId] - while (iterator.hasNext()) { - IntRange nextNode = iterator.next(); - // [startIdA, endIdA], [endIdA + 1, endIdB] -> [startIdA, endIdB] - if (nextNode.startId <= (end + 1)) { - if (nextNode.endId > end) { - end = nextNode.endId; - } - } else { - addRange(start, end, true); - start = nextNode.startId; - end = nextNode.endId; - } - } - // add final range - addRange(start, end, true); - } - return finishUpdate(); - } - - /** - * Enable or disable a single range of message identifiers. - * @param startId the first id included in the range - * @param endId the last id included in the range - * @param selected true to enable range, false to disable range - * @return true if successful, false otherwise - */ - private boolean tryAddSingleRange(int startId, int endId, boolean selected) { - startUpdate(); - addRange(startId, endId, selected); - return finishUpdate(); - } - - /** - * Returns whether the list of ranges is completely empty. - * @return true if there are no enabled ranges - */ - public boolean isEmpty() { - return mRanges.isEmpty(); - } - - /** - * Called when the list of enabled ranges has changed. This will be - * followed by zero or more calls to {@link #addRange} followed by - * a call to {@link #finishUpdate}. - */ - protected abstract void startUpdate(); - - /** - * Called after {@link #startUpdate} to indicate a range of enabled - * or disabled values. - * - * @param startId the first id included in the range - * @param endId the last id included in the range - * @param selected true to enable range, false to disable range - */ - protected abstract void addRange(int startId, int endId, boolean selected); - - /** - * Called to indicate the end of a range update started by the - * previous call to {@link #startUpdate}. - * @return true if successful, false otherwise - */ - protected abstract boolean finishUpdate(); -} diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java deleted file mode 100644 index b6711bc6939d..000000000000 --- a/telephony/java/com/android/internal/telephony/MccTable.java +++ /dev/null @@ -1,571 +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; - -import android.app.ActivityManagerNative; -import android.app.AlarmManager; -import android.app.IActivityManager; -import android.content.Context; -import android.content.res.Configuration; -import android.net.wifi.WifiManager; -import android.os.RemoteException; -import android.os.SystemProperties; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Locale; -import libcore.icu.TimeZones; - -/** - * Mobile Country Code - * - * {@hide} - */ -public final class MccTable -{ - static final String LOG_TAG = "MccTable"; - - static ArrayList table; - - static class MccEntry implements Comparable - { - int mcc; - String iso; - int smallestDigitsMnc; - String language; - - MccEntry(int mnc, String iso, int smallestDigitsMCC) { - this(mnc, iso, smallestDigitsMCC, null); - } - - MccEntry(int mnc, String iso, int smallestDigitsMCC, String language) { - this.mcc = mnc; - this.iso = iso; - this.smallestDigitsMnc = smallestDigitsMCC; - this.language = language; - } - - - public int compareTo(MccEntry o) - { - return mcc - o.mcc; - } - } - - private static MccEntry - entryForMcc(int mcc) - { - int index; - - MccEntry m; - - m = new MccEntry(mcc, null, 0); - - index = Collections.binarySearch(table, m); - - if (index < 0) { - return null; - } else { - return table.get(index); - } - } - - /** - * Returns a default time zone ID for the given MCC. - * @param mcc Mobile Country Code - * @return default TimeZone ID, or null if not specified - */ - public static String defaultTimeZoneForMcc(int mcc) { - MccEntry entry; - - entry = entryForMcc(mcc); - if (entry == null || entry.iso == null) { - return null; - } else { - Locale locale; - if (entry.language == null) { - locale = new Locale(entry.iso); - } else { - locale = new Locale(entry.language, entry.iso); - } - String[] tz = TimeZones.forLocale(locale); - if (tz.length == 0) return null; - return tz[0]; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * an ISO two-character country code if available. - * Returns "" if unavailable. - */ - public static String - countryCodeForMcc(int mcc) - { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return ""; - } else { - return entry.iso; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * an ISO 2-3 character language code if available. - * Returns null if unavailable. - */ - public static String defaultLanguageForMcc(int mcc) { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return null; - } else { - return entry.language; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * the smallest number of digits that M if available. - * Returns 2 if unavailable. - */ - public static int - smallestDigitsMccForMnc(int mcc) - { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return 2; - } else { - return entry.smallestDigitsMnc; - } - } - - /** - * Updates MCC and MNC device configuration information for application retrieving - * correct version of resources. If either MCC or MNC is 0, they will be ignored (not set). - * @param context Context to act on. - * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end - */ - public static void updateMccMncConfiguration(Context context, String mccmnc) { - if (!TextUtils.isEmpty(mccmnc)) { - int mcc, mnc; - - try { - mcc = Integer.parseInt(mccmnc.substring(0,3)); - mnc = Integer.parseInt(mccmnc.substring(3)); - } catch (NumberFormatException e) { - Log.e(LOG_TAG, "Error parsing IMSI"); - return; - } - - Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc); - - if (mcc != 0) { - setTimezoneFromMccIfNeeded(context, mcc); - setLocaleFromMccIfNeeded(context, mcc); - setWifiCountryCodeFromMcc(context, mcc); - } - try { - Configuration config = ActivityManagerNative.getDefault().getConfiguration(); - if (mcc != 0) { - config.mcc = mcc; - } - if (mnc != 0) { - config.mnc = mnc; - } - ActivityManagerNative.getDefault().updateConfiguration(config); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can't update configuration", e); - } - } - } - - /** - * Utility code to set the system locale if it's not set already - * @param context Context to act on. - * @param language Two character language code desired - * @param country Two character country code desired - * - * {@hide} - */ - public static void setSystemLocale(Context context, String language, String country) { - String l = SystemProperties.get("persist.sys.language"); - String c = SystemProperties.get("persist.sys.country"); - - if (null == language) { - return; // no match possible - } - language = language.toLowerCase(); - if (null == country) { - country = ""; - } - country = country.toUpperCase(); - - if((null == l || 0 == l.length()) && (null == c || 0 == c.length())) { - try { - // try to find a good match - String[] locales = context.getAssets().getLocales(); - final int N = locales.length; - String bestMatch = null; - for(int i = 0; i < N; i++) { - // only match full (lang + country) locales - if (locales[i]!=null && locales[i].length() >= 5 && - locales[i].substring(0,2).equals(language)) { - if (locales[i].substring(3,5).equals(country)) { - bestMatch = locales[i]; - break; - } else if (null == bestMatch) { - bestMatch = locales[i]; - } - } - } - if (null != bestMatch) { - IActivityManager am = ActivityManagerNative.getDefault(); - Configuration config = am.getConfiguration(); - config.locale = new Locale(bestMatch.substring(0,2), - bestMatch.substring(3,5)); - config.userSetLocale = true; - am.updateConfiguration(config); - } - } catch (Exception e) { - // Intentionally left blank - } - } - } - - /** - * If the timezone is not already set, set it based on the MCC of the SIM. - * @param context Context to act on. - * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA) - */ - private static void setTimezoneFromMccIfNeeded(Context context, int mcc) { - String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY); - if (timezone == null || timezone.length() == 0) { - String zoneId = defaultTimeZoneForMcc(mcc); - if (zoneId != null && zoneId.length() > 0) { - // Set time zone based on MCC - AlarmManager alarm = - (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - alarm.setTimeZone(zoneId); - Log.d(LOG_TAG, "timezone set to "+zoneId); - } - } - } - - /** - * If the locale is not already set, set it based on the MCC of the SIM. - * @param context Context to act on. - * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA) - */ - private static void setLocaleFromMccIfNeeded(Context context, int mcc) { - if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) { - // Avoid system locale is set from MCC table if CDMALTEPhone is used. - // The locale will be picked up based on EFpl/EFli once CSIM records are loaded. - return; - } - String language = MccTable.defaultLanguageForMcc(mcc); - String country = MccTable.countryCodeForMcc(mcc); - - Log.d(LOG_TAG, "locale set to "+language+"_"+country); - setSystemLocale(context, language, country); - } - - /** - * If the number of allowed wifi channels has not been set, set it based on - * the MCC of the SIM. - * @param context Context to act on. - * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA) - */ - private static void setWifiCountryCodeFromMcc(Context context, int mcc) { - String country = MccTable.countryCodeForMcc(mcc); - if (!country.isEmpty()) { - Log.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country); - WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - //persist - wM.setCountryCode(country, true); - } - } - - static { - table = new ArrayList(240); - - - /* - * The table below is built from two resources: - * - * 1) ITU "Mobile Network Code (MNC) for the international - * identification plan for mobile terminals and mobile users" - * which is available as an annex to the ITU operational bulletin - * available here: http://www.itu.int/itu-t/bulletin/annex.html - * - * 2) The ISO 3166 country codes list, available here: - * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html - * - * This table has not been verified. - * - */ - - table.add(new MccEntry(202,"gr",2)); //Greece - table.add(new MccEntry(204,"nl",2,"nl")); //Netherlands (Kingdom of the) - table.add(new MccEntry(206,"be",2)); //Belgium - table.add(new MccEntry(208,"fr",2,"fr")); //France - table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of) - table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of) - table.add(new MccEntry(214,"es",2,"es")); //Spain - table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of) - table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina - table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of) - table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro - table.add(new MccEntry(222,"it",2,"it")); //Italy - table.add(new MccEntry(225,"va",2,"it")); //Vatican City State - table.add(new MccEntry(226,"ro",2)); //Romania - table.add(new MccEntry(228,"ch",2,"de")); //Switzerland (Confederation of) - table.add(new MccEntry(230,"cz",2,"cs")); //Czech Republic - table.add(new MccEntry(231,"sk",2)); //Slovak Republic - table.add(new MccEntry(232,"at",2,"de")); //Austria - table.add(new MccEntry(234,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland - table.add(new MccEntry(235,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland - table.add(new MccEntry(238,"dk",2)); //Denmark - table.add(new MccEntry(240,"se",2)); //Sweden - table.add(new MccEntry(242,"no",2)); //Norway - table.add(new MccEntry(244,"fi",2)); //Finland - table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of) - table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of) - table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of) - table.add(new MccEntry(250,"ru",2)); //Russian Federation - table.add(new MccEntry(255,"ua",2)); //Ukraine - table.add(new MccEntry(257,"by",2)); //Belarus (Republic of) - table.add(new MccEntry(259,"md",2)); //Moldova (Republic of) - table.add(new MccEntry(260,"pl",2)); //Poland (Republic of) - table.add(new MccEntry(262,"de",2,"de")); //Germany (Federal Republic of) - table.add(new MccEntry(266,"gi",2)); //Gibraltar - table.add(new MccEntry(268,"pt",2)); //Portugal - table.add(new MccEntry(270,"lu",2)); //Luxembourg - table.add(new MccEntry(272,"ie",2,"en")); //Ireland - table.add(new MccEntry(274,"is",2)); //Iceland - table.add(new MccEntry(276,"al",2)); //Albania (Republic of) - table.add(new MccEntry(278,"mt",2)); //Malta - table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of) - table.add(new MccEntry(282,"ge",2)); //Georgia - table.add(new MccEntry(283,"am",2)); //Armenia (Republic of) - table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of) - table.add(new MccEntry(286,"tr",2)); //Turkey - table.add(new MccEntry(288,"fo",2)); //Faroe Islands - table.add(new MccEntry(289,"ge",2)); //Abkhazia (Georgia) - table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark) - table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of) - table.add(new MccEntry(293,"si",2)); //Slovenia (Republic of) - table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia - table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of) - table.add(new MccEntry(297,"me",2)); //Montenegro (Republic of) - table.add(new MccEntry(302,"ca",3,"")); //Canada - table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise) - table.add(new MccEntry(310,"us",3,"en")); //United States of America - table.add(new MccEntry(311,"us",3,"en")); //United States of America - table.add(new MccEntry(312,"us",3,"en")); //United States of America - table.add(new MccEntry(313,"us",3,"en")); //United States of America - table.add(new MccEntry(314,"us",3,"en")); //United States of America - table.add(new MccEntry(315,"us",3,"en")); //United States of America - table.add(new MccEntry(316,"us",3,"en")); //United States of America - table.add(new MccEntry(330,"pr",2)); //Puerto Rico - table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands - table.add(new MccEntry(334,"mx",3)); //Mexico - table.add(new MccEntry(338,"jm",3)); //Jamaica - table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of) - table.add(new MccEntry(342,"bb",3)); //Barbados - table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda - table.add(new MccEntry(346,"ky",3)); //Cayman Islands - table.add(new MccEntry(348,"vg",3)); //British Virgin Islands - table.add(new MccEntry(350,"bm",2)); //Bermuda - table.add(new MccEntry(352,"gd",2)); //Grenada - table.add(new MccEntry(354,"ms",2)); //Montserrat - table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis - table.add(new MccEntry(358,"lc",2)); //Saint Lucia - table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines - table.add(new MccEntry(362,"ai",2)); //Netherlands Antilles - table.add(new MccEntry(363,"aw",2)); //Aruba - table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the) - table.add(new MccEntry(365,"ai",3)); //Anguilla - table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of) - table.add(new MccEntry(368,"cu",2)); //Cuba - table.add(new MccEntry(370,"do",2)); //Dominican Republic - table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of) - table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago - table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands - table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic - table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of) - table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of) - table.add(new MccEntry(404,"in",2)); //India (Republic of) - table.add(new MccEntry(405,"in",2)); //India (Republic of) - table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of) - table.add(new MccEntry(412,"af",2)); //Afghanistan - table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of) - table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of) - table.add(new MccEntry(415,"lb",2)); //Lebanon - table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of) - table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic - table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of) - table.add(new MccEntry(419,"kw",2)); //Kuwait (State of) - table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of) - table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of) - table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of) - table.add(new MccEntry(423,"ps",2)); //Palestine - table.add(new MccEntry(424,"ae",2)); //United Arab Emirates - table.add(new MccEntry(425,"il",2)); //Israel (State of) - table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of) - table.add(new MccEntry(427,"qa",2)); //Qatar (State of) - table.add(new MccEntry(428,"mn",2)); //Mongolia - table.add(new MccEntry(429,"np",2)); //Nepal - table.add(new MccEntry(430,"ae",2)); //United Arab Emirates - table.add(new MccEntry(431,"ae",2)); //United Arab Emirates - table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of) - table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of) - table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of) - table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic - table.add(new MccEntry(438,"tm",2)); //Turkmenistan - table.add(new MccEntry(440,"jp",2,"ja")); //Japan - table.add(new MccEntry(441,"jp",2,"ja")); //Japan - table.add(new MccEntry(450,"kr",2,"ko")); //Korea (Republic of) - table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of) - table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China" - table.add(new MccEntry(455,"mo",2)); //"Macao, China" - table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of) - table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic - table.add(new MccEntry(460,"cn",2,"zh")); //China (People's Republic of) - table.add(new MccEntry(461,"cn",2,"zh")); //China (People's Republic of) - table.add(new MccEntry(466,"tw",2)); //"Taiwan, China" - table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea - table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of) - table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of) - table.add(new MccEntry(502,"my",2)); //Malaysia - table.add(new MccEntry(505,"au",2,"en")); //Australia - table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of) - table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste - table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the) - table.add(new MccEntry(520,"th",2)); //Thailand - table.add(new MccEntry(525,"sg",2,"en")); //Singapore (Republic of) - table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam - table.add(new MccEntry(530,"nz",2, "en")); //New Zealand - table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the) - table.add(new MccEntry(535,"gu",2)); //Guam - table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of) - table.add(new MccEntry(537,"pg",2)); //Papua New Guinea - table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of) - table.add(new MccEntry(540,"sb",2)); //Solomon Islands - table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of) - table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of) - table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer) - table.add(new MccEntry(544,"as",2)); //American Samoa - table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of) - table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer) - table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer) - table.add(new MccEntry(548,"ck",2)); //Cook Islands - table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of) - table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of) - table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the) - table.add(new MccEntry(552,"pw",2)); //Palau (Republic of) - table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of) - table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of) - table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of) - table.add(new MccEntry(605,"tn",2)); //Tunisia - table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya) - table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the) - table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of) - table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of) - table.add(new MccEntry(610,"ml",2)); //Mali (Republic of) - table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of) - table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of) - table.add(new MccEntry(613,"bf",2)); //Burkina Faso - table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the) - table.add(new MccEntry(615,"tg",2)); //Togolese Republic - table.add(new MccEntry(616,"bj",2)); //Benin (Republic of) - table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of) - table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of) - table.add(new MccEntry(619,"sl",2)); //Sierra Leone - table.add(new MccEntry(620,"gh",2)); //Ghana - table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of) - table.add(new MccEntry(622,"td",2)); //Chad (Republic of) - table.add(new MccEntry(623,"cf",2)); //Central African Republic - table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of) - table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of) - table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of) - table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of) - table.add(new MccEntry(628,"ga",2)); //Gabonese Republic - table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the) - table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo - table.add(new MccEntry(631,"ao",2)); //Angola (Republic of) - table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of) - table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of) - table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the) - table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of) - table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of) - table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic - table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of) - table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of) - table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of) - table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of) - table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of) - table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of) - table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of) - table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of) - table.add(new MccEntry(647,"re",2)); //Reunion (French Department of) - table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of) - table.add(new MccEntry(649,"na",2)); //Namibia (Republic of) - table.add(new MccEntry(650,"mw",2)); //Malawi - table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of) - table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of) - table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of) - table.add(new MccEntry(654,"km",2)); //Comoros (Union of the) - table.add(new MccEntry(655,"za",2,"en")); //South Africa (Republic of) - table.add(new MccEntry(657,"er",2)); //Eritrea - table.add(new MccEntry(702,"bz",2)); //Belize - table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of) - table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of) - table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of) - table.add(new MccEntry(710,"ni",2)); //Nicaragua - table.add(new MccEntry(712,"cr",2)); //Costa Rica - table.add(new MccEntry(714,"pa",2)); //Panama (Republic of) - table.add(new MccEntry(716,"pe",2)); //Peru - table.add(new MccEntry(722,"ar",3)); //Argentine Republic - table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of) - table.add(new MccEntry(730,"cl",2)); //Chile - table.add(new MccEntry(732,"co",3)); //Colombia (Republic of) - table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of) - table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of) - table.add(new MccEntry(738,"gy",2)); //Guyana - table.add(new MccEntry(740,"ec",2)); //Ecuador - table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of) - table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of) - table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of) - table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of) - table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas) - //table.add(new MccEntry(901,"",2)); //"International Mobile, shared code" - - Collections.sort(table); - } -} diff --git a/telephony/java/com/android/internal/telephony/MmiCode.java b/telephony/java/com/android/internal/telephony/MmiCode.java deleted file mode 100644 index c71ff778d859..000000000000 --- a/telephony/java/com/android/internal/telephony/MmiCode.java +++ /dev/null @@ -1,62 +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; - -/** - * {@hide} - */ -public interface MmiCode -{ - /** - * {@hide} - */ - public enum State { - PENDING, - CANCELLED, - COMPLETE, - FAILED - } - - - /** - * @return Current state of MmiCode request - */ - public State getState(); - - /** - * @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(); - - /** - * @return true if the network response is a REQUEST for more user input. - */ - public boolean isUssdRequest(); - - /** - * @return true if an outstanding request can be canceled. - */ - public boolean isCancelable(); -} diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java deleted file mode 100644 index 1999cb3ada4f..000000000000 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ /dev/null @@ -1,149 +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; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * {@hide} - */ -public class OperatorInfo implements Parcelable { - public enum State { - UNKNOWN, - AVAILABLE, - CURRENT, - FORBIDDEN; - } - - private String operatorAlphaLong; - private String operatorAlphaShort; - private String operatorNumeric; - - private State state = State.UNKNOWN; - - - public String - getOperatorAlphaLong() { - return operatorAlphaLong; - } - - public String - getOperatorAlphaShort() { - return operatorAlphaShort; - } - - public String - getOperatorNumeric() { - return operatorNumeric; - } - - public State - getState() { - return state; - } - - OperatorInfo(String operatorAlphaLong, - String operatorAlphaShort, - String operatorNumeric, - State state) { - - this.operatorAlphaLong = operatorAlphaLong; - this.operatorAlphaShort = operatorAlphaShort; - this.operatorNumeric = operatorNumeric; - - this.state = state; - } - - - public OperatorInfo(String operatorAlphaLong, - String operatorAlphaShort, - String operatorNumeric, - String stateString) { - this (operatorAlphaLong, operatorAlphaShort, - operatorNumeric, rilStateToState(stateString)); - } - - /** - * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS - */ - private static State rilStateToState(String s) { - if (s.equals("unknown")) { - return State.UNKNOWN; - } else if (s.equals("available")) { - return State.AVAILABLE; - } else if (s.equals("current")) { - return State.CURRENT; - } else if (s.equals("forbidden")) { - return State.FORBIDDEN; - } else { - throw new RuntimeException( - "RIL impl error: Invalid network state '" + s + "'"); - } - } - - - public String toString() { - return "OperatorInfo " + operatorAlphaLong - + "/" + operatorAlphaShort - + "/" + operatorNumeric - + "/" + state; - } - - /** - * Parcelable interface implemented below. - * This is a simple effort to make OperatorInfo parcelable rather than - * trying to make the conventional containing object (AsyncResult), - * 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 OperatorInfo object. - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(operatorAlphaLong); - dest.writeString(operatorAlphaShort); - dest.writeString(operatorNumeric); - dest.writeSerializable(state); - } - - /** - * Implement the Parcelable interface - * Method to deserialize a OperatorInfo object, or an array thereof. - */ - public static final Creator CREATOR = - new Creator() { - public OperatorInfo createFromParcel(Parcel in) { - OperatorInfo opInfo = new OperatorInfo( - in.readString(), /*operatorAlphaLong*/ - in.readString(), /*operatorAlphaShort*/ - in.readString(), /*operatorNumeric*/ - (State) in.readSerializable()); /*state*/ - return opInfo; - } - - public OperatorInfo[] newArray(int size) { - return new OperatorInfo[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java deleted file mode 100644 index d41ce4d928a6..000000000000 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ /dev/null @@ -1,1786 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.telephony.CellLocation; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; - -import com.android.internal.telephony.DataConnection; -import com.android.internal.telephony.gsm.UsimServiceTable; -import com.android.internal.telephony.ims.IsimRecords; -import com.android.internal.telephony.test.SimulatedRadioControl; - -import java.util.List; - -/** - * Internal interface used to control the phone; SDK developers cannot - * obtain this interface. - * - * {@hide} - * - */ -public interface Phone { - - /** used to enable additional debug messages */ - static final boolean DEBUG_PHONE = true; - - - /** - * The phone state. One of the following:

- *

    - *
  • IDLE = no phone activity
  • - *
  • RINGING = a phone call is ringing or call waiting. - * In the latter case, another call is active as well
  • - *
  • OFFHOOK = The phone is off hook. At least one call - * exists that is dialing, active or holding and no calls are - * ringing or waiting.
  • - *
- */ - enum State { - IDLE, RINGING, OFFHOOK; - }; - - /** - * The state of a data connection. - *
    - *
  • CONNECTED = IP traffic should be available
  • - *
  • CONNECTING = Currently setting up data connection
  • - *
  • DISCONNECTED = IP not available
  • - *
  • SUSPENDED = connection is created but IP traffic is - * temperately not available. i.e. voice call is in place - * in 2G network
  • - *
- */ - enum DataState { - CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED; - }; - - public enum DataActivityState { - /** - * The state of a data activity. - *
    - *
  • NONE = No traffic
  • - *
  • DATAIN = Receiving IP ppp traffic
  • - *
  • DATAOUT = Sending IP ppp traffic
  • - *
  • DATAINANDOUT = Both receiving and sending IP ppp traffic
  • - *
  • DORMANT = The data connection is still active, - but physical link is down
  • - *
- */ - NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT; - }; - - enum SuppService { - UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP; - }; - - static final String STATE_KEY = "state"; - static final String PHONE_NAME_KEY = "phoneName"; - static final String FAILURE_REASON_KEY = "reason"; - static final String STATE_CHANGE_REASON_KEY = "reason"; - static final String DATA_APN_TYPE_KEY = "apnType"; - static final String DATA_APN_KEY = "apn"; - static final String DATA_LINK_PROPERTIES_KEY = "linkProperties"; - static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities"; - - static final String DATA_IFACE_NAME_KEY = "iface"; - static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable"; - static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming"; - static final String PHONE_IN_ECM_STATE = "phoneinECMState"; - - /** - * APN types for data connections. These are usage categories for an APN - * entry. One APN entry may support multiple APN types, eg, a single APN - * may service regular internet traffic ("default") as well as MMS-specific - * connections.
- * APN_TYPE_ALL is a special type to indicate that this APN entry can - * service all data connections. - */ - static final String APN_TYPE_ALL = "*"; - /** APN type for default data traffic */ - static final String APN_TYPE_DEFAULT = "default"; - /** APN type for MMS traffic */ - static final String APN_TYPE_MMS = "mms"; - /** APN type for SUPL assisted GPS */ - static final String APN_TYPE_SUPL = "supl"; - /** APN type for DUN traffic */ - static final String APN_TYPE_DUN = "dun"; - /** APN type for HiPri traffic */ - static final String APN_TYPE_HIPRI = "hipri"; - /** APN type for FOTA */ - static final String APN_TYPE_FOTA = "fota"; - /** APN type for IMS */ - static final String APN_TYPE_IMS = "ims"; - /** APN type for CBS */ - static final String APN_TYPE_CBS = "cbs"; - - // "Features" accessible through the connectivity manager - static final String FEATURE_ENABLE_MMS = "enableMMS"; - static final String FEATURE_ENABLE_SUPL = "enableSUPL"; - static final String FEATURE_ENABLE_DUN = "enableDUN"; - static final String FEATURE_ENABLE_HIPRI = "enableHIPRI"; - static final String FEATURE_ENABLE_DUN_ALWAYS = "enableDUNAlways"; - static final String FEATURE_ENABLE_FOTA = "enableFOTA"; - static final String FEATURE_ENABLE_IMS = "enableIMS"; - static final String FEATURE_ENABLE_CBS = "enableCBS"; - - /** - * Return codes for enableApnType() - */ - static final int APN_ALREADY_ACTIVE = 0; - static final int APN_REQUEST_STARTED = 1; - static final int APN_TYPE_NOT_AVAILABLE = 2; - static final int APN_REQUEST_FAILED = 3; - static final int APN_ALREADY_INACTIVE = 4; - - - /** - * Optional reasons for disconnect and connect - */ - static final String REASON_ROAMING_ON = "roamingOn"; - static final String REASON_ROAMING_OFF = "roamingOff"; - static final String REASON_DATA_DISABLED = "dataDisabled"; - static final String REASON_DATA_ENABLED = "dataEnabled"; - static final String REASON_DATA_ATTACHED = "dataAttached"; - static final String REASON_DATA_DETACHED = "dataDetached"; - static final String REASON_CDMA_DATA_ATTACHED = "cdmaDataAttached"; - 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_APN_FAILED = "apnFailed"; - static final String REASON_RESTORE_DEFAULT_APN = "restoreDefaultApn"; - static final String REASON_RADIO_TURNED_OFF = "radioTurnedOff"; - static final String REASON_PDP_RESET = "pdpReset"; - static final String REASON_VOICE_CALL_ENDED = "2GVoiceCallEnded"; - static final String REASON_VOICE_CALL_STARTED = "2GVoiceCallStarted"; - static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled"; - static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled"; - static final String REASON_SIM_LOADED = "simLoaded"; - static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged"; - static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet"; - static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet"; - static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged"; - - // Used for band mode selection methods - static final int BM_UNSPECIFIED = 0; // selected by baseband automatically - static final int BM_EURO_BAND = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000 - static final int BM_US_BAND = 2; // GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900 - static final int BM_JPN_BAND = 3; // WCDMA-800 / WCDMA-IMT-2000 - static final int BM_AUS_BAND = 4; // GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000 - static final int BM_AUS2_BAND = 5; // GSM-900 / DCS-1800 / WCDMA-850 - static final int BM_BOUNDARY = 6; // upper band boundary - - // Radio Type - static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE; - static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE; - static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE; - static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE; - - // Modes for LTE_ON_CDMA - static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN; - static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE; - static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE; - - // Used for preferred network type - // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone - int NT_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF; - int NT_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY; - int NT_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY; - int NT_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS; - - int NT_MODE_CDMA = RILConstants.NETWORK_MODE_CDMA; - - int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; - int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; - int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL; - - int NT_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY; - int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE; - - - // Used for CDMA roaming mode - static final int CDMA_RM_HOME = 0; // Home Networks only, as defined in PRL - static final int CDMA_RM_AFFILIATED = 1; // Roaming an Affiliated networks, as defined in PRL - static final int CDMA_RM_ANY = 2; // Roaming on Any Network, as defined in PRL - - // Used for CDMA subscription mode - static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default) - static final int CDMA_SUBSCRIPTION_NV = 1; // NV -> non-volatile memory - - static final int PREFERRED_CDMA_SUBSCRIPTION = CDMA_SUBSCRIPTION_NV; - - static final int TTY_MODE_OFF = 0; - static final int TTY_MODE_FULL = 1; - static final int TTY_MODE_HCO = 2; - static final int TTY_MODE_VCO = 3; - - /** - * CDMA OTA PROVISION STATUS, the same as RIL_CDMA_OTA_Status in ril.h - */ - - public static final int CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED = 0; - public static final int CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED = 1; - public static final int CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED = 2; - public static final int CDMA_OTA_PROVISION_STATUS_SSD_UPDATED = 3; - public static final int CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED = 4; - public static final int CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED = 5; - public static final int CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED = 6; - public static final int CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED = 7; - public static final int CDMA_OTA_PROVISION_STATUS_COMMITTED = 8; - public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED = 9; - public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED = 10; - public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED = 11; - - - /** - * Get the current ServiceState. Use - * registerForServiceStateChanged to be informed of - * updates. - */ - ServiceState getServiceState(); - - /** - * Get the current CellLocation. - */ - CellLocation getCellLocation(); - - /** - * Get the current for the default apn DataState. No change notification - * exists at this interface -- use - * {@link android.telephony.PhoneStateListener} instead. - */ - DataState getDataConnectionState(); - - /** - * Get the current DataState. No change notification exists at this - * interface -- use - * {@link android.telephony.PhoneStateListener} instead. - * @param apnType specify for which apn to get connection state info. - */ - DataState getDataConnectionState(String apnType); - - /** - * Get the current DataActivityState. No change notification exists at this - * interface -- use - * {@link android.telephony.TelephonyManager} instead. - */ - DataActivityState getDataActivityState(); - - /** - * Gets the context for the phone, as set at initialization time. - */ - Context getContext(); - - /** - * Disables the DNS check (i.e., allows "0.0.0.0"). - * Useful for lab testing environment. - * @param b true disables the check, false enables. - */ - void disableDnsCheck(boolean b); - - /** - * Returns true if the DNS check is currently disabled. - */ - boolean isDnsCheckDisabled(); - - /** - * Get current coarse-grained voice call state. - * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object) - * registerForPreciseCallStateChanged()} for change notification.

- * If the phone has an active call and call waiting occurs, - * then the phone state is RINGING not OFFHOOK - * Note: - * This registration point provides notification of finer-grained - * changes.

- * - */ - State getState(); - - /** - * Returns a string identifier for this phone interface for parties - * outside the phone app process. - * @return The string name. - */ - String getPhoneName(); - - /** - * Return a numerical identifier for the phone radio interface. - * @return PHONE_TYPE_XXX as defined above. - */ - int getPhoneType(); - - /** - * Returns an array of string identifiers for the APN types serviced by the - * currently active. - * @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT. - * TODO: Revisit if we always should return at least one entry. - */ - String[] getActiveApnTypes(); - - /** - * Returns string for the active APN host. - * @return type as a string or null if none. - */ - String getActiveApnHost(String apnType); - - /** - * Return the LinkProperties for the named apn or null if not available - */ - LinkProperties getLinkProperties(String apnType); - - /** - * Return the LinkCapabilities - */ - LinkCapabilities getLinkCapabilities(String apnType); - - /** - * Get current signal strength. No change notification available on this - * interface. Use PhoneStateNotifier or an equivalent. - * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). - * The following special values are defined:

- *
  • 0 means "-113 dBm or less".
  • - *
  • 31 means "-51 dBm or greater".
- * - * @return Current signal strength as SignalStrength - */ - SignalStrength getSignalStrength(); - - /** - * 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. - */ - void registerForUnknownConnection(Handler h, int what, Object obj); - - /** - * Unregisters for unknown connection notifications. - */ - void unregisterForUnknownConnection(Handler h); - - /** - * Register for getting notifications for change in the Call State {@link Call.State} - * This is called PreciseCallState because the call state is more precise than the - * {@link Phone.State} which can be obtained using the {@link PhoneStateListener} - * - * Resulting events will have an AsyncResult in Message.obj. - * AsyncResult.userData will be set to the obj argument here. - * The h parameter is held only by a weak reference. - */ - void registerForPreciseCallStateChanged(Handler h, int what, Object obj); - - /** - * Unregisters for voice call state change notifications. - * Extraneous calls are tolerated silently. - */ - void unregisterForPreciseCallStateChanged(Handler h); - - - /** - * Notifies when a new ringing or waiting connection has appeared.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection.

- * Please check Connection.isRinging() to make sure the Connection - * has not dropped since this message was posted. - * If Connection.isRinging() is true, then - * Connection.getCall() == Phone.getRingingCall() - */ - void registerForNewRingingConnection(Handler h, int what, Object obj); - - /** - * Unregisters for new ringing connection notification. - * Extraneous calls are tolerated silently - */ - - void unregisterForNewRingingConnection(Handler h); - - /** - * Notifies when an incoming call rings.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection.

- */ - void registerForIncomingRing(Handler h, int what, Object obj); - - /** - * Unregisters for ring notification. - * Extraneous calls are tolerated silently - */ - - void unregisterForIncomingRing(Handler h); - - /** - * Notifies when out-band ringback tone is needed.

- * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = boolean, true to start play ringback tone - * and false to stop.

- */ - void registerForRingbackTone(Handler h, int what, Object obj); - - /** - * Unregisters for ringback tone notification. - */ - - void unregisterForRingbackTone(Handler h); - - /** - * Registers the handler to reset the uplink mute state to get - * uplink audio. - */ - void registerForResendIncallMute(Handler h, int what, Object obj); - - /** - * Unregisters for resend incall mute notifications. - */ - void unregisterForResendIncallMute(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:

- *

  • Message.obj will be an AsyncResult
  • - *
  • AsyncResult.userObj = obj
  • - *
  • AsyncResult.result = a Connection object that is - * no longer connected.
- */ - void registerForDisconnect(Handler h, int what, Object obj); - - /** - * Unregisters for voice disconnection notification. - * Extraneous calls are tolerated silently - */ - void unregisterForDisconnect(Handler h); - - - /** - * Register for notifications of initiation of a new MMI code request. - * MMI codes for GSM are discussed in 3GPP TS 22.030.

- * - * Example: If Phone.dial is called with "*#31#", then the app will - * be notified here.

- * - * The returned Message.obj will contain an AsyncResult. - * - * obj.result will be an "MmiCode" object. - */ - void registerForMmiInitiate(Handler h, int what, Object obj); - - /** - * Unregisters for new MMI initiate notification. - * Extraneous calls are tolerated silently - */ - void unregisterForMmiInitiate(Handler h); - - /** - * Register for notifications that an MMI request has completed - * its network activity and is in its final state. This may mean a state - * of COMPLETE, FAILED, or CANCELLED. - * - * Message.obj will contain an AsyncResult. - * obj.result will be an "MmiCode" object - */ - void registerForMmiComplete(Handler h, int what, Object obj); - - /** - * Unregisters for MMI complete notification. - * Extraneous calls are tolerated silently - */ - void unregisterForMmiComplete(Handler h); - - /** - * Registration point for Ecm timer reset - * @param h handler to notify - * @param what user-defined message code - * @param obj placed in Message.obj - */ - public void registerForEcmTimerReset(Handler h, int what, Object obj); - - /** - * Unregister for notification for Ecm timer reset - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForEcmTimerReset(Handler h); - - /** - * Returns a list of MMI codes that are pending. (They have initiated - * but have not yet completed). - * Presently there is only ever one. - * Use registerForMmiInitiate - * and registerForMmiComplete for change notification. - */ - public List getPendingMmiCodes(); - - /** - * Sends user response to a USSD REQUEST message. An MmiCode instance - * representing this response is sent to handlers registered with - * registerForMmiInitiate. - * - * @param ussdMessge Message to send in the response. - */ - public void sendUssdResponse(String ussdMessge); - - /** - * 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. - * Extraneous calls are tolerated silently - */ - void unregisterForServiceStateChanged(Handler h); - - /** - * Register for Supplementary Service notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForSuppServiceNotification(Handler h, int what, Object obj); - - /** - * Unregisters for Supplementary Service notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForSuppServiceNotification(Handler h); - - /** - * Register for notifications when a supplementary service attempt fails. - * Message.obj will contain an AsyncResult. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForSuppServiceFailed(Handler h, int what, Object obj); - - /** - * 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); - - /** - * 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); - - /** - * Register for notifications when CDMA OTA Provision status change - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForCdmaOtaStatusChange(Handler h, int what, Object obj); - - /** - * Unegister for notifications when CDMA OTA Provision status change - * @param h Handler to be removed from the registrant list. - */ - void unregisterForCdmaOtaStatusChange(Handler h); - - /** - * Registration point for subscription info ready - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj); - - /** - * Unregister for notifications for subscription info - * @param h Handler to be removed from the registrant list. - */ - public void unregisterForSubscriptionInfoReady(Handler h); - - /** - * Returns SIM record load state. Use - * getSimCard().registerForReady() for change notification. - * - * @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 getIccRecordsLoaded(); - - /** - * Returns the ICC card interface for this phone, or null - * if not applicable to underlying technology. - */ - IccCard getIccCard(); - - /** - * Answers a ringing or waiting call. Active calls, if any, go on hold. - * Answering occurs asynchronously, and final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @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 #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @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 #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if a call is ringing, waiting, or - * dialing/alerting. In these cases, this operation may not be performed. - */ - void switchHoldingAndActive() throws CallStateException; - - /** - * 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. - */ - boolean canConference(); - - /** - * Conferences holding and active. Conference occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if canConference() would return false. - * In these cases, this operation may not be performed. - */ - void conference() throws CallStateException; - - /** - * 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); - - /** - * Whether or not the phone can do explicit call transfer in the current - * phone state--that is, one call holding and one call active. - * @return true if the phone can do explicit call transfer; false otherwise. - */ - boolean canTransfer(); - - /** - * Connects the two calls and disconnects the subscriber from both calls - * Explicit Call Transfer occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - * - * @exception CallStateException if canTransfer() would return false. - * In these cases, this operation may not be performed. - */ - void explicitCallTransfer() throws CallStateException; - - /** - * Clears all DISCONNECTED connections from Call connection lists. - * Calls that were in the DISCONNECTED state become idle. This occurs - * synchronously. - */ - void clearDisconnected(); - - - /** - * Gets the foreground call object, which represents all connections that - * are dialing or active (all connections - * that have their audio path connected).

- * - * The foreground call is a singleton object. It is constant for the life - * of this phone. It is never null.

- * - * The foreground call will only ever be in one of these states: - * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - */ - 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).

- * - * The background call is a singleton object. It is constant for the life - * of this phone object . It is never null.

- * - * The background call will only ever be in one of these states: - * IDLE, HOLDING or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - */ - Call getBackgroundCall(); - - /** - * 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.)

- - * The ringing call is a singleton object. It is constant for the life - * of this phone. It is never null.

- * - * The ringing call will only ever be in one of these states: - * IDLE, INCOMING, WAITING or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()}. - */ - 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 - * handled asynchronously. - */ - Connection dial(String dialString) throws CallStateException; - - /** - * Initiate a new voice connection with supplementary User to User - * Information. 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 handled asynchronously. - */ - Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException; - - /** - * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated - * without SEND (so dial is not appropriate). - * - * @param dialString the MMI command to be executed. - * @return true if MMI command is executed. - */ - boolean handlePinMmi(String dialString); - - /** - * Handles in-call MMI commands. While in a call, or while receiving a - * call, use this to execute MMI commands. - * see 3GPP 20.030, section 6.5.5.1 for specs on the allowed MMI commands. - * - * @param command the MMI command to be executed. - * @return true if the MMI command is executed. - * @throws CallStateException - */ - boolean handleInCallMmiCommands(String command) throws CallStateException; - - /** - * 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. - */ - void sendDtmf(char c); - - /** - * Start to paly a DTMF tone on the active call. Ignored if there is no active call - * or there is a playing DTMF tone. - * @param c should be one of 0-9, '*' or '#'. Other values will be - * silently ignored. - */ - void startDtmf(char c); - - /** - * Stop the playing DTMF tone. Ignored if there is no playing DTMF - * tone or no active call. - */ - void stopDtmf(); - - /** - * send burst DTMF tone, it can send the string as single character or multiple character - * ignore if there is no active call or not valid digits string. - * Valid digit means only includes characters ISO-LATIN characters 0-9, *, # - * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character, - * this api can send single character and multiple character, also, this api has response - * back to caller. - * - * @param dtmfString is string representing the dialing digit(s) in the active call - * @param on the DTMF ON length in milliseconds, or 0 for default - * @param off the DTMF OFF length in milliseconds, or 0 for default - * @param onComplete is the callback message when the action is processed by BP - * - */ - void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete); - - /** - * 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()}. - * Note: This request is asynchronous. - * getServiceState().getState() will not change immediately after this call. - * registerForServiceStateChanged() to find out when the - * request is complete. - * - * @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. - * - * @return true if there is a voice message waiting - */ - boolean getMessageWaitingIndicator(); - - /** - * Get voice call forwarding indicator status. No change notification - * available on this interface. Use PhoneStateNotifier or similar instead. - * - * @return true if there is a voice call forwarding - */ - boolean getCallForwardingIndicator(); - - /** - * Get the line 1 phone number (MSISDN). For CDMA phones, the MDN is returned - * and {@link #getMsisdn()} will return the MSISDN on CDMA/LTE phones.

- * - * @return phone number. May return null if not - * available or the SIM is not ready - */ - String getLine1Number(); - - /** - * Returns the alpha tag associated with the msisdn number. - * If there is no alpha tag associated or the record is not yet available, - * returns a default localized string.

- */ - String getLine1AlphaTag(); - - /** - * Sets the MSISDN phone number in the SIM card. - * - * @param alphaTag the alpha tag associated with the MSISDN phone number - * (see getMsisdnAlphaTag) - * @param number the new MSISDN phone number to be set on the SIM. - * @param onComplete a callback message when the action is completed. - */ - 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 - * available or the SIM is not ready.

- */ - String getVoiceMailNumber(); - - /** - * Returns unread voicemail count. This count is shown when the voicemail - * notification is expanded.

- */ - int getVoiceMessageCount(); - - /** - * Returns the alpha tag associated with the voice mail number. - * If there is no alpha tag associated or the record is not yet available, - * returns a default localized string.

- * - * 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.

- * - * Usage of this alpha tag in the UI is a common carrier requirement. - */ - String getVoiceMailAlphaTag(); - - /** - * setVoiceMailNumber - * sets the voicemail number in the SIM card. - * - * @param alphaTag the alpha tag associated with the voice mail number - * (see getVoiceMailAlphaTag) - * @param voiceMailNumber the new voicemail number to be set on the SIM. - * @param onComplete a callback message when the action is completed. - */ - void setVoiceMailNumber(String alphaTag, - String voiceMailNumber, - Message onComplete); - - /** - * 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 - * com.android.internal.telephony.CommandsInterface. - * @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 - * com.android.internal.telephony.CommandsInterface. - * @param commandInterfaceCFAction is one of the valid call forwarding - * CF_ACTIONS, as defined in - * com.android.internal.telephony.CommandsInterface. - * @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. - */ - void setCallForwardingOption(int commandInterfaceCFReason, - int commandInterfaceCFAction, - String dialingNumber, - int timerSeconds, - Message onComplete); - - /** - * getOutgoingCallerIdDisplay - * 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.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 - * 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 - * ((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.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 - * 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, response.obj is set to an AsyncResult with - * one of the following members:.

- *

    - *
  • response.obj.result will be a List of - * OperatorInfo objects, or
  • - *
  • response.obj.exception will be set with an exception - * on failure.
  • - *
- */ - 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 - * is complete. - * - * @see #selectNetworkManually(OperatorInfo, android.os.Message ) - */ - void setNetworkSelectionModeAutomatic(Message response); - - /** - * Manually selects a network. response is - * dispatched when this is complete. response.obj will be - * an AsyncResult, and response.obj.exception will be non-null - * on failure. - * - * @see #setNetworkSelectionModeAutomatic(Message) - */ - void selectNetworkManually(OperatorInfo network, - Message response); - - /** - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * @param networkType one of NT_*_TYPE - * @param response is callback message - */ - void setPreferredNetworkType(int networkType, Message response); - - /** - * Query the preferred network type setting - * - * @param response is callback message to report one of NT_*_TYPE - */ - void getPreferredNetworkType(Message response); - - /** - * Gets the default SMSC address. - * - * @param result Callback message contains the SMSC address. - */ - void getSmscAddress(Message result); - - /** - * Sets the default SMSC address. - * - * @param address new SMSC address - * @param result Callback message is empty on completion - */ - void setSmscAddress(String address, Message result); - - /** - * Query neighboring cell IDs. response is dispatched when - * this is complete. response.obj will be an AsyncResult, - * and response.obj.exception will be non-null on failure. - * On success, AsyncResult.result will be a String[] - * containing the neighboring cell IDs. Index 0 will contain the count - * of available cell IDs. Cell IDs are in hexadecimal format. - * - * @param response callback message that is dispatched when the query - * completes. - */ - void getNeighboringCids(Message response); - - /** - * Sets an event to be fired when the telephony system processes - * a post-dial character on an outgoing call.

- * - * Messages of type what will be sent to h. - * The obj field of these Message's will be instances of - * AsyncResult. Message.obj.result will be - * a Connection object.

- * - * Message.arg1 will be the post dial character being processed, - * or 0 ('\0') if end of string.

- * - * 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 - * DTMF sequence.

- * - * 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() - * Connection.cancelPostDial()} - * for the telephony system to continue playing the - * post-dial DTMF sequence.

- * - * Only one post dial character handler may be set.

- * Calling this method with "h" equal to null unsets this handler.

- */ - void setOnPostDialCharacter(Handler h, int what, Object obj); - - - /** - * 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, - * false to activate the microphone. - */ - - void setMute(boolean muted); - - /** - * Gets current mute status. Use - * {@link #registerForPreciseCallStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPreciseCallStateChanged()} - * as a change notifcation, although presently phone state changed is not - * fired when setMute() is called. - * - * @return true is muting, false is unmuting - */ - boolean getMute(); - - /** - * Enables or disables echo suppression. - */ - void setEchoSuppressionEnabled(boolean enabled); - - /** - * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation. - * - * @param data The data for the request. - * @param response On success, - * (byte[])(((AsyncResult)response.obj).result) - * On failure, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * @see #invokeOemRilRequestRaw(byte[], android.os.Message) - */ - void invokeOemRilRequestRaw(byte[] data, Message response); - - /** - * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation. - * - * @param strings The strings to make available as the request data. - * @param response On success, "response" bytes is - * made available as: - * (String[])(((AsyncResult)response.obj).result). - * On failure, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message) - */ - void invokeOemRilRequestStrings(String[] strings, Message response); - - /** - * Get the current active Data Call list - * - * @param response On success, "response" bytes is - * made available as: - * (String[])(((AsyncResult)response.obj).result). - * On failure, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - */ - void getDataCallList(Message response); - - /** - * Update the ServiceState CellLocation for current network registration. - */ - void updateServiceLocation(); - - /** - * Enable location update notifications. - */ - void enableLocationUpdates(); - - /** - * Disable location update notifications. - */ - void disableLocationUpdates(); - - /** - * 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 - */ - boolean getUnitTestMode(); - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - void setBandMode(int bandMode, Message response); - - /** - * 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 - */ - void queryAvailableBandMode(Message response); - - /** - * @return true if enable data connection on roaming - */ - boolean getDataRoamingEnabled(); - - /** - * @param enable set true if enable data connection on roaming - */ - void setDataRoamingEnabled(boolean enable); - - /** - * Query the CDMA roaming preference setting - * - * @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); - - /** - * If this is a simulated phone interface, returns a SimulatedRadioControl. - * @ return A SimulatedRadioControl if this is a simulated interface; - * otherwise, null. - */ - SimulatedRadioControl getSimulatedRadioControl(); - - /** - * Enables the specified APN type. Only works for "special" APN types, - * i.e., not the default APN. - * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}. - * @return APN_ALREADY_ACTIVE if the current APN - * services the requested type.
- * APN_TYPE_NOT_AVAILABLE if the carrier does not - * support the requested APN.
- * APN_REQUEST_STARTED if the request has been initiated.
- * APN_REQUEST_FAILED if the request was invalid.
- * A ACTION_ANY_DATA_CONNECTION_STATE_CHANGED broadcast will - * indicate connection state progress. - */ - int enableApnType(String type); - - /** - * Disables the specified APN type, and switches back to the default APN, - * if necessary. Switching to the default APN will not happen if default - * data traffic has been explicitly disabled via a call to {@link #disableDataConnectivity}. - *

Only works for "special" APN types, - * i.e., not the default APN. - * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}. - * @return APN_ALREADY_ACTIVE if the default APN - * is already active.
- * APN_REQUEST_STARTED if the request to switch to the default - * APN has been initiated.
- * APN_REQUEST_FAILED if the request was invalid.
- * A ACTION_ANY_DATA_CONNECTION_STATE_CHANGED broadcast will - * indicate connection state progress. - */ - int disableApnType(String type); - - /** - * Report on whether data connectivity is allowed. - */ - boolean isDataConnectivityPossible(); - - /** - * Report on whether data connectivity is allowed for an APN. - */ - boolean isDataConnectivityPossible(String apnType); - - /** - * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones. - */ - String getDeviceId(); - - /** - * Retrieves the software version number for the device, e.g., IMEI/SV - * for GSM phones. - */ - String getDeviceSvn(); - - /** - * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. - */ - String getSubscriberId(); - - /** - * Retrieves the serial number of the ICC, if applicable. - */ - String getIccSerialNumber(); - - /* CDMA support methods */ - - /** - * Retrieves the MIN for CDMA phones. - */ - String getCdmaMin(); - - /** - * Check if subscription data has been assigned to mMin - * - * return true if MIN info is ready; false otherwise. - */ - boolean isMinInfoReady(); - - /** - * Retrieves PRL Version for CDMA phones - */ - String getCdmaPrlVersion(); - - /** - * Retrieves the ESN for CDMA phones. - */ - String getEsn(); - - /** - * Retrieves MEID for CDMA phones. - */ - String getMeid(); - - /** - * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to - * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns - * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones. - */ - String getMsisdn(); - - /** - * Retrieves IMEI for phones. Returns null if IMEI is not set. - */ - String getImei(); - - /** - * Retrieves the PhoneSubInfo of the Phone - */ - public PhoneSubInfo getPhoneSubInfo(); - - /** - * Retrieves the IccSmsInterfaceManager of the Phone - */ - public IccSmsInterfaceManager getIccSmsInterfaceManager(); - - /** - * Retrieves the IccPhoneBookInterfaceManager of the Phone - */ - public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(); - - /** - * setTTYMode - * sets a TTY mode option. - * @param ttyMode is a one of the following: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * @param onComplete a callback message when the action is completed - */ - void setTTYMode(int ttyMode, Message onComplete); - - /** - * queryTTYMode - * query the status of the TTY mode - * - * @param onComplete a callback message when the action is completed. - */ - void queryTTYMode(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. - * - * TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig - * - * @param response - * Callback message is empty on completion - */ - public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response); - - public void notifyDataActivity(); - - /** - * Returns the CDMA ERI icon index to display - */ - public int getCdmaEriIconIndex(); - - /** - * Returns the CDMA ERI icon mode, - * 0 - ON - * 1 - FLASHING - */ - public int getCdmaEriIconMode(); - - /** - * Returns the CDMA ERI text, - */ - public String getCdmaEriText(); - - /** - * request to exit emergency call back mode - * the caller should use setOnECMModeExitResponse - * to receive the emergency callback mode exit response - */ - void exitEmergencyCallbackMode(); - - /** - * this decides if the dial number is OTA(Over the air provision) number or not - * @param dialStr is string representing the dialing digit(s) - * @return true means the dialStr is OTA number, and false means the dialStr is not OTA number - */ - boolean isOtaSpNumber(String dialStr); - - /** - * Returns true if OTA Service Provisioning needs to be performed. - */ - boolean needsOtaServiceProvisioning(); - - /** - * Register for notifications when CDMA call waiting comes - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForCallWaiting(Handler h, int what, Object obj); - - /** - * Unegister for notifications when CDMA Call waiting comes - * @param h Handler to be removed from the registrant list. - */ - void unregisterForCallWaiting(Handler h); - - - /** - * Register for signal information notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - - void registerForSignalInfo(Handler h, int what, Object obj) ; - /** - * Unregisters for signal information notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForSignalInfo(Handler h); - - /** - * Register for display information notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForDisplayInfo(Handler h, int what, Object obj); - - /** - * Unregisters for display information notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForDisplayInfo(Handler h) ; - - /** - * Register for CDMA number information record notification from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec - * instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForNumberInfo(Handler h, int what, Object obj); - - /** - * Unregisters for number information record notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForNumberInfo(Handler h); - - /** - * Register for CDMA redirected number information record notification - * from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec - * instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForRedirectedNumberInfo(Handler h, int what, Object obj); - - /** - * Unregisters for redirected number information record notification. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForRedirectedNumberInfo(Handler h); - - /** - * Register for CDMA line control information record notification - * from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec - * instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForLineControlInfo(Handler h, int what, Object obj); - - /** - * Unregisters for line control information notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForLineControlInfo(Handler h); - - /** - * Register for CDMA T53 CLIR information record notifications - * from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec - * instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerFoT53ClirlInfo(Handler h, int what, Object obj); - - /** - * Unregisters for T53 CLIR information record notification - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForT53ClirInfo(Handler h); - - /** - * Register for CDMA T53 audio control information record notifications - * from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec - * instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForT53AudioControlInfo(Handler h, int what, Object obj); - - /** - * Unregisters for T53 audio control information record notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForT53AudioControlInfo(Handler h); - - /** - * registers for exit emergency call back mode request response - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - - void setOnEcbModeExitResponse(Handler h, int what, Object obj); - - /** - * Unregisters for exit emergency call back mode request response - * - * @param h Handler to be removed from the registrant list. - */ - void unsetOnEcbModeExitResponse(Handler h); - - /** - * Return if the current radio is LTE on CDMA. This - * is a tri-state return value as for a period of time - * the mode may be unknown. - * - * @return {@link #LTE_ON_CDMA_UNKNOWN}, {@link #LTE_ON_CDMA_FALSE} or {@link #LTE_ON_CDMA_TRUE} - */ - public int getLteOnCdmaMode(); - - /** - * TODO: Adding a function for each property is not good. - * A fucntion of type getPhoneProp(propType) where propType is an - * enum of GSM+CDMA+LTE props would be a better approach. - * - * Get "Restriction of menu options for manual PLMN selection" bit - * status from EF_CSP data, this belongs to "Value Added Services Group". - * @return true if this bit is set or EF_CSP data is unavailable, - * false otherwise - */ - boolean isCspPlmnEnabled(); - - /** - * Return an interface to retrieve the ISIM records for IMS, if available. - * @return the interface to retrieve the ISIM records, or null if not supported - */ - IsimRecords getIsimRecords(); - - /** - * Request the ISIM application on the UICC to perform the AKA - * challenge/response algorithm for IMS authentication. The nonce string - * and challenge response are Base64 encoded Strings. - * - * @param nonce the nonce string to pass with the ISIM authentication request - * @param response a callback message with the String response in the obj field - */ - void requestIsimAuthentication(String nonce, Message response); - - /** - * 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 - * messages are waiting - */ - void setVoiceMessageWaiting(int line, int countWaiting); - - /** - * Gets the USIM service table from the UICC, if present and available. - * @return an interface to the UsimServiceTable record, or null if not available - */ - UsimServiceTable getUsimServiceTable(); - - /** - * Unregister from all events it registered for and dispose objects - * created by this object. - */ - void dispose(); - - /** - * Remove references to external object stored in this object. - */ - void removeReferences(); -} diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java deleted file mode 100644 index 2ac936593a42..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ /dev/null @@ -1,1188 +0,0 @@ -/* - * 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; - -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import android.content.Context; -import android.content.res.Configuration; -import android.content.SharedPreferences; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.net.wifi.WifiManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Settings; -import android.telephony.ServiceState; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.R; -import com.android.internal.telephony.gsm.UsimServiceTable; -import com.android.internal.telephony.ims.IsimRecords; -import com.android.internal.telephony.test.SimulatedRadioControl; -import com.android.internal.telephony.gsm.SIMRecords; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicReference; - - -/** - * (Not for SDK use) - * 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. - * - * {@hide} - * - */ - -public abstract class PhoneBase extends Handler implements Phone { - private static final String LOG_TAG = "PHONE"; - private static final boolean LOCAL_DEBUG = true; - - // Key used to read and write the saved network selection numeric value - public static final String NETWORK_SELECTION_KEY = "network_selection_key"; - // Key used to read and write the saved network selection operator name - public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_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. */ - protected static final int EVENT_SSN = 2; - protected static final int EVENT_SIM_RECORDS_LOADED = 3; - protected static final int EVENT_MMI_DONE = 4; - protected static final int EVENT_RADIO_ON = 5; - protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; - protected static final int EVENT_USSD = 7; - protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; - protected static final int EVENT_GET_IMEI_DONE = 9; - protected static final int EVENT_GET_IMEISV_DONE = 10; - protected static final int EVENT_GET_SIM_STATUS_DONE = 11; - 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; - protected static final int EVENT_CALL_RING_CONTINUE = 15; - - // Used to intercept the carrier selection calls so that - // we can save the values. - protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; - protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; - protected static final int EVENT_SET_CLIR_COMPLETE = 18; - protected static final int EVENT_REGISTERED_TO_NETWORK = 19; - protected static final int EVENT_SET_VM_NUMBER_DONE = 20; - // Events for CDMA support - protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; - protected static final int EVENT_RUIM_RECORDS_LOADED = 22; - protected static final int EVENT_NV_READY = 23; - protected static final int EVENT_SET_ENHANCED_VP = 24; - protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; - protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; - protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; - // other - protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; - protected static final int EVENT_NEW_ICC_SMS = 29; - protected static final int EVENT_ICC_RECORD_EVENTS = 30; - - // Key used to read/write current CLIR setting - public static final String CLIR_KEY = "clir_key"; - - // Key used to read/write "disable DNS server check" pref (used for testing) - public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; - - /* Instance Variables */ - public CommandsInterface mCM; - boolean mDnsCheckDisabled; - public DataConnectionTracker mDataConnectionTracker; - boolean mDoesRilSendMultipleCallRing; - int mCallRingContinueToken; - int mCallRingDelay; - public boolean mIsTheCurrentActivePhone = true; - boolean mIsVoiceCapable = true; - public IccRecords mIccRecords; - protected AtomicReference mIccCard = new AtomicReference(); - public SmsStorageMonitor mSmsStorageMonitor; - public SmsUsageMonitor mSmsUsageMonitor; - public SMSDispatcher mSMS; - - /** - * Set a system property, unless we're in unit test mode - */ - public void - setSystemProperty(String property, String value) { - if(getUnitTestMode()) { - return; - } - SystemProperties.set(property, value); - } - - - protected final RegistrantList mPreciseCallStateRegistrants - = new RegistrantList(); - - protected final RegistrantList mNewRingingConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mIncomingRingRegistrants - = new RegistrantList(); - - protected final RegistrantList mDisconnectRegistrants - = new RegistrantList(); - - protected final RegistrantList mServiceStateRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiCompleteRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiRegistrants - = new RegistrantList(); - - protected final RegistrantList mUnknownConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mSuppServiceFailedRegistrants - = new RegistrantList(); - - protected Looper mLooper; /* to insure registrants are in correct thread*/ - - protected final Context mContext; - - /** - * 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; - - protected SimulatedRadioControl mSimulatedRadioControl; - - boolean mUnitTestMode; - - /** - * Constructs a PhoneBase in normal (non-unit test) mode. - * - * @param context Context object from hosting application - * @param notifier An instance of DefaultPhoneNotifier, - * unless unit testing. - */ - protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) { - this(notifier, context, ci, false); - } - - /** - * Constructs a PhoneBase in normal (non-unit test) mode. - * - * @param context Context object from hosting application - * @param notifier An instance of DefaultPhoneNotifier, - * unless unit testing. - * @param unitTestMode when true, prevents notifications - * of state change events - */ - protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, - boolean unitTestMode) { - this.mNotifier = notifier; - this.mContext = context; - mLooper = Looper.myLooper(); - mCM = ci; - - setPropertiesByCarrier(); - - setUnitTestMode(unitTestMode); - - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); - mCM.setOnCallRing(this, EVENT_CALL_RING, null); - - /* "Voice capable" means that this device supports circuit-switched - * (i.e. voice) phone calls over the telephony network, and is allowed - * to display the in-call UI while a cellular voice call is active. - * This will be false on "data only" devices which can't make voice - * calls and don't support any in-call UI. - */ - mIsVoiceCapable = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_voice_capable); - - /** - * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs - * to be generated locally. Ideally all ring tones should be loops - * and this wouldn't be necessary. But to minimize changes to upper - * layers it is requested that it be generated by lower layers. - * - * By default old phones won't have the property set but do generate - * the RIL_UNSOL_CALL_RING so the default if there is no property is - * true. - */ - mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); - Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); - - mCallRingDelay = SystemProperties.getInt( - TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); - Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); - - // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. - mSmsStorageMonitor = new SmsStorageMonitor(this); - mSmsUsageMonitor = new SmsUsageMonitor(context); - } - - public void dispose() { - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - mCM.unSetOnCallRing(this); - // Must cleanup all connectionS and needs to use sendMessage! - mDataConnectionTracker.cleanUpAllConnections(null); - mIsTheCurrentActivePhone = false; - // Dispose the SMS usage and storage monitors - mSmsStorageMonitor.dispose(); - mSmsUsageMonitor.dispose(); - } - } - - public void removeReferences() { - mSmsStorageMonitor = null; - mSmsUsageMonitor = null; - mSMS = null; - mIccRecords = null; - mIccCard.set(null); - mDataConnectionTracker = null; - } - - /** - * When overridden the derived class needs to call - * super.handleMessage(msg) so this method has a - * a chance to process the message. - * - * @param msg - */ - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch(msg.what) { - case EVENT_CALL_RING: - Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - Phone.State state = getState(); - if ((!mDoesRilSendMultipleCallRing) - && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) { - mCallRingContinueToken += 1; - sendIncomingCallRingNotification(mCallRingContinueToken); - } else { - notifyIncomingRing(); - } - } - break; - - case EVENT_CALL_RING_CONTINUE: - Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); - if (getState() == Phone.State.RINGING) { - sendIncomingCallRingNotification(msg.arg1); - } - break; - - default: - throw new RuntimeException("unexpected event not handled"); - } - } - - // Inherited documentation suffices. - public Context getContext() { - return mContext; - } - - /** - * Disables the DNS check (i.e., allows "0.0.0.0"). - * Useful for lab testing environment. - * @param b true disables the check, false enables. - */ - public void disableDnsCheck(boolean b) { - mDnsCheckDisabled = b; - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); - editor.apply(); - } - - /** - * Returns true if the DNS check is currently disabled. - */ - public boolean isDnsCheckDisabled() { - return mDnsCheckDisabled; - } - - // Inherited documentation suffices. - public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mPreciseCallStateRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForPreciseCallStateChanged(Handler h) { - mPreciseCallStateRegistrants.remove(h); - } - - /** - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyPreciseCallStateChangedP() { - AsyncResult ar = new AsyncResult(null, this, null); - mPreciseCallStateRegistrants.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) { - checkCorrectThread(h); - - mNewRingingConnectionRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForNewRingingConnection(Handler h) { - 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); - } - - // Inherited documentation suffices. - 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); - - mDisconnectRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForDisconnect(Handler h) { - mDisconnectRegistrants.remove(h); - } - - // 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); - - mMmiRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForMmiInitiate(Handler h) { - mMmiRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForMmiComplete(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mMmiCompleteRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForMmiComplete(Handler h) { - checkCorrectThread(h); - - mMmiCompleteRegistrants.remove(h); - } - - /** - * Method to retrieve the saved operator id from the Shared Preferences - */ - private String getSavedNetworkSelection() { - // open the shared preferences and search with our key. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - return sp.getString(NETWORK_SELECTION_KEY, ""); - } - - /** - * Method to restore the previously saved operator id, or reset to - * automatic selection, all depending upon the value in the shared - * preferences. - */ - 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); - } else { - mCM.setNetworkSelectionModeManual(networkSelection, response); - } - } - - // Inherited documentation suffices. - public void setUnitTestMode(boolean f) { - mUnitTestMode = f; - } - - // Inherited documentation suffices. - public boolean getUnitTestMode() { - return mUnitTestMode; - } - - /** - * To be invoked when a voice call Connection disconnects. - * - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyDisconnectP(Connection cn) { - AsyncResult ar = new AsyncResult(null, cn, null); - mDisconnectRegistrants.notifyRegistrants(ar); - } - - // Inherited documentation suffices. - public void registerForServiceStateChanged( - Handler h, int what, Object obj) { - checkCorrectThread(h); - - mServiceStateRegistrants.add(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForServiceStateChanged(Handler h) { - mServiceStateRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForRingbackTone(Handler h, int what, Object obj) { - mCM.registerForRingbackTone(h,what,obj); - } - - // Inherited documentation suffices. - public void unregisterForRingbackTone(Handler h) { - mCM.unregisterForRingbackTone(h); - } - - // Inherited documentation suffices. - public void registerForResendIncallMute(Handler h, int what, Object obj) { - mCM.registerForResendIncallMute(h,what,obj); - } - - // Inherited documentation suffices. - public void unregisterForResendIncallMute(Handler h) { - mCM.unregisterForResendIncallMute(h); - } - - public void setEchoSuppressionEnabled(boolean enabled) { - // no need for regular phone - } - - /** - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyServiceStateChangedP(ServiceState ss) { - AsyncResult ar = new AsyncResult(null, ss, null); - mServiceStateRegistrants.notifyRegistrants(ar); - - mNotifier.notifyServiceState(this); - } - - // Inherited documentation suffices. - public SimulatedRadioControl getSimulatedRadioControl() { - return mSimulatedRadioControl; - } - - /** - * Verifies the current thread is the same as the thread originally - * used in the initialization of this instance. Throws RuntimeException - * if not. - * - * @exception RuntimeException if the current thread is not - * the thread that originally obtained this PhoneBase instance. - */ - private void checkCorrectThread(Handler h) { - if (h.getLooper() != mLooper) { - throw new RuntimeException( - "com.android.internal.telephony.Phone must be used from within one thread"); - } - } - - /** - * Set the properties by matching the carrier string in - * a string-array resource - */ - private void setPropertiesByCarrier() { - String carrier = SystemProperties.get("ro.carrier"); - - if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { - return; - } - - CharSequence[] carrierLocales = mContext. - getResources().getTextArray(R.array.carrier_properties); - - for (int i = 0; i < carrierLocales.length; i+=3) { - String c = carrierLocales[i].toString(); - if (carrier.equals(c)) { - String l = carrierLocales[i+1].toString(); - - String language = l.substring(0, 2); - String country = ""; - if (l.length() >=5) { - country = l.substring(3, 5); - } - MccTable.setSystemLocale(mContext, language, country); - - if (!country.isEmpty()) { - try { - Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.WIFI_COUNTRY_CODE); - } catch (Settings.SettingNotFoundException e) { - // note this is not persisting - WifiManager wM = (WifiManager) - mContext.getSystemService(Context.WIFI_SERVICE); - wM.setCountryCode(country, false); - } - } - return; - } - } - } - - /** - * Get state - */ - public abstract Phone.State getState(); - - /** - * Retrieves the IccFileHandler of the Phone instance - */ - public IccFileHandler getIccFileHandler(){ - IccCard iccCard = mIccCard.get(); - if (iccCard == null) return null; - return iccCard.getIccFileHandler(); - } - - /* - * Retrieves the Handler of the Phone instance - */ - public Handler getHandler() { - return this; - } - - /** - * Retrieves the ServiceStateTracker of the phone instance. - */ - public ServiceStateTracker getServiceStateTracker() { - return null; - } - - /** - * Get call tracker - */ - public CallTracker getCallTracker() { - return null; - } - - @Override - public IccCard getIccCard() { - return mIccCard.get(); - } - - @Override - public String getIccSerialNumber() { - return mIccRecords.iccid; - } - - @Override - public boolean getIccRecordsLoaded() { - return mIccRecords.getRecordsLoaded(); - } - - @Override - public boolean getMessageWaitingIndicator() { - return mIccRecords.getVoiceMessageWaiting(); - } - - @Override - public boolean getCallForwardingIndicator() { - return mIccRecords.getVoiceCallForwardingFlag(); - } - - /** - * 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.setCdmaSubscriptionSource(cdmaSubscriptionType, response); - } - - /** - * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only - */ - public void setPreferredNetworkType(int networkType, Message response) { - mCM.setPreferredNetworkType(networkType, response); - } - - public void getPreferredNetworkType(Message response) { - mCM.getPreferredNetworkType(response); - } - - public void getSmscAddress(Message result) { - mCM.getSmscAddress(result); - } - - public void setSmscAddress(String address, Message result) { - mCM.setSmscAddress(address, result); - } - - public void setTTYMode(int ttyMode, Message onComplete) { - mCM.setTTYMode(ttyMode, onComplete); - } - - public void queryTTYMode(Message onComplete) { - mCM.queryTTYMode(onComplete); - } - - public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); - } - - public void getEnhancedVoicePrivacy(Message onComplete) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); - } - - public void setBandMode(int bandMode, Message response) { - mCM.setBandMode(bandMode, response); - } - - public void queryAvailableBandMode(Message response) { - mCM.queryAvailableBandMode(response); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) { - mCM.invokeOemRilRequestRaw(data, response); - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) { - mCM.invokeOemRilRequestStrings(strings, response); - } - - public void notifyDataActivity() { - mNotifier.notifyDataActivity(this); - } - - public void notifyMessageWaitingIndicator() { - // Do not notify voice mail waiting if device doesn't support voice - if (!mIsVoiceCapable) - return; - - // This function is added to send the notification to DefaultPhoneNotifier. - mNotifier.notifyMessageWaitingChanged(this); - } - - public void notifyDataConnection(String reason, String apnType, - Phone.DataState state) { - mNotifier.notifyDataConnection(this, reason, apnType, state); - } - - public void notifyDataConnection(String reason, String apnType) { - mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); - } - - public void notifyDataConnection(String reason) { - String types[] = getActiveApnTypes(); - for (String apnType : types) { - mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); - } - } - - public void notifyOtaspChanged(int otaspMode) { - mNotifier.notifyOtaspChanged(this, otaspMode); - } - - /** - * @return true if a mobile originating emergency call is active - */ - public boolean isInEmergencyCall() { - return false; - } - - /** - * @return true if we are in the emergency call back mode. This is a period where - * the phone should be using as little power as possible and be ready to receive an - * incoming call from the emergency operator. - */ - public boolean isInEcm() { - return false; - } - - public abstract String getPhoneName(); - - public abstract int getPhoneType(); - - /** @hide */ - public int getVoiceMessageCount(){ - return 0; - } - - /** - * Returns the CDMA ERI icon index to display - */ - public int getCdmaEriIconIndex() { - logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); - return -1; - } - - /** - * Returns the CDMA ERI icon mode, - * 0 - ON - * 1 - FLASHING - */ - public int getCdmaEriIconMode() { - logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); - return -1; - } - - /** - * Returns the CDMA ERI text, - */ - public String getCdmaEriText() { - logUnexpectedCdmaMethodCall("getCdmaEriText"); - return "GSM nw, no ERI"; - } - - public String getCdmaMin() { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("getCdmaMin"); - return null; - } - - public boolean isMinInfoReady() { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("isMinInfoReady"); - return false; - } - - public String getCdmaPrlVersion(){ - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); - return null; - } - - public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("sendBurstDtmf"); - } - - public void exitEmergencyCallbackMode() { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); - } - - public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); - } - - public void unregisterForCdmaOtaStatusChange(Handler h) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); - } - - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); - } - - public void unregisterForSubscriptionInfoReady(Handler h) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); - } - - /** - * Returns true if OTA Service Provisioning needs to be performed. - * If not overridden return false. - */ - public boolean needsOtaServiceProvisioning() { - return false; - } - - /** - * Return true if number is an OTASP number. - * If not overridden return false. - */ - public boolean isOtaSpNumber(String dialStr) { - return false; - } - - public void registerForCallWaiting(Handler h, int what, Object obj){ - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("registerForCallWaiting"); - } - - public void unregisterForCallWaiting(Handler h){ - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); - } - - public void registerForEcmTimerReset(Handler h, int what, Object obj) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); - } - - public void unregisterForEcmTimerReset(Handler h) { - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); - } - - public void registerForSignalInfo(Handler h, int what, Object obj) { - mCM.registerForSignalInfo(h, what, obj); - } - - public void unregisterForSignalInfo(Handler h) { - mCM.unregisterForSignalInfo(h); - } - - public void registerForDisplayInfo(Handler h, int what, Object obj) { - mCM.registerForDisplayInfo(h, what, obj); - } - - public void unregisterForDisplayInfo(Handler h) { - mCM.unregisterForDisplayInfo(h); - } - - public void registerForNumberInfo(Handler h, int what, Object obj) { - mCM.registerForNumberInfo(h, what, obj); - } - - public void unregisterForNumberInfo(Handler h) { - mCM.unregisterForNumberInfo(h); - } - - public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { - mCM.registerForRedirectedNumberInfo(h, what, obj); - } - - public void unregisterForRedirectedNumberInfo(Handler h) { - mCM.unregisterForRedirectedNumberInfo(h); - } - - public void registerForLineControlInfo(Handler h, int what, Object obj) { - mCM.registerForLineControlInfo( h, what, obj); - } - - public void unregisterForLineControlInfo(Handler h) { - mCM.unregisterForLineControlInfo(h); - } - - public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { - mCM.registerFoT53ClirlInfo(h, what, obj); - } - - public void unregisterForT53ClirInfo(Handler h) { - mCM.unregisterForT53ClirInfo(h); - } - - public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { - mCM.registerForT53AudioControlInfo( h, what, obj); - } - - public void unregisterForT53AudioControlInfo(Handler h) { - mCM.unregisterForT53AudioControlInfo(h); - } - - public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); - } - - public void unsetOnEcbModeExitResponse(Handler h){ - // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. - logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); - } - - public String[] getActiveApnTypes() { - return mDataConnectionTracker.getActiveApnTypes(); - } - - public String getActiveApnHost(String apnType) { - return mDataConnectionTracker.getActiveApnString(apnType); - } - - public LinkProperties getLinkProperties(String apnType) { - return mDataConnectionTracker.getLinkProperties(apnType); - } - - public LinkCapabilities getLinkCapabilities(String apnType) { - return mDataConnectionTracker.getLinkCapabilities(apnType); - } - - public int enableApnType(String type) { - return mDataConnectionTracker.enableApnType(type); - } - - public int disableApnType(String type) { - return mDataConnectionTracker.disableApnType(type); - } - - public boolean isDataConnectivityPossible() { - return isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT); - } - - public boolean isDataConnectivityPossible(String apnType) { - return ((mDataConnectionTracker != null) && - (mDataConnectionTracker.isDataPossible(apnType))); - } - - /** - * Notify registrants of a new ringing Connection. - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyNewRingingConnectionP(Connection cn) { - if (!mIsVoiceCapable) - return; - AsyncResult ar = new AsyncResult(null, cn, null); - mNewRingingConnectionRegistrants.notifyRegistrants(ar); - } - - /** - * Notify registrants of a RING event. - */ - private void notifyIncomingRing() { - if (!mIsVoiceCapable) - return; - AsyncResult ar = new AsyncResult(null, this, null); - mIncomingRingRegistrants.notifyRegistrants(ar); - } - - /** - * Send the incoming call Ring notification if conditions are right. - */ - private void sendIncomingCallRingNotification(int token) { - if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && - (token == mCallRingContinueToken)) { - Log.d(LOG_TAG, "Sending notifyIncomingRing"); - notifyIncomingRing(); - sendMessageDelayed( - obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); - } else { - Log.d(LOG_TAG, "Ignoring ring notification request," - + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing - + " token=" + token - + " mCallRingContinueToken=" + mCallRingContinueToken - + " mIsVoiceCapable=" + mIsVoiceCapable); - } - } - - public boolean isCspPlmnEnabled() { - // This function should be overridden by the class GSMPhone. - // Not implemented in CDMAPhone. - logUnexpectedGsmMethodCall("isCspPlmnEnabled"); - return false; - } - - public IsimRecords getIsimRecords() { - Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); - return null; - } - - public void requestIsimAuthentication(String nonce, Message result) { - Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices"); - } - - public String getMsisdn() { - logUnexpectedGsmMethodCall("getMsisdn"); - return null; - } - - /** - * Common error logger method for unexpected calls to CDMA-only methods. - */ - private static void logUnexpectedCdmaMethodCall(String name) - { - Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + - "called, CDMAPhone inactive."); - } - - public DataState getDataConnectionState() { - return getDataConnectionState(APN_TYPE_DEFAULT); - } - - /** - * Common error logger method for unexpected calls to GSM/WCDMA-only methods. - */ - private static void logUnexpectedGsmMethodCall(String name) { - Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + - "called, GSMPhone inactive."); - } - - // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. - public void notifyCallForwardingIndicator() { - // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. - Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); - } - - public void notifyDataConnectionFailed(String reason, String apnType) { - mNotifier.notifyDataConnectionFailed(this, reason, apnType); - } - - /** - * {@inheritDoc} - */ - @Override - public int getLteOnCdmaMode() { - return mCM.getLteOnCdmaMode(); - } - - /** - * 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 - * messages are waiting - */ - @Override - public void setVoiceMessageWaiting(int line, int countWaiting) { - mIccRecords.setVoiceMessageWaiting(line, countWaiting); - } - - /** - * Gets the USIM service table from the UICC, if present and available. - * @return an interface to the UsimServiceTable record, or null if not available - */ - @Override - public UsimServiceTable getUsimServiceTable() { - return mIccRecords.getUsimServiceTable(); - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("PhoneBase:"); - pw.println(" mCM=" + mCM); - pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); - pw.println(" mDataConnectionTracker=" + mDataConnectionTracker); - pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); - pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); - pw.println(" mCallRingDelay=" + mCallRingDelay); - pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); - pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); - pw.println(" mIccRecords=" + mIccRecords); - pw.println(" mIccCard=" + mIccCard.get()); - pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); - pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); - pw.println(" mSMS=" + mSMS); - pw.flush(); - pw.println(" mLooper=" + mLooper); - pw.println(" mContext=" + mContext); - pw.println(" mNotifier=" + mNotifier); - pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); - pw.println(" mUnitTestMode=" + mUnitTestMode); - pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); - pw.println(" getUnitTestMode()=" + getUnitTestMode()); - pw.println(" getState()=" + getState()); - pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); - pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); - pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); - pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); - pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); - pw.flush(); - pw.println(" isInEcm()=" + isInEcm()); - pw.println(" getPhoneName()=" + getPhoneName()); - pw.println(" getPhoneType()=" + getPhoneType()); - pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); - pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); - pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); - pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); - } -} diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java new file mode 100644 index 000000000000..16ea625cce94 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012 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; + +/** + * @hide + */ +public class PhoneConstants { + + /** + * The phone state. One of the following:

+ *

    + *
  • IDLE = no phone activity
  • + *
  • RINGING = a phone call is ringing or call waiting. + * In the latter case, another call is active as well
  • + *
  • OFFHOOK = The phone is off hook. At least one call + * exists that is dialing, active or holding and no calls are + * ringing or waiting.
  • + *
+ */ + public enum State { + IDLE, RINGING, OFFHOOK; + }; + + /** + * The state of a data connection. + *
    + *
  • CONNECTED = IP traffic should be available
  • + *
  • CONNECTING = Currently setting up data connection
  • + *
  • DISCONNECTED = IP not available
  • + *
  • SUSPENDED = connection is created but IP traffic is + * temperately not available. i.e. voice call is in place + * in 2G network
  • + *
+ */ + public enum DataState { + CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED; + }; + + public static final String STATE_KEY = "state"; + + // Radio Type + public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE; + public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE; + public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE; + public static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE; + + // Modes for LTE_ON_CDMA + public static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN; + public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE; + public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE; + + // Number presentation type for caller id display (From internal/Conneciton.java) + public static int PRESENTATION_ALLOWED = 1; // normal + public static int PRESENTATION_RESTRICTED = 2; // block by user + public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network + public static int PRESENTATION_PAYPHONE = 4; // show pay phone info + + + public static final String PHONE_NAME_KEY = "phoneName"; + public static final String FAILURE_REASON_KEY = "reason"; + public static final String STATE_CHANGE_REASON_KEY = "reason"; + public static final String DATA_APN_TYPE_KEY = "apnType"; + public static final String DATA_APN_KEY = "apn"; + public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties"; + public static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities"; + + public static final String DATA_IFACE_NAME_KEY = "iface"; + public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable"; + public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming"; + public static final String PHONE_IN_ECM_STATE = "phoneinECMState"; + + public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged"; + + /** + * Return codes for enableApnType() + */ + public static final int APN_ALREADY_ACTIVE = 0; + public static final int APN_REQUEST_STARTED = 1; + public static final int APN_TYPE_NOT_AVAILABLE = 2; + public static final int APN_REQUEST_FAILED = 3; + public static final int APN_ALREADY_INACTIVE = 4; + + /** + * APN types for data connections. These are usage categories for an APN + * entry. One APN entry may support multiple APN types, eg, a single APN + * may service regular internet traffic ("default") as well as MMS-specific + * connections.
+ * APN_TYPE_ALL is a special type to indicate that this APN entry can + * service all data connections. + */ + public static final String APN_TYPE_ALL = "*"; + /** APN type for default data traffic */ + public static final String APN_TYPE_DEFAULT = "default"; + /** APN type for MMS traffic */ + public static final String APN_TYPE_MMS = "mms"; + /** APN type for SUPL assisted GPS */ + public static final String APN_TYPE_SUPL = "supl"; + /** APN type for DUN traffic */ + public static final String APN_TYPE_DUN = "dun"; + /** APN type for HiPri traffic */ + public static final String APN_TYPE_HIPRI = "hipri"; + /** APN type for FOTA */ + public static final String APN_TYPE_FOTA = "fota"; + /** APN type for IMS */ + public static final String APN_TYPE_IMS = "ims"; + /** APN type for CBS */ + public static final String APN_TYPE_CBS = "cbs"; + +} diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java deleted file mode 100644 index f495d7e5e87c..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ /dev/null @@ -1,249 +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; - -import android.content.Context; -import android.net.LocalServerSocket; -import android.os.Looper; -import android.provider.Settings; -import android.util.Log; -import android.os.SystemProperties; - -import com.android.internal.telephony.cdma.CDMAPhone; -import com.android.internal.telephony.cdma.CDMALTEPhone; -import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.sip.SipPhone; -import com.android.internal.telephony.sip.SipPhoneFactory; - -/** - * {@hide} - */ -public class PhoneFactory { - static final String LOG_TAG = "PHONE"; - static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000; - static final int SOCKET_OPEN_MAX_RETRY = 3; - - //***** Class Variables - - 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; - - static final int preferredCdmaSubscription = - CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION; - - //***** Class Methods - - public static void makeDefaultPhones(Context context) { - makeDefaultPhone(context); - } - - /** - * FIXME replace this with some other way of making these - * instances - */ - public static void makeDefaultPhone(Context context) { - synchronized(Phone.class) { - if (!sMadeDefaults) { - sLooper = Looper.myLooper(); - sContext = context; - - if (sLooper == null) { - throw new RuntimeException( - "PhoneFactory.makeDefaultPhone must be called from Looper thread"); - } - - int retryCount = 0; - for(;;) { - boolean hasException = false; - retryCount ++; - - try { - // use UNIX domain socket to - // prevent subsequent initialization - new LocalServerSocket("com.android.internal.telephony"); - } catch (java.io.IOException ex) { - hasException = true; - } - - if ( !hasException ) { - break; - } else if (retryCount > SOCKET_OPEN_MAX_RETRY) { - throw new RuntimeException("PhoneFactory probably already running"); - } else { - try { - Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); - } catch (InterruptedException er) { - } - } - } - - sPhoneNotifier = new DefaultPhoneNotifier(); - - // Get preferred network mode - int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE; - if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) { - preferredNetworkMode = Phone.NT_MODE_GLOBAL; - } - int networkMode = Settings.Secure.getInt(context.getContentResolver(), - Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode); - Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode)); - - // Get cdmaSubscription - // TODO: Change when the ril will provides a way to know at runtime - // the configuration, bug 4202572. And the ril issues the - // RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439. - int cdmaSubscription; - int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic(); - switch (lteOnCdma) { - case Phone.LTE_ON_CDMA_FALSE: - cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV; - Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV"); - break; - case Phone.LTE_ON_CDMA_TRUE: - cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM; - Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM"); - break; - case Phone.LTE_ON_CDMA_UNKNOWN: - default: - //Get cdmaSubscription mode from Settings.System - cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(), - Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION, - preferredCdmaSubscription); - Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION"); - break; - } - Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription); - - //reads the system properties and makes commandsinterface - sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); - - int phoneType = getPhoneType(networkMode); - if (phoneType == Phone.PHONE_TYPE_GSM) { - Log.i(LOG_TAG, "Creating GSMPhone"); - sProxyPhone = new PhoneProxy(new GSMPhone(context, - sCommandsInterface, sPhoneNotifier)); - } else if (phoneType == Phone.PHONE_TYPE_CDMA) { - switch (BaseCommands.getLteOnCdmaModeStatic()) { - case Phone.LTE_ON_CDMA_TRUE: - Log.i(LOG_TAG, "Creating CDMALTEPhone"); - sProxyPhone = new PhoneProxy(new CDMALTEPhone(context, - sCommandsInterface, sPhoneNotifier)); - break; - case Phone.LTE_ON_CDMA_FALSE: - default: - Log.i(LOG_TAG, "Creating CDMAPhone"); - sProxyPhone = new PhoneProxy(new CDMAPhone(context, - sCommandsInterface, sPhoneNotifier)); - break; - } - } - - sMadeDefaults = true; - } - } - } - - /* - * This function returns the type of the phone, depending - * on the network mode. - * - * @param network mode - * @return Phone Type - */ - public static int getPhoneType(int networkMode) { - switch(networkMode) { - case RILConstants.NETWORK_MODE_CDMA: - case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: - case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: - return Phone.PHONE_TYPE_CDMA; - - case RILConstants.NETWORK_MODE_WCDMA_PREF: - case RILConstants.NETWORK_MODE_GSM_ONLY: - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - case RILConstants.NETWORK_MODE_GSM_UMTS: - return Phone.PHONE_TYPE_GSM; - - // Use CDMA Phone for the global mode including CDMA - case RILConstants.NETWORK_MODE_GLOBAL: - case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: - case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA: - return Phone.PHONE_TYPE_CDMA; - - case RILConstants.NETWORK_MODE_LTE_ONLY: - if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) { - return Phone.PHONE_TYPE_CDMA; - } else { - return Phone.PHONE_TYPE_GSM; - } - default: - return Phone.PHONE_TYPE_GSM; - } - } - - public static Phone getDefaultPhone() { - if (sLooper != Looper.myLooper()) { - throw new RuntimeException( - "PhoneFactory.getDefaultPhone must be called from Looper thread"); - } - - if (!sMadeDefaults) { - throw new IllegalStateException("Default phones haven't been made yet!"); - } - return sProxyPhone; - } - - public static Phone getCdmaPhone() { - Phone phone; - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - switch (BaseCommands.getLteOnCdmaModeStatic()) { - case Phone.LTE_ON_CDMA_TRUE: { - phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier); - break; - } - case Phone.LTE_ON_CDMA_FALSE: - case Phone.LTE_ON_CDMA_UNKNOWN: - default: { - phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier); - break; - } - } - } - return phone; - } - - public static Phone getGsmPhone() { - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier); - return phone; - } - } - - /** - * Makes a {@link SipPhone} object. - * @param sipUri the local SIP URI the phone runs on - * @return the {@code SipPhone} object or null if the SIP URI is not valid - */ - public static SipPhone makeSipPhone(String sipUri) { - return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier); - } -} diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java deleted file mode 100644 index 10768700f49a..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java +++ /dev/null @@ -1,50 +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; - -import android.telephony.CellInfo; - -/** - * {@hide} - */ -public interface PhoneNotifier { - - public void notifyPhoneState(Phone sender); - - public void notifyServiceState(Phone sender); - - public void notifyCellLocation(Phone sender); - - public void notifySignalStrength(Phone sender); - - public void notifyMessageWaitingChanged(Phone sender); - - public void notifyCallForwardingChanged(Phone sender); - - /** TODO - reason should never be null */ - public void notifyDataConnection(Phone sender, String reason, String apnType, - Phone.DataState state); - - public void notifyDataConnectionFailed(Phone sender, String reason, String apnType); - - public void notifyDataActivity(Phone sender); - - public void notifyOtaspChanged(Phone sender, int otaspMode); - - // TODO - trigger notifyCellInfo from ServiceStateTracker - public void notifyCellInfo(Phone sender, CellInfo cellInfo); -} diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java deleted file mode 100644 index 1a8b3ca01ca2..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - - -import android.app.ActivityManagerNative; -import android.content.Context; -import android.content.Intent; -import android.net.LinkCapabilities; -import android.net.LinkProperties; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.telephony.CellLocation; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.util.Log; - -import com.android.internal.telephony.cdma.CDMAPhone; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.gsm.UsimServiceTable; -import com.android.internal.telephony.ims.IsimRecords; -import com.android.internal.telephony.test.SimulatedRadioControl; -import com.android.internal.telephony.CallManager; - -import java.util.List; - -public class PhoneProxy extends Handler implements Phone { - public final static Object lockForRadioTechnologyChange = new Object(); - - private Phone mActivePhone; - private CommandsInterface mCommandsInterface; - private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy; - private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy; - private PhoneSubInfoProxy mPhoneSubInfoProxy; - - private boolean mResetModemOnRadioTechnologyChange = false; - - private int mRilVersion; - - private static final int EVENT_VOICE_RADIO_TECH_CHANGED = 1; - private static final int EVENT_RADIO_ON = 2; - private static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE = 3; - private static final int EVENT_RIL_CONNECTED = 4; - - private static final String LOG_TAG = "PHONE"; - - //***** Class Methods - public PhoneProxy(Phone phone) { - mActivePhone = phone; - mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false); - mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy( - phone.getIccSmsInterfaceManager()); - mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy( - phone.getIccPhoneBookInterfaceManager()); - mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo()); - mCommandsInterface = ((PhoneBase)mActivePhone).mCM; - - mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); - mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null); - mCommandsInterface.registerForVoiceRadioTechChanged( - this, EVENT_VOICE_RADIO_TECH_CHANGED, null); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar = (AsyncResult) msg.obj; - switch(msg.what) { - case EVENT_RADIO_ON: - /* Proactively query voice radio technologies */ - mCommandsInterface.getVoiceRadioTechnology( - this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE)); - break; - - case EVENT_RIL_CONNECTED: - if (ar.exception == null && ar.result != null) { - mRilVersion = (Integer) ar.result; - } else { - logd("Unexpected exception on EVENT_RIL_CONNECTED"); - mRilVersion = -1; - } - break; - - case EVENT_VOICE_RADIO_TECH_CHANGED: - case EVENT_REQUEST_VOICE_RADIO_TECH_DONE: - - if (ar.exception == null) { - if ((ar.result != null) && (((int[]) ar.result).length != 0)) { - int newVoiceTech = ((int[]) ar.result)[0]; - updatePhoneObject(newVoiceTech); - } else { - loge("Voice Radio Technology event " + msg.what + " has no tech!"); - } - } else { - loge("Voice Radio Technology event " + msg.what + " exception!" + ar.exception); - } - break; - - default: - loge("Error! This handler was not registered for this message type. Message: " - + msg.what); - break; - } - super.handleMessage(msg); - } - - private static 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); - } - - private void updatePhoneObject(int newVoiceRadioTech) { - - if (mActivePhone != null) { - if(mRilVersion == 6 && getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) { - /* - * On v6 RIL, when LTE_ON_CDMA is TRUE, always create CDMALTEPhone - * irrespective of the voice radio tech reported. - */ - if (mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) { - logd("LTE ON CDMA property is set. Use CDMA Phone" + - " newVoiceRadioTech = " + newVoiceRadioTech + - " Active Phone = " + mActivePhone.getPhoneName()); - return; - } else { - logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" + - " newVoiceRadioTech = " + newVoiceRadioTech + - " Active Phone = " + mActivePhone.getPhoneName()); - newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT; - } - } else { - if ((ServiceState.isCdma(newVoiceRadioTech) && - mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) || - (ServiceState.isGsm(newVoiceRadioTech) && - mActivePhone.getPhoneType() == PHONE_TYPE_GSM)) { - // Nothing changed. Keep phone as it is. - logd("Ignoring voice radio technology changed message." + - " newVoiceRadioTech = " + newVoiceRadioTech + - " Active Phone = " + mActivePhone.getPhoneName()); - return; - } - } - } - - if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) { - // We need some voice phone object to be active always, so never - // delete the phone without anything to replace it with! - logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown." - + " Active Phone = " + mActivePhone.getPhoneName()); - return; - } - - boolean oldPowerState = false; // old power state to off - if (mResetModemOnRadioTechnologyChange) { - if (mCommandsInterface.getRadioState().isOn()) { - oldPowerState = true; - logd("Setting Radio Power to Off"); - mCommandsInterface.setRadioPower(false, null); - } - } - - deleteAndCreatePhone(newVoiceRadioTech); - - if (mResetModemOnRadioTechnologyChange && oldPowerState) { // restore power state - logd("Resetting Radio"); - mCommandsInterface.setRadioPower(oldPowerState, 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.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName()); - ActivityManagerNative.broadcastStickyIntent(intent, null); - - } - - private void deleteAndCreatePhone(int newVoiceRadioTech) { - - String outgoingPhoneName = "Unknown"; - Phone oldPhone = mActivePhone; - - if (oldPhone != null) { - outgoingPhoneName = ((PhoneBase) oldPhone).getPhoneName(); - } - - logd("Switching Voice Phone : " + outgoingPhoneName + " >>> " - + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA")); - - if (oldPhone != null) { - CallManager.getInstance().unregisterPhone(oldPhone); - logd("Disposing old phone.."); - oldPhone.dispose(); - } - - // 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(); - - if (ServiceState.isCdma(newVoiceRadioTech)) { - mActivePhone = PhoneFactory.getCdmaPhone(); - } else if (ServiceState.isGsm(newVoiceRadioTech)) { - mActivePhone = PhoneFactory.getGsmPhone(); - } - - if (oldPhone != null) { - oldPhone.removeReferences(); - } - - if(mActivePhone != null) { - CallManager.getInstance().registerPhone(mActivePhone); - } - - oldPhone = null; - } - - public ServiceState getServiceState() { - return mActivePhone.getServiceState(); - } - - public CellLocation getCellLocation() { - return mActivePhone.getCellLocation(); - } - - public DataState getDataConnectionState() { - return mActivePhone.getDataConnectionState(Phone.APN_TYPE_DEFAULT); - } - - public DataState getDataConnectionState(String apnType) { - return mActivePhone.getDataConnectionState(apnType); - } - - public DataActivityState getDataActivityState() { - return mActivePhone.getDataActivityState(); - } - - public Context getContext() { - return mActivePhone.getContext(); - } - - public void disableDnsCheck(boolean b) { - mActivePhone.disableDnsCheck(b); - } - - public boolean isDnsCheckDisabled() { - return mActivePhone.isDnsCheckDisabled(); - } - - public State getState() { - return mActivePhone.getState(); - } - - public String getPhoneName() { - return mActivePhone.getPhoneName(); - } - - public int getPhoneType() { - return mActivePhone.getPhoneType(); - } - - public String[] getActiveApnTypes() { - return mActivePhone.getActiveApnTypes(); - } - - public String getActiveApnHost(String apnType) { - return mActivePhone.getActiveApnHost(apnType); - } - - public LinkProperties getLinkProperties(String apnType) { - return mActivePhone.getLinkProperties(apnType); - } - - public LinkCapabilities getLinkCapabilities(String apnType) { - return mActivePhone.getLinkCapabilities(apnType); - } - - public SignalStrength getSignalStrength() { - return mActivePhone.getSignalStrength(); - } - - public void registerForUnknownConnection(Handler h, int what, Object obj) { - mActivePhone.registerForUnknownConnection(h, what, obj); - } - - public void unregisterForUnknownConnection(Handler h) { - mActivePhone.unregisterForUnknownConnection(h); - } - - public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { - mActivePhone.registerForPreciseCallStateChanged(h, what, obj); - } - - public void unregisterForPreciseCallStateChanged(Handler h) { - mActivePhone.unregisterForPreciseCallStateChanged(h); - } - - public void registerForNewRingingConnection(Handler h, int what, Object obj) { - mActivePhone.registerForNewRingingConnection(h, what, obj); - } - - public void unregisterForNewRingingConnection(Handler h) { - mActivePhone.unregisterForNewRingingConnection(h); - } - - public void registerForIncomingRing(Handler h, int what, Object obj) { - mActivePhone.registerForIncomingRing(h, what, obj); - } - - public void unregisterForIncomingRing(Handler h) { - mActivePhone.unregisterForIncomingRing(h); - } - - public void registerForDisconnect(Handler h, int what, Object obj) { - mActivePhone.registerForDisconnect(h, what, obj); - } - - public void unregisterForDisconnect(Handler h) { - mActivePhone.unregisterForDisconnect(h); - } - - public void registerForMmiInitiate(Handler h, int what, Object obj) { - mActivePhone.registerForMmiInitiate(h, what, obj); - } - - public void unregisterForMmiInitiate(Handler h) { - mActivePhone.unregisterForMmiInitiate(h); - } - - public void registerForMmiComplete(Handler h, int what, Object obj) { - mActivePhone.registerForMmiComplete(h, what, obj); - } - - public void unregisterForMmiComplete(Handler h) { - mActivePhone.unregisterForMmiComplete(h); - } - - public List getPendingMmiCodes() { - return mActivePhone.getPendingMmiCodes(); - } - - public void sendUssdResponse(String ussdMessge) { - mActivePhone.sendUssdResponse(ussdMessge); - } - - public void registerForServiceStateChanged(Handler h, int what, Object obj) { - mActivePhone.registerForServiceStateChanged(h, what, obj); - } - - public void unregisterForServiceStateChanged(Handler h) { - mActivePhone.unregisterForServiceStateChanged(h); - } - - public void registerForSuppServiceNotification(Handler h, int what, Object obj) { - mActivePhone.registerForSuppServiceNotification(h, what, obj); - } - - public void unregisterForSuppServiceNotification(Handler h) { - mActivePhone.unregisterForSuppServiceNotification(h); - } - - public void registerForSuppServiceFailed(Handler h, int what, Object obj) { - mActivePhone.registerForSuppServiceFailed(h, what, obj); - } - - public void unregisterForSuppServiceFailed(Handler h) { - mActivePhone.unregisterForSuppServiceFailed(h); - } - - 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 void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { - mActivePhone.registerForCdmaOtaStatusChange(h,what,obj); - } - - public void unregisterForCdmaOtaStatusChange(Handler h) { - mActivePhone.unregisterForCdmaOtaStatusChange(h); - } - - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { - mActivePhone.registerForSubscriptionInfoReady(h, what, obj); - } - - public void unregisterForSubscriptionInfoReady(Handler h) { - mActivePhone.unregisterForSubscriptionInfoReady(h); - } - - public void registerForEcmTimerReset(Handler h, int what, Object obj) { - mActivePhone.registerForEcmTimerReset(h,what,obj); - } - - public void unregisterForEcmTimerReset(Handler h) { - mActivePhone.unregisterForEcmTimerReset(h); - } - - public void registerForRingbackTone(Handler h, int what, Object obj) { - mActivePhone.registerForRingbackTone(h,what,obj); - } - - public void unregisterForRingbackTone(Handler h) { - mActivePhone.unregisterForRingbackTone(h); - } - - public void registerForResendIncallMute(Handler h, int what, Object obj) { - mActivePhone.registerForResendIncallMute(h,what,obj); - } - - public void unregisterForResendIncallMute(Handler h) { - mActivePhone.unregisterForResendIncallMute(h); - } - - public boolean getIccRecordsLoaded() { - return mActivePhone.getIccRecordsLoaded(); - } - - public IccCard getIccCard() { - return mActivePhone.getIccCard(); - } - - public void acceptCall() throws CallStateException { - mActivePhone.acceptCall(); - } - - public void rejectCall() throws CallStateException { - mActivePhone.rejectCall(); - } - - public void switchHoldingAndActive() throws CallStateException { - mActivePhone.switchHoldingAndActive(); - } - - public boolean canConference() { - return mActivePhone.canConference(); - } - - public void conference() throws CallStateException { - mActivePhone.conference(); - } - - public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { - mActivePhone.enableEnhancedVoicePrivacy(enable, onComplete); - } - - public void getEnhancedVoicePrivacy(Message onComplete) { - mActivePhone.getEnhancedVoicePrivacy(onComplete); - } - - public boolean canTransfer() { - return mActivePhone.canTransfer(); - } - - public void explicitCallTransfer() throws CallStateException { - mActivePhone.explicitCallTransfer(); - } - - public void clearDisconnected() { - mActivePhone.clearDisconnected(); - } - - public Call getForegroundCall() { - return mActivePhone.getForegroundCall(); - } - - public Call getBackgroundCall() { - return mActivePhone.getBackgroundCall(); - } - - public Call getRingingCall() { - return mActivePhone.getRingingCall(); - } - - public Connection dial(String dialString) throws CallStateException { - return mActivePhone.dial(dialString); - } - - public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { - return mActivePhone.dial(dialString, uusInfo); - } - - public boolean handlePinMmi(String dialString) { - return mActivePhone.handlePinMmi(dialString); - } - - public boolean handleInCallMmiCommands(String command) throws CallStateException { - return mActivePhone.handleInCallMmiCommands(command); - } - - public void sendDtmf(char c) { - mActivePhone.sendDtmf(c); - } - - public void startDtmf(char c) { - mActivePhone.startDtmf(c); - } - - public void stopDtmf() { - mActivePhone.stopDtmf(); - } - - public void setRadioPower(boolean power) { - mActivePhone.setRadioPower(power); - } - - public boolean getMessageWaitingIndicator() { - return mActivePhone.getMessageWaitingIndicator(); - } - - public boolean getCallForwardingIndicator() { - return mActivePhone.getCallForwardingIndicator(); - } - - public String getLine1Number() { - return mActivePhone.getLine1Number(); - } - - public String getCdmaMin() { - return mActivePhone.getCdmaMin(); - } - - public boolean isMinInfoReady() { - return mActivePhone.isMinInfoReady(); - } - - public String getCdmaPrlVersion() { - return mActivePhone.getCdmaPrlVersion(); - } - - public String getLine1AlphaTag() { - return mActivePhone.getLine1AlphaTag(); - } - - public void setLine1Number(String alphaTag, String number, Message onComplete) { - mActivePhone.setLine1Number(alphaTag, number, onComplete); - } - - public String getVoiceMailNumber() { - return mActivePhone.getVoiceMailNumber(); - } - - /** @hide */ - public int getVoiceMessageCount(){ - return mActivePhone.getVoiceMessageCount(); - } - - public String getVoiceMailAlphaTag() { - return mActivePhone.getVoiceMailAlphaTag(); - } - - public void setVoiceMailNumber(String alphaTag,String voiceMailNumber, - Message onComplete) { - mActivePhone.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete); - } - - public void getCallForwardingOption(int commandInterfaceCFReason, - Message onComplete) { - mActivePhone.getCallForwardingOption(commandInterfaceCFReason, - onComplete); - } - - public void setCallForwardingOption(int commandInterfaceCFReason, - int commandInterfaceCFAction, String dialingNumber, - int timerSeconds, Message onComplete) { - mActivePhone.setCallForwardingOption(commandInterfaceCFReason, - commandInterfaceCFAction, dialingNumber, timerSeconds, onComplete); - } - - public void getOutgoingCallerIdDisplay(Message onComplete) { - mActivePhone.getOutgoingCallerIdDisplay(onComplete); - } - - public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, - Message onComplete) { - mActivePhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, - onComplete); - } - - public void getCallWaiting(Message onComplete) { - mActivePhone.getCallWaiting(onComplete); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - mActivePhone.setCallWaiting(enable, onComplete); - } - - public void getAvailableNetworks(Message response) { - mActivePhone.getAvailableNetworks(response); - } - - public void setNetworkSelectionModeAutomatic(Message response) { - mActivePhone.setNetworkSelectionModeAutomatic(response); - } - - public void selectNetworkManually(OperatorInfo network, Message response) { - mActivePhone.selectNetworkManually(network, response); - } - - public void setPreferredNetworkType(int networkType, Message response) { - mActivePhone.setPreferredNetworkType(networkType, response); - } - - public void getPreferredNetworkType(Message response) { - mActivePhone.getPreferredNetworkType(response); - } - - public void getNeighboringCids(Message response) { - mActivePhone.getNeighboringCids(response); - } - - public void setOnPostDialCharacter(Handler h, int what, Object obj) { - mActivePhone.setOnPostDialCharacter(h, what, obj); - } - - public void setMute(boolean muted) { - mActivePhone.setMute(muted); - } - - public boolean getMute() { - return mActivePhone.getMute(); - } - - public void setEchoSuppressionEnabled(boolean enabled) { - mActivePhone.setEchoSuppressionEnabled(enabled); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) { - mActivePhone.invokeOemRilRequestRaw(data, response); - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) { - mActivePhone.invokeOemRilRequestStrings(strings, response); - } - - public void getDataCallList(Message response) { - mActivePhone.getDataCallList(response); - } - - public void updateServiceLocation() { - mActivePhone.updateServiceLocation(); - } - - public void enableLocationUpdates() { - mActivePhone.enableLocationUpdates(); - } - - public void disableLocationUpdates() { - mActivePhone.disableLocationUpdates(); - } - - public void setUnitTestMode(boolean f) { - mActivePhone.setUnitTestMode(f); - } - - public boolean getUnitTestMode() { - return mActivePhone.getUnitTestMode(); - } - - public void setBandMode(int bandMode, Message response) { - mActivePhone.setBandMode(bandMode, response); - } - - public void queryAvailableBandMode(Message response) { - mActivePhone.queryAvailableBandMode(response); - } - - public boolean getDataRoamingEnabled() { - return mActivePhone.getDataRoamingEnabled(); - } - - public void setDataRoamingEnabled(boolean enable) { - mActivePhone.setDataRoamingEnabled(enable); - } - - 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); - } - - public SimulatedRadioControl getSimulatedRadioControl() { - return mActivePhone.getSimulatedRadioControl(); - } - - public int enableApnType(String type) { - return mActivePhone.enableApnType(type); - } - - public int disableApnType(String type) { - return mActivePhone.disableApnType(type); - } - - public boolean isDataConnectivityPossible() { - return mActivePhone.isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT); - } - - public boolean isDataConnectivityPossible(String apnType) { - return mActivePhone.isDataConnectivityPossible(apnType); - } - - public String getDeviceId() { - return mActivePhone.getDeviceId(); - } - - public String getDeviceSvn() { - return mActivePhone.getDeviceSvn(); - } - - public String getSubscriberId() { - return mActivePhone.getSubscriberId(); - } - - public String getIccSerialNumber() { - return mActivePhone.getIccSerialNumber(); - } - - public String getEsn() { - return mActivePhone.getEsn(); - } - - public String getMeid() { - return mActivePhone.getMeid(); - } - - public String getMsisdn() { - return mActivePhone.getMsisdn(); - } - - public String getImei() { - return mActivePhone.getImei(); - } - - public PhoneSubInfo getPhoneSubInfo(){ - return mActivePhone.getPhoneSubInfo(); - } - - public IccSmsInterfaceManager getIccSmsInterfaceManager(){ - return mActivePhone.getIccSmsInterfaceManager(); - } - - public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ - return mActivePhone.getIccPhoneBookInterfaceManager(); - } - - public void setTTYMode(int ttyMode, Message onComplete) { - mActivePhone.setTTYMode(ttyMode, onComplete); - } - - public void queryTTYMode(Message onComplete) { - mActivePhone.queryTTYMode(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(); - } - - public void getSmscAddress(Message result) { - mActivePhone.getSmscAddress(result); - } - - public void setSmscAddress(String address, Message result) { - mActivePhone.setSmscAddress(address, result); - } - - public int getCdmaEriIconIndex() { - return mActivePhone.getCdmaEriIconIndex(); - } - - public String getCdmaEriText() { - return mActivePhone.getCdmaEriText(); - } - - public int getCdmaEriIconMode() { - return mActivePhone.getCdmaEriIconMode(); - } - - public Phone getActivePhone() { - return mActivePhone; - } - - public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){ - mActivePhone.sendBurstDtmf(dtmfString, on, off, onComplete); - } - - public void exitEmergencyCallbackMode(){ - mActivePhone.exitEmergencyCallbackMode(); - } - - public boolean needsOtaServiceProvisioning(){ - return mActivePhone.needsOtaServiceProvisioning(); - } - - public boolean isOtaSpNumber(String dialStr){ - return mActivePhone.isOtaSpNumber(dialStr); - } - - public void registerForCallWaiting(Handler h, int what, Object obj){ - mActivePhone.registerForCallWaiting(h,what,obj); - } - - public void unregisterForCallWaiting(Handler h){ - mActivePhone.unregisterForCallWaiting(h); - } - - public void registerForSignalInfo(Handler h, int what, Object obj) { - mActivePhone.registerForSignalInfo(h,what,obj); - } - - public void unregisterForSignalInfo(Handler h) { - mActivePhone.unregisterForSignalInfo(h); - } - - public void registerForDisplayInfo(Handler h, int what, Object obj) { - mActivePhone.registerForDisplayInfo(h,what,obj); - } - - public void unregisterForDisplayInfo(Handler h) { - mActivePhone.unregisterForDisplayInfo(h); - } - - public void registerForNumberInfo(Handler h, int what, Object obj) { - mActivePhone.registerForNumberInfo(h, what, obj); - } - - public void unregisterForNumberInfo(Handler h) { - mActivePhone.unregisterForNumberInfo(h); - } - - public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { - mActivePhone.registerForRedirectedNumberInfo(h, what, obj); - } - - public void unregisterForRedirectedNumberInfo(Handler h) { - mActivePhone.unregisterForRedirectedNumberInfo(h); - } - - public void registerForLineControlInfo(Handler h, int what, Object obj) { - mActivePhone.registerForLineControlInfo( h, what, obj); - } - - public void unregisterForLineControlInfo(Handler h) { - mActivePhone.unregisterForLineControlInfo(h); - } - - public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { - mActivePhone.registerFoT53ClirlInfo(h, what, obj); - } - - public void unregisterForT53ClirInfo(Handler h) { - mActivePhone.unregisterForT53ClirInfo(h); - } - - public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { - mActivePhone.registerForT53AudioControlInfo( h, what, obj); - } - - public void unregisterForT53AudioControlInfo(Handler h) { - mActivePhone.unregisterForT53AudioControlInfo(h); - } - - public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ - mActivePhone.setOnEcbModeExitResponse(h,what,obj); - } - - public void unsetOnEcbModeExitResponse(Handler h){ - mActivePhone.unsetOnEcbModeExitResponse(h); - } - - public boolean isCspPlmnEnabled() { - return mActivePhone.isCspPlmnEnabled(); - } - - public IsimRecords getIsimRecords() { - return mActivePhone.getIsimRecords(); - } - - public void requestIsimAuthentication(String nonce, Message response) { - mActivePhone.requestIsimAuthentication(nonce, response); - } - - /** - * {@inheritDoc} - */ - @Override - public int getLteOnCdmaMode() { - return mActivePhone.getLteOnCdmaMode(); - } - - @Override - public void setVoiceMessageWaiting(int line, int countWaiting) { - mActivePhone.setVoiceMessageWaiting(line, countWaiting); - } - - @Override - public UsimServiceTable getUsimServiceTable() { - return mActivePhone.getUsimServiceTable(); - } - - public void dispose() { - mCommandsInterface.unregisterForOn(this); - mCommandsInterface.unregisterForVoiceRadioTechChanged(this); - mCommandsInterface.unregisterForRilConnected(this); - } - - public void removeReferences() { - mActivePhone = null; - mCommandsInterface = null; - } -} diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java deleted file mode 100644 index 898e624e92f6..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java +++ /dev/null @@ -1,203 +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; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.os.Message; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.TelephonyManager; -import android.util.Log; - -/** - * - * DO NOT USE THIS CLASS: - * - * Use android.telephony.TelephonyManager and PhoneStateListener instead. - * - * - */ -@Deprecated -public final class PhoneStateIntentReceiver extends BroadcastReceiver { - private static final String LOG_TAG = "PHONE"; - private static final boolean DBG = false; - - private static final int NOTIF_PHONE = 1 << 0; - private static final int NOTIF_SERVICE = 1 << 1; - private static final int NOTIF_SIGNAL = 1 << 2; - - private static final int NOTIF_MAX = 1 << 5; - - Phone.State mPhoneState = Phone.State.IDLE; - ServiceState mServiceState = new ServiceState(); - SignalStrength mSignalStrength = new SignalStrength(); - - private Context mContext; - private Handler mTarget; - private IntentFilter mFilter; - private int mWants; - private int mPhoneStateEventWhat; - private int mServiceStateEventWhat; - private int mLocationEventWhat; - private int mAsuEventWhat; - - public PhoneStateIntentReceiver() { - super(); - mFilter = new IntentFilter(); - } - - public PhoneStateIntentReceiver(Context context, Handler target) { - this(); - setContext(context); - setTarget(target); - } - - public void setContext(Context c) { - mContext = c; - } - - public void setTarget(Handler h) { - mTarget = h; - } - - public Phone.State getPhoneState() { - if ((mWants & NOTIF_PHONE) == 0) { - throw new RuntimeException - ("client must call notifyPhoneCallState(int)"); - } - return mPhoneState; - } - - public ServiceState getServiceState() { - if ((mWants & NOTIF_SERVICE) == 0) { - throw new RuntimeException - ("client must call notifyServiceState(int)"); - } - return mServiceState; - } - - /** - * Returns current signal strength in as an asu 0..31 - * - * Throws RuntimeException if client has not called notifySignalStrength() - */ - public int getSignalStrengthLevelAsu() { - // TODO: use new SignalStrength instead of asu - if ((mWants & NOTIF_SIGNAL) == 0) { - throw new RuntimeException - ("client must call notifySignalStrength(int)"); - } - return mSignalStrength.getAsuLevel(); - } - - /** - * Return current signal strength in "dBm", ranging from -113 - -51dBm - * or -1 if unknown - * - * @return signal strength in dBm, -1 if not yet updated - * Throws RuntimeException if client has not called notifySignalStrength() - */ - public int getSignalStrengthDbm() { - if ((mWants & NOTIF_SIGNAL) == 0) { - throw new RuntimeException - ("client must call notifySignalStrength(int)"); - } - return mSignalStrength.getDbm(); - } - - public void notifyPhoneCallState(int eventWhat) { - mWants |= NOTIF_PHONE; - mPhoneStateEventWhat = eventWhat; - mFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - } - - public boolean getNotifyPhoneCallState() { - return ((mWants & NOTIF_PHONE) != 0); - } - - public void notifyServiceState(int eventWhat) { - mWants |= NOTIF_SERVICE; - mServiceStateEventWhat = eventWhat; - mFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); - } - - public boolean getNotifyServiceState() { - return ((mWants & NOTIF_SERVICE) != 0); - } - - public void notifySignalStrength (int eventWhat) { - mWants |= NOTIF_SIGNAL; - mAsuEventWhat = eventWhat; - mFilter.addAction(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); - } - - public boolean getNotifySignalStrength() { - return ((mWants & NOTIF_SIGNAL) != 0); - } - - public void registerIntent() { - mContext.registerReceiver(this, mFilter); - } - - public void unregisterIntent() { - mContext.unregisterReceiver(this); - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - try { - if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) { - mSignalStrength = SignalStrength.newFromBundle(intent.getExtras()); - - if (mTarget != null && getNotifySignalStrength()) { - Message message = Message.obtain(mTarget, mAsuEventWhat); - mTarget.sendMessage(message); - } - } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { - if (DBG) Log.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state=" - + intent.getStringExtra(Phone.STATE_KEY)); - String phoneState = intent.getStringExtra(Phone.STATE_KEY); - mPhoneState = (Phone.State) Enum.valueOf( - Phone.State.class, phoneState); - - if (mTarget != null && getNotifyPhoneCallState()) { - Message message = Message.obtain(mTarget, - mPhoneStateEventWhat); - mTarget.sendMessage(message); - } - } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) { - mServiceState = ServiceState.newFromBundle(intent.getExtras()); - - if (mTarget != null && getNotifyServiceState()) { - Message message = Message.obtain(mTarget, - mServiceStateEventWhat); - mTarget.sendMessage(message); - } - } - } catch (Exception ex) { - Log.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex); - ex.printStackTrace(); - } - } - -} diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java deleted file mode 100755 index e8449cefe16c..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.telephony.PhoneNumberUtils; -import android.util.Log; - -import com.android.internal.telephony.ims.IsimRecords; - -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 = - android.Manifest.permission.READ_PHONE_STATE; - // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE - private static final String CALL_PRIVILEGED = - android.Manifest.permission.CALL_PRIVILEGED; - private static final String READ_PRIVILEGED_PHONE_STATE = - android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; - - public PhoneSubInfo(Phone phone) { - mPhone = phone; - mContext = phone.getContext(); - } - - public void dispose() { - } - - protected void finalize() { - try { - super.finalize(); - } catch (Throwable throwable) { - Log.e(LOG_TAG, "Error while finalizing:", throwable); - } - Log.d(LOG_TAG, "PhoneSubInfo finalized"); - } - - /** - * 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"); - return mPhone.getDeviceId(); - } - - /** - * Retrieves the software version number for the device, e.g., IMEI/SV - * for GSM phones. - */ - public String getDeviceSvn() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getDeviceSvn(); - } - - /** - * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. - */ - public String getSubscriberId() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getSubscriberId(); - } - - /** - * Retrieves the serial number of the ICC, if applicable. - */ - public String getIccSerialNumber() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getIccSerialNumber(); - } - - /** - * Retrieves the phone number string for line 1. - */ - public String getLine1Number() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getLine1Number(); - } - - /** - * Retrieves the alpha identifier for line 1. - */ - public String getLine1AlphaTag() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return (String) mPhone.getLine1AlphaTag(); - } - - /** - * Retrieves the MSISDN string. - */ - public String getMsisdn() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getMsisdn(); - } - - /** - * Retrieves the voice mail number. - */ - public String getVoiceMailNumber() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber()); - Log.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number); - return number; - } - - /** - * Retrieves the complete voice mail number. - * - * @hide - */ - public String getCompleteVoiceMailNumber() { - mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED, - "Requires CALL_PRIVILEGED"); - String number = mPhone.getVoiceMailNumber(); - Log.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number); - return number; - } - - /** - * Retrieves the alpha identifier associated with the voice mail number. - */ - public String getVoiceMailAlphaTag() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return (String) mPhone.getVoiceMailAlphaTag(); - } - - /** - * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. - * @return the IMPI, or null if not present or not loaded - */ - public String getIsimImpi() { - mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, - "Requires READ_PRIVILEGED_PHONE_STATE"); - IsimRecords isim = mPhone.getIsimRecords(); - if (isim != null) { - return isim.getIsimImpi(); - } else { - return null; - } - } - - /** - * Returns the IMS home network domain name that was loaded from the ISIM. - * @return the IMS domain name, or null if not present or not loaded - */ - public String getIsimDomain() { - mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, - "Requires READ_PRIVILEGED_PHONE_STATE"); - IsimRecords isim = mPhone.getIsimRecords(); - if (isim != null) { - return isim.getIsimDomain(); - } else { - return null; - } - } - - /** - * Returns the IMS public user identities (IMPU) that were loaded from the ISIM. - * @return an array of IMPU strings, with one IMPU per string, or null if - * not present or not loaded - */ - public String[] getIsimImpu() { - mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, - "Requires READ_PRIVILEGED_PHONE_STATE"); - IsimRecords isim = mPhone.getIsimRecords(); - if (isim != null) { - return isim.getIsimImpu(); - } else { - return null; - } - } - - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump PhoneSubInfo from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - pw.println("Phone Subscriber Info:"); - pw.println(" Phone Type = " + mPhone.getPhoneName()); - pw.println(" Device ID = " + mPhone.getDeviceId()); - } - -} diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java deleted file mode 100755 index bd130deb00d4..000000000000 --- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java +++ /dev/null @@ -1,133 +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; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.ServiceManager; - - -public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub { - private PhoneSubInfo mPhoneSubInfo; - - public PhoneSubInfoProxy(PhoneSubInfo phoneSubInfo) { - mPhoneSubInfo = phoneSubInfo; - if(ServiceManager.getService("iphonesubinfo") == null) { - ServiceManager.addService("iphonesubinfo", this); - } - } - - public void setmPhoneSubInfo(PhoneSubInfo phoneSubInfo) { - this.mPhoneSubInfo = phoneSubInfo; - } - - public String getDeviceId() { - return mPhoneSubInfo.getDeviceId(); - } - - public String getDeviceSvn() { - return mPhoneSubInfo.getDeviceSvn(); - } - - /** - * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. - */ - public String getSubscriberId() { - return mPhoneSubInfo.getSubscriberId(); - } - - /** - * Retrieves the serial number of the ICC, if applicable. - */ - public String getIccSerialNumber() { - return mPhoneSubInfo.getIccSerialNumber(); - } - - /** - * Retrieves the phone number string for line 1. - */ - public String getLine1Number() { - return mPhoneSubInfo.getLine1Number(); - } - - /** - * Retrieves the alpha identifier for line 1. - */ - public String getLine1AlphaTag() { - return mPhoneSubInfo.getLine1AlphaTag(); - } - - /** - * Retrieves the MSISDN Number. - */ - public String getMsisdn() { - return mPhoneSubInfo.getMsisdn(); - } - - /** - * Retrieves the voice mail number. - */ - public String getVoiceMailNumber() { - return mPhoneSubInfo.getVoiceMailNumber(); - } - - /** - * Retrieves the complete voice mail number. - */ - public String getCompleteVoiceMailNumber() { - return mPhoneSubInfo.getCompleteVoiceMailNumber(); - } - - /** - * Retrieves the alpha identifier associated with the voice mail number. - */ - public String getVoiceMailAlphaTag() { - return mPhoneSubInfo.getVoiceMailAlphaTag(); - } - - /** - * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. - * @return the IMPI, or null if not present or not loaded - */ - public String getIsimImpi() { - return mPhoneSubInfo.getIsimImpi(); - } - - /** - * Returns the IMS home network domain name that was loaded from the ISIM. - * @return the IMS domain name, or null if not present or not loaded - */ - public String getIsimDomain() { - return mPhoneSubInfo.getIsimDomain(); - } - - /** - * Returns the IMS public user identities (IMPU) that were loaded from the ISIM. - * @return an array of IMPU strings, with one IMPU per string, or null if - * not present or not loaded - */ - public String[] getIsimImpu() { - return mPhoneSubInfo.getIsimImpu(); - } - - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - mPhoneSubInfo.dump(fd, pw, args); - } -} diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java deleted file mode 100644 index b14f6c8ea60f..000000000000 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ /dev/null @@ -1,3861 +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; - -import static com.android.internal.telephony.RILConstants.*; -import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; -import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE; -import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS; -import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS; -import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA; -import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA; -import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.LocalSocket; -import android.net.LocalSocketAddress; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.os.Parcel; -import android.os.PowerManager; -import android.os.SystemProperties; -import android.os.PowerManager.WakeLock; -import android.telephony.NeighboringCellInfo; -import android.telephony.PhoneNumberUtils; -import android.telephony.SmsManager; -import android.telephony.SmsMessage; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; -import com.android.internal.telephony.gsm.SuppServiceNotification; -import com.android.internal.telephony.cdma.CdmaCallWaitingNotification; -import com.android.internal.telephony.cdma.CdmaInformationRecords; -import com.android.internal.telephony.IccRefreshResponse; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * {@hide} - */ -class RILRequest { - static final String LOG_TAG = "RILJ"; - - //***** Class Variables - static int sNextSerial = 0; - static Object sSerialMonitor = new Object(); - private static Object sPoolSync = new Object(); - private static RILRequest sPool = null; - private static int sPoolSize = 0; - private static final int MAX_POOL_SIZE = 4; - - //***** Instance Variables - int mSerial; - int mRequest; - Message mResult; - Parcel mp; - RILRequest mNext; - - /** - * 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; - sPool = rr.mNext; - rr.mNext = null; - sPoolSize--; - } - } - - if (rr == null) { - rr = new RILRequest(); - } - - synchronized(sSerialMonitor) { - rr.mSerial = sNextSerial++; - } - rr.mRequest = request; - rr.mResult = result; - rr.mp = Parcel.obtain(); - - if (result != null && result.getTarget() == null) { - throw new NullPointerException("Message target must not be null"); - } - - // first elements in any RIL Parcel - rr.mp.writeInt(request); - rr.mp.writeInt(rr.mSerial); - - return rr; - } - - /** - * Returns a RILRequest instance to the pool. - * - * Note: This should only be called once per use. - */ - void release() { - synchronized (sPoolSync) { - if (sPoolSize < MAX_POOL_SIZE) { - this.mNext = sPool; - sPool = this; - sPoolSize++; - mResult = null; - } - } - } - - private RILRequest() { - } - - static void - resetSerial() { - synchronized(sSerialMonitor) { - sNextSerial = 0; - } - } - - String - serialString() { - //Cheesy way to do %04d - StringBuilder sb = new StringBuilder(8); - String sn; - - sn = Integer.toString(mSerial); - - //sb.append("J["); - sb.append('['); - for (int i = 0, s = sn.length() ; i < 4 - s; i++) { - sb.append('0'); - } - - sb.append(sn); - sb.append(']'); - return sb.toString(); - } - - void - onError(int error, Object ret) { - CommandException ex; - - ex = CommandException.fromRilErrno(error); - - if (RIL.RILJ_LOGD) Log.d(LOG_TAG, serialString() + "< " - + RIL.requestToString(mRequest) - + " error: " + ex); - - if (mResult != null) { - AsyncResult.forMessage(mResult, ret, ex); - mResult.sendToTarget(); - } - - if (mp != null) { - mp.recycle(); - mp = null; - } - } -} - - -/** - * RIL implementation of the CommandsInterface. - * FIXME public only for testing - * - * {@hide} - */ -public final class RIL extends BaseCommands implements CommandsInterface { - static final String LOG_TAG = "RILJ"; - static final boolean RILJ_LOGD = true; - static final boolean RILJ_LOGV = false; // STOP SHIP if true - - /** - * Wake lock timeout should be longer than the longest timeout in - * the vendor ril. - */ - private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000; - - //***** Instance Variables - - LocalSocket mSocket; - HandlerThread mSenderThread; - RILSender mSender; - Thread mReceiverThread; - RILReceiver mReceiver; - WakeLock mWakeLock; - int mWakeLockTimeout; - // The number of requests pending to be sent out, it increases before calling - // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while - // WAKE_LOCK_TIMEOUT occurs. - int mRequestMessagesPending; - // The number of requests sent out but waiting for response. It increases while - // sending request and decreases while handling response. It should match - // mRequestList.size() unless there are requests no replied while - // WAKE_LOCK_TIMEOUT occurs. - int mRequestMessagesWaiting; - - //I'd rather this be LinkedList or something - ArrayList mRequestsList = new ArrayList(); - - Object mLastNITZTimeInfo; - - // When we are testing emergency calls - AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false); - - //***** Events - - static final int EVENT_SEND = 1; - static final int EVENT_WAKE_LOCK_TIMEOUT = 2; - - //***** Constants - - // match with constant in ril.cpp - static final int RIL_MAX_COMMAND_BYTES = (8 * 1024); - static final int RESPONSE_SOLICITED = 0; - static final int RESPONSE_UNSOLICITED = 1; - - static final String SOCKET_NAME_RIL = "rild"; - - static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000; - - // The number of the required config values for broadcast SMS stored in the C struct - // RIL_CDMA_BroadcastServiceInfo - private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3; - - private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31; - - BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { - sendScreenState(true); - } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { - sendScreenState(false); - } else { - Log.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction()); - } - } - }; - - class RILSender extends Handler implements Runnable { - public RILSender(Looper looper) { - super(looper); - } - - // Only allocated once - byte[] dataLength = new byte[4]; - - //***** Runnable implementation - public void - run() { - //setup if needed - } - - - //***** Handler implementation - @Override public void - handleMessage(Message msg) { - RILRequest rr = (RILRequest)(msg.obj); - RILRequest req = null; - - switch (msg.what) { - case EVENT_SEND: - /** - * mRequestMessagePending++ already happened for every - * EVENT_SEND, thus we must make sure - * mRequestMessagePending-- happens once and only once - */ - boolean alreadySubtracted = false; - try { - LocalSocket s; - - s = mSocket; - - if (s == null) { - rr.onError(RADIO_NOT_AVAILABLE, null); - rr.release(); - if (mRequestMessagesPending > 0) - mRequestMessagesPending--; - alreadySubtracted = true; - return; - } - - synchronized (mRequestsList) { - mRequestsList.add(rr); - mRequestMessagesWaiting++; - } - - if (mRequestMessagesPending > 0) - mRequestMessagesPending--; - alreadySubtracted = true; - - byte[] data; - - data = rr.mp.marshall(); - rr.mp.recycle(); - rr.mp = null; - - if (data.length > RIL_MAX_COMMAND_BYTES) { - throw new RuntimeException( - "Parcel larger than max bytes allowed! " - + data.length); - } - - // parcel length in big endian - dataLength[0] = dataLength[1] = 0; - dataLength[2] = (byte)((data.length >> 8) & 0xff); - dataLength[3] = (byte)((data.length) & 0xff); - - //Log.v(LOG_TAG, "writing packet: " + data.length + " bytes"); - - s.getOutputStream().write(dataLength); - s.getOutputStream().write(data); - } catch (IOException ex) { - Log.e(LOG_TAG, "IOException", ex); - req = findAndRemoveRequestFromList(rr.mSerial); - // make sure this request has not already been handled, - // eg, if RILReceiver cleared the list. - if (req != null || !alreadySubtracted) { - rr.onError(RADIO_NOT_AVAILABLE, null); - rr.release(); - } - } catch (RuntimeException exc) { - Log.e(LOG_TAG, "Uncaught exception ", exc); - req = findAndRemoveRequestFromList(rr.mSerial); - // make sure this request has not already been handled, - // eg, if RILReceiver cleared the list. - if (req != null || !alreadySubtracted) { - rr.onError(GENERIC_FAILURE, null); - rr.release(); - } - } finally { - // Note: We are "Done" only if there are no outstanding - // requests or replies. Thus this code path will only release - // the wake lock on errors. - releaseWakeLockIfDone(); - } - - if (!alreadySubtracted && mRequestMessagesPending > 0) { - mRequestMessagesPending--; - } - - break; - - case EVENT_WAKE_LOCK_TIMEOUT: - // Haven't heard back from the last request. Assume we're - // not getting a response and release the wake lock. - synchronized (mWakeLock) { - if (mWakeLock.isHeld()) { - // The timer of WAKE_LOCK_TIMEOUT is reset with each - // new send request. So when WAKE_LOCK_TIMEOUT occurs - // all requests in mRequestList already waited at - // least DEFAULT_WAKE_LOCK_TIMEOUT but no response. - // Reset mRequestMessagesWaiting to enable - // releaseWakeLockIfDone(). - // - // Note: Keep mRequestList so that delayed response - // can still be handled when response finally comes. - if (mRequestMessagesWaiting != 0) { - Log.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but" - + mRequestMessagesWaiting + " at TIMEOUT, reset!" - + " There still msg waitng for response"); - - mRequestMessagesWaiting = 0; - - if (RILJ_LOGD) { - synchronized (mRequestsList) { - int count = mRequestsList.size(); - Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " + - " mRequestList=" + count); - - for (int i = 0; i < count; i++) { - rr = mRequestsList.get(i); - Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " - + requestToString(rr.mRequest)); - } - } - } - } - // mRequestMessagesPending shows how many - // requests are waiting to be sent (and before - // to be added in request list) since star the - // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT - // is the expected time to get response, all requests - // should already sent out (i.e. - // mRequestMessagesPending is 0 )while TIMEOUT occurs. - if (mRequestMessagesPending != 0) { - Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but" - + mRequestMessagesPending + " at TIMEOUT, reset!"); - mRequestMessagesPending = 0; - - } - mWakeLock.release(); - } - } - break; - } - } - } - - /** - * Reads in a single RIL message off the wire. A RIL message consists - * of a 4-byte little-endian length and a subsequent series of bytes. - * The final message (length header omitted) is read into - * buffer and the length of the final message (less header) - * is returned. A return value of -1 indicates end-of-stream. - * - * @param is non-null; Stream to read from - * @param buffer Buffer to fill in. Must be as large as maximum - * message size, or an ArrayOutOfBounds exception will be thrown. - * @return Length of message less header, or -1 on end of stream. - * @throws IOException - */ - private static int readRilMessage(InputStream is, byte[] buffer) - throws IOException { - int countRead; - int offset; - int remaining; - int messageLength; - - // First, read in the length of the message - offset = 0; - remaining = 4; - do { - countRead = is.read(buffer, offset, remaining); - - if (countRead < 0 ) { - Log.e(LOG_TAG, "Hit EOS reading message length"); - return -1; - } - - offset += countRead; - remaining -= countRead; - } while (remaining > 0); - - messageLength = ((buffer[0] & 0xff) << 24) - | ((buffer[1] & 0xff) << 16) - | ((buffer[2] & 0xff) << 8) - | (buffer[3] & 0xff); - - // Then, re-use the buffer and read in the message itself - offset = 0; - remaining = messageLength; - do { - countRead = is.read(buffer, offset, remaining); - - if (countRead < 0 ) { - Log.e(LOG_TAG, "Hit EOS reading message. messageLength=" + messageLength - + " remaining=" + remaining); - return -1; - } - - offset += countRead; - remaining -= countRead; - } while (remaining > 0); - - return messageLength; - } - - class RILReceiver implements Runnable { - byte[] buffer; - - RILReceiver() { - buffer = new byte[RIL_MAX_COMMAND_BYTES]; - } - - public void - run() { - int retryCount = 0; - - try {for (;;) { - LocalSocket s = null; - LocalSocketAddress l; - - try { - s = new LocalSocket(); - l = new LocalSocketAddress(SOCKET_NAME_RIL, - LocalSocketAddress.Namespace.RESERVED); - s.connect(l); - } catch (IOException ex){ - try { - if (s != null) { - s.close(); - } - } 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, - "Couldn't find '" + SOCKET_NAME_RIL - + "' socket after " + retryCount - + " times, continuing to retry silently"); - } else if (retryCount > 0 && retryCount < 8) { - Log.i (LOG_TAG, - "Couldn't find '" + SOCKET_NAME_RIL - + "' socket; retrying after timeout"); - } - - try { - Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); - } catch (InterruptedException er) { - } - - retryCount++; - continue; - } - - retryCount = 0; - - mSocket = s; - Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket"); - - int length = 0; - try { - InputStream is = mSocket.getInputStream(); - - for (;;) { - Parcel p; - - length = readRilMessage(is, buffer); - - if (length < 0) { - // End-of-stream reached - break; - } - - p = Parcel.obtain(); - p.unmarshall(buffer, 0, length); - p.setDataPosition(0); - - //Log.v(LOG_TAG, "Read packet: " + length + " bytes"); - - processResponse(p); - p.recycle(); - } - } catch (java.io.IOException ex) { - Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed", - ex); - } catch (Throwable tr) { - Log.e(LOG_TAG, "Uncaught exception read length=" + length + - "Exception:" + tr.toString()); - } - - Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL - + "' socket"); - - setRadioState (RadioState.RADIO_UNAVAILABLE); - - try { - mSocket.close(); - } catch (IOException ex) { - } - - mSocket = null; - RILRequest.resetSerial(); - - // Clear request list on close - clearRequestsList(RADIO_NOT_AVAILABLE, false); - }} catch (Throwable tr) { - Log.e(LOG_TAG,"Uncaught exception", tr); - } - - /* We're disconnected so we don't know the ril version */ - notifyRegistrantsRilConnectionChanged(-1); - } - } - - - - //***** Constructors - - public RIL(Context context, int preferredNetworkType, int cdmaSubscription) { - super(context); - if (RILJ_LOGD) { - riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType + - " cdmaSubscription=" + cdmaSubscription + ")"); - } - mCdmaSubscription = cdmaSubscription; - mPreferredNetworkType = preferredNetworkType; - mPhoneType = RILConstants.NO_PHONE; - - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); - mWakeLock.setReferenceCounted(false); - mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT, - DEFAULT_WAKE_LOCK_TIMEOUT); - mRequestMessagesPending = 0; - mRequestMessagesWaiting = 0; - - mSenderThread = new HandlerThread("RILSender"); - mSenderThread.start(); - - Looper looper = mSenderThread.getLooper(); - mSender = new RILSender(looper); - - ConnectivityManager cm = (ConnectivityManager)context.getSystemService( - Context.CONNECTIVITY_SERVICE); - if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) { - riljLog("Not starting RILReceiver: wifi-only"); - } else { - riljLog("Starting RILReceiver"); - mReceiver = new RILReceiver(); - mReceiverThread = new Thread(mReceiver, "RILReceiver"); - mReceiverThread.start(); - - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - context.registerReceiver(mIntentReceiver, filter); - } - } - - //***** CommandsInterface implementation - - public void getVoiceRadioTechnology(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - @Override public void - setOnNITZTime(Handler h, int what, Object obj) { - super.setOnNITZTime(h, what, obj); - - // Send the last NITZ time if we have it - if (mLastNITZTimeInfo != null) { - mNITZTimeRegistrant - .notifyRegistrant( - new AsyncResult (null, mLastNITZTimeInfo, null)); - mLastNITZTimeInfo = null; - } - } - - public void - getIccCardStatus(Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - @Override public void - supplyIccPin(String pin, Message result) { - supplyIccPinForApp(pin, null, result); - } - - @Override public void - supplyIccPinForApp(String pin, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(pin); - rr.mp.writeString(aid); - - send(rr); - } - - @Override public void - supplyIccPuk(String puk, String newPin, Message result) { - supplyIccPukForApp(puk, newPin, null, result); - } - - @Override public void - supplyIccPukForApp(String puk, String newPin, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(puk); - rr.mp.writeString(newPin); - rr.mp.writeString(aid); - - send(rr); - } - - @Override public void - supplyIccPin2(String pin, Message result) { - supplyIccPin2ForApp(pin, null, result); - } - - @Override public void - supplyIccPin2ForApp(String pin, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(pin); - rr.mp.writeString(aid); - - send(rr); - } - - @Override public void - supplyIccPuk2(String puk2, String newPin2, Message result) { - supplyIccPuk2ForApp(puk2, newPin2, null, result); - } - - @Override public void - supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(puk); - rr.mp.writeString(newPin2); - rr.mp.writeString(aid); - - send(rr); - } - - @Override public void - changeIccPin(String oldPin, String newPin, Message result) { - changeIccPinForApp(oldPin, newPin, null, result); - } - - @Override public void - changeIccPinForApp(String oldPin, String newPin, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(oldPin); - rr.mp.writeString(newPin); - rr.mp.writeString(aid); - - send(rr); - } - - @Override public void - changeIccPin2(String oldPin2, String newPin2, Message result) { - changeIccPin2ForApp(oldPin2, newPin2, null, result); - } - - @Override public void - changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) { - //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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(oldPin2); - rr.mp.writeString(newPin2); - rr.mp.writeString(aid); - - send(rr); - } - - public void - changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(facility); - rr.mp.writeString(oldPwd); - rr.mp.writeString(newPwd); - - send(rr); - } - - public void - supplyNetworkDepersonalization(String netpin, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(1); - rr.mp.writeString(netpin); - - send(rr); - } - - public void - getCurrentCalls (Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - @Deprecated public void - getPDPContextList(Message result) { - getDataCallList(result); - } - - public void - getDataCallList(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - dial (String address, int clirMode, Message result) { - dial(address, clirMode, null, result); - } - - public void - dial(String address, int clirMode, UUSInfo uusInfo, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); - - rr.mp.writeString(address); - rr.mp.writeInt(clirMode); - rr.mp.writeInt(0); // UUS information is absent - - if (uusInfo == null) { - rr.mp.writeInt(0); // UUS information is absent - } else { - rr.mp.writeInt(1); // UUS information is present - rr.mp.writeInt(uusInfo.getType()); - rr.mp.writeInt(uusInfo.getDcs()); - rr.mp.writeByteArray(uusInfo.getUserData()); - } - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getIMSI(Message result) { - getIMSIForApp(null, result); - } - - public void - getIMSIForApp(String aid, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); - - rr.mp.writeInt(1); - rr.mp.writeString(aid); - - if (RILJ_LOGD) riljLog(rr.serialString() + - "> getIMSI: " + requestToString(rr.mRequest) - + " aid: " + aid); - - send(rr); - } - - public void - getIMEI(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getIMEISV(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - hangupConnection (int gsmIndex, Message result) { - if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex); - - RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + - gsmIndex); - - rr.mp.writeInt(1); - rr.mp.writeInt(gsmIndex); - - send(rr); - } - - public void - hangupWaitingOrBackground (Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, - result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - hangupForegroundResumeBackground (Message result) { - RILRequest rr - = RILRequest.obtain( - RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, - result); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - switchWaitingOrHoldingAndActive (Message result) { - RILRequest rr - = RILRequest.obtain( - RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, - result); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - conference (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - 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); - send(rr); - } - - public void - separateConnection (int gsmIndex, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + gsmIndex); - - rr.mp.writeInt(1); - rr.mp.writeInt(gsmIndex); - - send(rr); - } - - public void - acceptCall (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_ANSWER, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - rejectCall (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_UDUB, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - explicitCallTransfer (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getLastCallFailCause (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * @deprecated - */ - public void - getLastPdpFailCause (Message 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_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setMute (boolean enableMute, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + enableMute); - - rr.mp.writeInt(1); - rr.mp.writeInt(enableMute ? 1 : 0); - - send(rr); - } - - public void - getMute (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getSignalStrength (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getVoiceRegistrationState (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getDataRegistrationState (Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getOperator(Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OPERATOR, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - sendDtmf(char c, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(Character.toString(c)); - - send(rr); - } - - public void - startDtmf(char c, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF_START, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(Character.toString(c)); - - send(rr); - } - - public void - stopDtmf(Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - sendBurstDtmf(String dtmfString, int on, int off, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result); - - rr.mp.writeInt(3); - rr.mp.writeString(dtmfString); - rr.mp.writeString(Integer.toString(on)); - rr.mp.writeString(Integer.toString(off)); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + dtmfString); - - send(rr); - } - - public void - sendSMS (String smscPDU, String pdu, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result); - - rr.mp.writeInt(2); - rr.mp.writeString(smscPDU); - rr.mp.writeString(pdu); - - if (RILJ_LOGD) 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.writeByte((byte) 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.writeByte((byte) address_nbr_of_digits); - for(int i=0; i < address_nbr_of_digits; i++){ - rr.mp.writeByte(dis.readByte()); // address_orig_bytes[i] - } - rr.mp.writeInt(dis.read()); //subaddressType - rr.mp.writeByte((byte) dis.read()); //subaddr_odd - subaddr_nbr_of_digits = (byte) dis.read(); - rr.mp.writeByte((byte) subaddr_nbr_of_digits); - for(int i=0; i < subaddr_nbr_of_digits; i++){ - rr.mp.writeByte(dis.readByte()); //subaddr_orig_bytes[i] - } - - bearerDataLength = dis.read(); - rr.mp.writeInt(bearerDataLength); - for(int i=0; i < bearerDataLength; i++){ - rr.mp.writeByte(dis.readByte()); //bearerData[i] - } - }catch (IOException ex){ - if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: " - + ex); - } - - if (RILJ_LOGD) 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 (false) { - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + 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 (false) { - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) - + " " + index); - } - - send(rr); - } - - 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 (false) { - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + 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 (false) { - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) - + " " + status); - } - - send(rr); - } - - /** - * Translates EF_SMS status bits to a status value compatible with - * SMS AT commands. See TS 27.005 3.1. - */ - private int translateStatus(int status) { - switch(status & 0x7) { - case SmsManager.STATUS_ON_ICC_READ: - return 1; - case SmsManager.STATUS_ON_ICC_UNREAD: - return 0; - case SmsManager.STATUS_ON_ICC_SENT: - return 3; - case SmsManager.STATUS_ON_ICC_UNSENT: - return 2; - } - - // Default to READ. - return 1; - } - - public void - setupDataCall(String radioTechnology, String profile, String apn, - String user, String password, String authType, String protocol, - Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result); - - rr.mp.writeInt(7); - - rr.mp.writeString(radioTechnology); - rr.mp.writeString(profile); - rr.mp.writeString(apn); - rr.mp.writeString(user); - rr.mp.writeString(password); - rr.mp.writeString(authType); - rr.mp.writeString(protocol); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) + " " + radioTechnology + " " - + profile + " " + apn + " " + user + " " - + password + " " + authType + " " + protocol); - - send(rr); - } - - public void - deactivateDataCall(int cid, int reason, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result); - - rr.mp.writeInt(2); - rr.mp.writeString(Integer.toString(cid)); - rr.mp.writeString(Integer.toString(reason)); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + - requestToString(rr.mRequest) + " " + cid + " " + reason); - - send(rr); - } - - public void - setRadioPower(boolean on, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result); - - rr.mp.writeInt(1); - rr.mp.writeInt(on ? 1 : 0); - - if (RILJ_LOGD) { - riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + (on ? " on" : " off")); - } - - send(rr); - } - - public void - setSuppServiceNotifications(boolean enable, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result); - - rr.mp.writeInt(1); - rr.mp.writeInt(enable ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest)); - - send(rr); - } - - public void - acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result); - - rr.mp.writeInt(2); - rr.mp.writeInt(success ? 1 : 0); - rr.mp.writeInt(cause); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + success + " " + cause); - - send(rr); - } - - public void - acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result); - - rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass - // cause code according to X.S004-550E - rr.mp.writeInt(cause); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + success + " " + cause); - - send(rr); - } - - public void - acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result); - - rr.mp.writeInt(2); - rr.mp.writeString(success ? "1" : "0"); - rr.mp.writeString(ackPdu); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + ' ' + success + " [" + ackPdu + ']'); - - send(rr); - } - - public void - iccIO (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, Message result) { - iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, null, result); - } - public void - iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, String aid, Message result) { - //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); - rr.mp.writeInt(p1); - rr.mp.writeInt(p2); - rr.mp.writeInt(p3); - rr.mp.writeString(data); - rr.mp.writeString(pin2); - rr.mp.writeString(aid); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " - + requestToString(rr.mRequest) - + " 0x" + Integer.toHexString(command) - + " 0x" + Integer.toHexString(fileid) + " " - + " path: " + path + "," - + p1 + "," + p2 + "," + p3 - + " aid: " + aid); - - send(rr); - } - - public void - getCLIR(Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setCLIR(int clirMode, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result); - - // count ints - rr.mp.writeInt(1); - - rr.mp.writeInt(clirMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + clirMode); - - send(rr); - } - - public void - queryCallWaiting(int serviceClass, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(serviceClass); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + serviceClass); - - send(rr); - } - - public void - setCallWaiting(boolean enable, int serviceClass, Message response) { - 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_LOGD) 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, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setNetworkSelectionModeManual(String operatorNumeric, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + operatorNumeric); - - rr.mp.writeString(operatorNumeric); - - send(rr); - } - - public void - getNetworkSelectionMode(Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getAvailableNetworks(Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setCallForward(int action, int cfReason, int serviceClass, - String number, int timeSeconds, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response); - - rr.mp.writeInt(action); - rr.mp.writeInt(cfReason); - rr.mp.writeInt(serviceClass); - rr.mp.writeInt(PhoneNumberUtils.toaFromString(number)); - rr.mp.writeString(number); - rr.mp.writeInt (timeSeconds); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + action + " " + cfReason + " " + serviceClass - + timeSeconds); - - send(rr); - } - - public void - queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response); - - rr.mp.writeInt(2); // 2 is for query action, not in used anyway - rr.mp.writeInt(cfReason); - rr.mp.writeInt(serviceClass); - rr.mp.writeInt(PhoneNumberUtils.toaFromString(number)); - rr.mp.writeString(number); - rr.mp.writeInt (0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + cfReason + " " + serviceClass); - - send(rr); - } - - public void - queryCLIP(Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - getBasebandVersion (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - @Override - public void - queryFacilityLock(String facility, String password, int serviceClass, - Message response) { - queryFacilityLockForApp(facility, password, serviceClass, null, response); - } - - @Override - public void - queryFacilityLockForApp(String facility, String password, int serviceClass, String appId, - Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(4); - - rr.mp.writeString(facility); - rr.mp.writeString(password); - - rr.mp.writeString(Integer.toString(serviceClass)); - rr.mp.writeString(appId); - - send(rr); - } - - @Override - public void - setFacilityLock (String facility, boolean lockState, String password, - int serviceClass, Message response) { - setFacilityLockForApp(facility, lockState, password, serviceClass, null, response); - } - - @Override - public void - setFacilityLockForApp(String facility, boolean lockState, String password, - int serviceClass, String appId, Message response) { - String lockString; - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(5); - - rr.mp.writeString(facility); - lockString = (lockState)?"1":"0"; - rr.mp.writeString(lockString); - rr.mp.writeString(password); - rr.mp.writeString(Integer.toString(serviceClass)); - rr.mp.writeString(appId); - - send(rr); - - } - - public void - sendUSSD (String ussdString, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + ussdString); - - rr.mp.writeString(ussdString); - - send(rr); - } - - // inherited javadoc suffices - public void cancelPendingUssd (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response); - - if (RILJ_LOGD) riljLog(rr.serialString() - + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void resetRadio(Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + "[" + IccUtils.bytesToHexString(data) + "]"); - - rr.mp.writeByteArray(data); - - send(rr); - - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeStringArray(strings); - - send(rr); - } - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - public void setBandMode (int bandMode, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(bandMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + bandMode); - - send(rr); - } - - /** - * 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 - */ - public void queryAvailableBandMode (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void sendTerminalResponse(String contents, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(contents); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelope(String contents, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(contents); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelopeWithStatus(String contents, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + '[' + contents + ']'); - - rr.mp.writeString(contents); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void handleCallSetupRequestFromSim( - boolean accept, Message response) { - - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - int[] param = new int[1]; - param[0] = accept ? 1 : 0; - rr.mp.writeIntArray(param); - send(rr); - } - - /** - * {@inheritDoc} - */ - @Override - public void setCurrentPreferredNetworkType() { - if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType); - setPreferredNetworkType(mSetPreferredNetworkType, null); - } - private int mSetPreferredNetworkType; - - /** - * {@inheritDoc} - */ - public void setPreferredNetworkType(int networkType , Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(networkType); - - mSetPreferredNetworkType = networkType; - mPreferredNetworkType = networkType; - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + networkType); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getPreferredNetworkType(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getNeighboringCids(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setLocationUpdates(boolean enable, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response); - rr.mp.writeInt(1); - rr.mp.writeInt(enable ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) + ": " + enable); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getSmscAddress(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SMSC_ADDRESS, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setSmscAddress(String address, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result); - - rr.mp.writeString(address); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + address); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void reportSmsMemoryStatus(boolean available, Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result); - rr.mp.writeInt(1); - rr.mp.writeInt(available ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) + ": " + available); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void reportStkServiceIsRunning(Message result) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getGsmBroadcastConfig(Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response); - - int numOfConfig = config.length; - rr.mp.writeInt(numOfConfig); - - for(int i = 0; i < numOfConfig; i++) { - rr.mp.writeInt(config[i].getFromServiceId()); - rr.mp.writeInt(config[i].getToServiceId()); - rr.mp.writeInt(config[i].getFromCodeScheme()); - rr.mp.writeInt(config[i].getToCodeScheme()); - rr.mp.writeInt(config[i].isSelected() ? 1 : 0); - } - - if (RILJ_LOGD) { - riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " with " + numOfConfig + " configs : "); - for (int i = 0; i < numOfConfig; i++) { - riljLog(config[i].toString()); - } - } - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setGsmBroadcastActivation(boolean activate, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(activate ? 0 : 1); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - //***** Private Methods - - private void sendScreenState(boolean on) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null); - rr.mp.writeInt(1); - rr.mp.writeInt(on ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() - + "> " + requestToString(rr.mRequest) + ": " + on); - - send(rr); - } - - protected void - onRadioAvailable() { - // In case screen state was lost (due to process crash), - // this ensures that the RIL knows the correct screen state. - - // TODO: Should query Power Manager and send the actual - // screen state. Just send true for now. - sendScreenState(true); - } - - private RadioState getRadioStateFromInt(int stateInt) { - RadioState state; - - /* RIL_RadioState ril.h */ - switch(stateInt) { - case 0: state = RadioState.RADIO_OFF; break; - case 1: state = RadioState.RADIO_UNAVAILABLE; break; - case 10: state = RadioState.RADIO_ON; break; - - default: - throw new RuntimeException( - "Unrecognized RIL_RadioState: " + stateInt); - } - return state; - } - - private void switchToRadioState(RadioState newState) { - setRadioState(newState); - } - - /** - * Holds a PARTIAL_WAKE_LOCK whenever - * a) There is outstanding RIL request sent to RIL deamon and no replied - * b) There is a request pending to be sent out. - * - * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't - * happen often. - */ - - private void - acquireWakeLock() { - synchronized (mWakeLock) { - mWakeLock.acquire(); - mRequestMessagesPending++; - - mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); - mSender.sendMessageDelayed(msg, mWakeLockTimeout); - } - } - - private void - releaseWakeLockIfDone() { - synchronized (mWakeLock) { - if (mWakeLock.isHeld() && - (mRequestMessagesPending == 0) && - (mRequestMessagesWaiting == 0)) { - mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - mWakeLock.release(); - } - } - } - - private void - send(RILRequest rr) { - Message msg; - - if (mSocket == null) { - rr.onError(RADIO_NOT_AVAILABLE, null); - rr.release(); - return; - } - - msg = mSender.obtainMessage(EVENT_SEND, rr); - - acquireWakeLock(); - - msg.sendToTarget(); - } - - private void - processResponse (Parcel p) { - int type; - - type = p.readInt(); - - if (type == RESPONSE_UNSOLICITED) { - processUnsolicited (p); - } else if (type == RESPONSE_SOLICITED) { - processSolicited (p); - } - - releaseWakeLockIfDone(); - } - - /** - * Release each request in mReqeustsList then clear the list - * @param error is the RIL_Errno sent back - * @param loggable true means to print all requests in mRequestslist - */ - private void clearRequestsList(int error, boolean loggable) { - RILRequest rr; - synchronized (mRequestsList) { - int count = mRequestsList.size(); - if (RILJ_LOGD && loggable) { - Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " + - " mReqPending=" + mRequestMessagesPending + - " mRequestList=" + count); - } - - for (int i = 0; i < count ; i++) { - rr = mRequestsList.get(i); - if (RILJ_LOGD && loggable) { - Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " + - requestToString(rr.mRequest)); - } - rr.onError(error, null); - rr.release(); - } - mRequestsList.clear(); - mRequestMessagesWaiting = 0; - } - } - - private RILRequest findAndRemoveRequestFromList(int serial) { - synchronized (mRequestsList) { - for (int i = 0, s = mRequestsList.size() ; i < s ; i++) { - RILRequest rr = mRequestsList.get(i); - - if (rr.mSerial == serial) { - mRequestsList.remove(i); - if (mRequestMessagesWaiting > 0) - mRequestMessagesWaiting--; - return rr; - } - } - } - - return null; - } - - private void - processSolicited (Parcel p) { - int serial, error; - boolean found = false; - - serial = p.readInt(); - error = p.readInt(); - - RILRequest rr; - - rr = findAndRemoveRequestFromList(serial); - - if (rr == null) { - Log.w(LOG_TAG, "Unexpected solicited response! sn: " - + serial + " error: " + error); - return; - } - - Object ret = null; - - if (error == 0 || p.dataAvail() > 0) { - // either command succeeds or command fails but with data payload - try {switch (rr.mRequest) { - /* - cat libs/telephony/ril_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/' - */ - case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break; - case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break; - case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break; - case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break; - case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break; - case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break; - case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break; - case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break; - case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break; - case RIL_REQUEST_DIAL: ret = responseVoid(p); break; - case RIL_REQUEST_GET_IMSI: ret = responseString(p); break; - case RIL_REQUEST_HANGUP: ret = responseVoid(p); break; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: { - if (mTestingEmergencyCall.getAndSet(false)) { - if (mEmergencyCallbackModeRegistrant != null) { - riljLog("testing emergency call, notify ECM Registrants"); - mEmergencyCallbackModeRegistrant.notifyRegistrant(); - } - } - ret = responseVoid(p); - break; - } - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break; - case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break; - case RIL_REQUEST_UDUB: ret = responseVoid(p); break; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break; - case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; - case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break; - case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break; - case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break; - case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break; - 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_DATA_CALL: ret = responseSetupDataCall(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; - case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break; - case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break; - case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break; - case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break; - case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break; - 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_DATA_CALL: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break; - case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break; - case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseOperatorInfos(p); break; - case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break; - 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_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 = responseGetPreferredNetworkType(p); break; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break; - case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: 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; - case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break; - case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break; - case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break; - case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break; - case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break; - case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break; - case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break; - case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break; - case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break; - case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break; - case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break; - case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break; - case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break; - case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; - case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break; - case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break; - case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break; - case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break; - case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break; - case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break; - case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break; - default: - 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); - - if (rr.mResult != null) { - AsyncResult.forMessage(rr.mResult, null, tr); - rr.mResult.sendToTarget(); - } - rr.release(); - return; - } - } - - if (error != 0) { - rr.onError(error, ret); - rr.release(); - return; - } - - if (RILJ_LOGD) 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(); - } - - private String - retToString(int req, Object ret) { - if (ret == null) return ""; - switch (req) { - // Don't log these return values, for privacy's sake. - case RIL_REQUEST_GET_IMSI: - case RIL_REQUEST_GET_IMEI: - case RIL_REQUEST_GET_IMEISV: - if (!RILJ_LOGV) { - // If not versbose logging just return and don't display IMSI and IMEI, IMEISV - return ""; - } - } - - StringBuilder sb; - String s; - int length; - if (ret instanceof int[]){ - int[] intArray = (int[]) ret; - length = intArray.length; - sb = new StringBuilder("{"); - if (length > 0) { - int i = 0; - sb.append(intArray[i++]); - while ( i < length) { - sb.append(", ").append(intArray[i++]); - } - } - sb.append("}"); - s = sb.toString(); - } else if (ret instanceof String[]) { - String[] strings = (String[]) ret; - length = strings.length; - sb = new StringBuilder("{"); - if (length > 0) { - int i = 0; - sb.append(strings[i++]); - while ( i < length) { - sb.append(", ").append(strings[i++]); - } - } - sb.append("}"); - s = sb.toString(); - }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) { - ArrayList calls = (ArrayList) ret; - sb = new StringBuilder(" "); - for (DriverCall dc : calls) { - sb.append("[").append(dc).append("] "); - } - s = sb.toString(); - } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) { - ArrayList cells; - cells = (ArrayList) ret; - sb = new StringBuilder(" "); - for (NeighboringCellInfo cell : cells) { - sb.append(cell).append(" "); - } - s = sb.toString(); - } else { - s = ret.toString(); - } - return s; - } - - private void - processUnsolicited (Parcel p) { - int response; - Object ret; - - response = p.readInt(); - - try {switch(response) { -/* - cat libs/telephony/ril_unsol_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/' -*/ - - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break; - case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break; - case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break; - case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; - case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break; - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break; - case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break; - 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; - case RIL_UNSOL_SIM_REFRESH: ret = responseSimRefresh(p); break; - case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break; - case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break; - case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break; - case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break; - case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; - case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; - case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break; - case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break; - case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break; - case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break; - case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break; - case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break; - case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break; - case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break; - case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; - case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break; - case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break; - - default: - throw new RuntimeException("Unrecognized unsol response: " + response); - //break; (implied) - }} catch (Throwable tr) { - Log.e(LOG_TAG, "Exception processing unsol response: " + response + - "Exception:" + tr.toString()); - return; - } - - switch(response) { - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: - /* has bonus radio state int */ - RadioState newState = getRadioStateFromInt(p.readInt()); - if (RILJ_LOGD) unsljLogMore(response, newState.toString()); - - switchToRadioState(newState); - break; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: - if (RILJ_LOGD) unsljLog(response); - - mCallStateRegistrants - .notifyRegistrants(new AsyncResult(null, null, null)); - break; - case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: - if (RILJ_LOGD) unsljLog(response); - - mVoiceNetworkStateRegistrants - .notifyRegistrants(new AsyncResult(null, null, null)); - break; - case RIL_UNSOL_RESPONSE_NEW_SMS: { - if (RILJ_LOGD) unsljLog(response); - - // FIXME this should move up a layer - String a[] = new String[2]; - - a[1] = (String)ret; - - SmsMessage sms; - - sms = SmsMessage.newFromCMT(a); - if (mGsmSmsRegistrant != null) { - mGsmSmsRegistrant - .notifyRegistrant(new AsyncResult(null, sms, null)); - } - break; - } - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mSmsStatusRegistrant != null) { - mSmsStatusRegistrant.notifyRegistrant( - new AsyncResult(null, ret, null)); - } - break; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: - if (RILJ_LOGD) unsljLogRet(response, ret); - - int[] smsIndex = (int[])ret; - - if(smsIndex.length == 1) { - if (mSmsOnSimRegistrant != null) { - mSmsOnSimRegistrant. - notifyRegistrant(new AsyncResult(null, smsIndex, null)); - } - } else { - if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length " - + smsIndex.length); - } - break; - case RIL_UNSOL_ON_USSD: - String[] resp = (String[])ret; - - if (resp.length < 2) { - resp = new String[2]; - resp[0] = ((String[])ret)[0]; - resp[1] = null; - } - if (RILJ_LOGD) unsljLogMore(response, resp[0]); - if (mUSSDRegistrant != null) { - mUSSDRegistrant.notifyRegistrant( - new AsyncResult (null, resp, null)); - } - break; - case RIL_UNSOL_NITZ_TIME_RECEIVED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - // has bonus long containing milliseconds since boot that the NITZ - // time was received - long nitzReceiveTime = p.readLong(); - - Object[] result = new Object[2]; - - result[0] = ret; - result[1] = Long.valueOf(nitzReceiveTime); - - boolean ignoreNitz = SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_IGNORE_NITZ, false); - - if (ignoreNitz) { - if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED"); - } else { - if (mNITZTimeRegistrant != null) { - - mNITZTimeRegistrant - .notifyRegistrant(new AsyncResult (null, result, null)); - } else { - // in case NITZ time registrant isnt registered yet - mLastNITZTimeInfo = result; - } - } - break; - - case RIL_UNSOL_SIGNAL_STRENGTH: - // Note this is set to "verbose" because it happens - // frequently - if (RILJ_LOGV) unsljLogvRet(response, ret); - - if (mSignalStrengthRegistrant != null) { - mSignalStrengthRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - case RIL_UNSOL_DATA_CALL_LIST_CHANGED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null)); - break; - - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mSsnRegistrant != null) { - mSsnRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_SESSION_END: - if (RILJ_LOGD) unsljLog(response); - - if (mCatSessionEndRegistrant != null) { - mCatSessionEndRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_PROACTIVE_COMMAND: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCatProCmdRegistrant != null) { - mCatProCmdRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_EVENT_NOTIFY: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCatEventRegistrant != null) { - mCatEventRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_CALL_SETUP: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCatCallSetUpRegistrant != null) { - mCatCallSetUpRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: - if (RILJ_LOGD) unsljLog(response); - - if (mIccSmsFullRegistrant != null) { - mIccSmsFullRegistrant.notifyRegistrant(); - } - break; - - case RIL_UNSOL_SIM_REFRESH: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mIccRefreshRegistrants != null) { - mIccRefreshRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_CALL_RING: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mRingRegistrant != null) { - mRingRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_RESTRICTED_STATE_CHANGED: - if (RILJ_LOGD) unsljLogvRet(response, ret); - if (mRestrictedStateRegistrant != null) { - mRestrictedStateRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: - if (RILJ_LOGD) unsljLog(response); - - if (mIccStatusChangedRegistrants != null) { - mIccStatusChangedRegistrants.notifyRegistrants(); - } - break; - - case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: - if (RILJ_LOGD) unsljLog(response); - - SmsMessage sms = (SmsMessage) ret; - - if (mCdmaSmsRegistrant != null) { - mCdmaSmsRegistrant - .notifyRegistrant(new AsyncResult(null, sms, null)); - } - break; - - case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: - if (RILJ_LOGD) unsljLog(response); - - if (mGsmBroadcastSmsRegistrant != null) { - mGsmBroadcastSmsRegistrant - .notifyRegistrant(new AsyncResult(null, ret, null)); - } - break; - - case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: - if (RILJ_LOGD) unsljLog(response); - - if (mIccSmsFullRegistrant != null) { - mIccSmsFullRegistrant.notifyRegistrant(); - } - break; - - case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: - if (RILJ_LOGD) unsljLog(response); - - if (mEmergencyCallbackModeRegistrant != null) { - mEmergencyCallbackModeRegistrant.notifyRegistrant(); - } - break; - - case RIL_UNSOL_CDMA_CALL_WAITING: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCallWaitingInfoRegistrants != null) { - mCallWaitingInfoRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mOtaProvisionRegistrants != null) { - mOtaProvisionRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_CDMA_INFO_REC: - ArrayList listInfoRecs; - - try { - listInfoRecs = (ArrayList)ret; - } catch (ClassCastException e) { - Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e); - break; - } - - for (CdmaInformationRecords rec : listInfoRecs) { - if (RILJ_LOGD) unsljLogRet(response, rec); - notifyRegistrantsCdmaInfoRec(rec); - } - break; - - case RIL_UNSOL_OEM_HOOK_RAW: - if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret)); - if (mUnsolOemHookRawRegistrant != null) { - mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null)); - } - break; - - case RIL_UNSOL_RINGBACK_TONE: - if (RILJ_LOGD) unsljLogvRet(response, ret); - if (mRingbackToneRegistrants != null) { - boolean playtone = (((int[])ret)[0] == 1); - mRingbackToneRegistrants.notifyRegistrants( - new AsyncResult (null, playtone, null)); - } - break; - - case RIL_UNSOL_RESEND_INCALL_MUTE: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mResendIncallMuteRegistrants != null) { - mResendIncallMuteRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mVoiceRadioTechChangedRegistrants != null) { - mVoiceRadioTechChangedRegistrants.notifyRegistrants( - new AsyncResult(null, ret, null)); - } - break; - - case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCdmaSubscriptionChangedRegistrants != null) { - mCdmaSubscriptionChangedRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOl_CDMA_PRL_CHANGED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mCdmaPrlChangedRegistrants != null) { - mCdmaPrlChangedRegistrants.notifyRegistrants( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mExitEmergencyCallbackModeRegistrants != null) { - mExitEmergencyCallbackModeRegistrants.notifyRegistrants( - new AsyncResult (null, null, null)); - } - break; - - case RIL_UNSOL_RIL_CONNECTED: { - if (RILJ_LOGD) unsljLogRet(response, ret); - - // Initial conditions - setRadioPower(false, null); - setPreferredNetworkType(mPreferredNetworkType, null); - setCdmaSubscriptionSource(mCdmaSubscription, null); - notifyRegistrantsRilConnectionChanged(((int[])ret)[0]); - break; - } - } - } - - /** - * Notifiy all registrants that the ril has connected or disconnected. - * - * @param rilVer is the version of the ril or -1 if disconnected. - */ - private void notifyRegistrantsRilConnectionChanged(int rilVer) { - mRilVersion = rilVer; - if (mRilConnectedRegistrants != null) { - mRilConnectedRegistrants.notifyRegistrants( - new AsyncResult (null, new Integer(rilVer), null)); - } - } - - private Object - responseInts(Parcel p) { - int numInts; - int response[]; - - numInts = p.readInt(); - - response = new int[numInts]; - - for (int i = 0 ; i < numInts ; i++) { - response[i] = p.readInt(); - } - - return response; - } - - - private Object - responseVoid(Parcel p) { - return null; - } - - private Object - responseCallForward(Parcel p) { - int numInfos; - CallForwardInfo infos[]; - - numInfos = p.readInt(); - - infos = new CallForwardInfo[numInfos]; - - for (int i = 0 ; i < numInfos ; i++) { - infos[i] = new CallForwardInfo(); - - infos[i].status = p.readInt(); - infos[i].reason = p.readInt(); - infos[i].serviceClass = p.readInt(); - infos[i].toa = p.readInt(); - infos[i].number = p.readString(); - infos[i].timeSeconds = p.readInt(); - } - - return infos; - } - - 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 - responseCdmaSms(Parcel p) { - SmsMessage sms; - sms = SmsMessage.newFromParcel(p); - - return sms; - } - - private Object - responseString(Parcel p) { - String response; - - response = p.readString(); - - return response; - } - - private Object - responseStrings(Parcel p) { - int num; - String response[]; - - response = p.readStringArray(); - - if (false) { - num = p.readInt(); - - response = new String[num]; - for (int i = 0; i < num; i++) { - response[i] = p.readString(); - } - } - - return response; - } - - private Object - responseRaw(Parcel p) { - int num; - byte response[]; - - response = p.createByteArray(); - - return response; - } - - private Object - responseSMS(Parcel p) { - int messageRef, errorCode; - String ackPDU; - - messageRef = p.readInt(); - ackPDU = p.readString(); - errorCode = p.readInt(); - - SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode); - - return response; - } - - - private Object - responseICC_IO(Parcel p) { - int sw1, sw2; - byte data[] = null; - Message ret; - - sw1 = p.readInt(); - sw2 = p.readInt(); - - String s = p.readString(); - - if (RILJ_LOGV) riljLog("< iccIO: " - + " 0x" + Integer.toHexString(sw1) - + " 0x" + Integer.toHexString(sw2) + " " - + s); - - return new IccIoResult(sw1, sw2, s); - } - - private Object - responseIccCardStatus(Parcel p) { - IccCardApplication ca; - - IccCardStatus status = new IccCardStatus(); - status.setCardState(p.readInt()); - status.setUniversalPinState(p.readInt()); - status.setGsmUmtsSubscriptionAppIndex(p.readInt()); - status.setCdmaSubscriptionAppIndex(p.readInt()); - status.setImsSubscriptionAppIndex(p.readInt()); - int numApplications = p.readInt(); - - // limit to maximum allowed applications - if (numApplications > IccCardStatus.CARD_MAX_APPS) { - numApplications = IccCardStatus.CARD_MAX_APPS; - } - status.setNumApplications(numApplications); - - for (int i = 0 ; i < numApplications ; i++) { - ca = new IccCardApplication(); - ca.app_type = ca.AppTypeFromRILInt(p.readInt()); - ca.app_state = ca.AppStateFromRILInt(p.readInt()); - ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt()); - ca.aid = p.readString(); - ca.app_label = p.readString(); - ca.pin1_replaced = p.readInt(); - ca.pin1 = ca.PinStateFromRILInt(p.readInt()); - ca.pin2 = ca.PinStateFromRILInt(p.readInt()); - status.addApplication(ca); - } - return status; - } - - private Object - responseSimRefresh(Parcel p) { - IccRefreshResponse response = new IccRefreshResponse(); - - response.refreshResult = p.readInt(); - response.efId = p.readInt(); - response.aid = p.readString(); - return response; - } - - private Object - responseCallList(Parcel p) { - int num; - int voiceSettings; - ArrayList response; - DriverCall dc; - - num = p.readInt(); - response = new ArrayList(num); - - if (RILJ_LOGV) { - riljLog("responseCallList: num=" + num + - " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant + - " mTestingEmergencyCall=" + mTestingEmergencyCall.get()); - } - 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(); - voiceSettings = p.readInt(); - dc.isVoice = (0 == voiceSettings) ? false : true; - dc.isVoicePrivacy = (0 != p.readInt()); - dc.number = p.readString(); - int np = p.readInt(); - dc.numberPresentation = DriverCall.presentationFromCLIP(np); - dc.name = p.readString(); - dc.namePresentation = p.readInt(); - int uusInfoPresent = p.readInt(); - if (uusInfoPresent == 1) { - dc.uusInfo = new UUSInfo(); - dc.uusInfo.setType(p.readInt()); - dc.uusInfo.setDcs(p.readInt()); - byte[] userData = p.createByteArray(); - dc.uusInfo.setUserData(userData); - riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d", - dc.uusInfo.getType(), dc.uusInfo.getDcs(), - dc.uusInfo.getUserData().length)); - riljLogv("Incoming UUS : data (string)=" - + new String(dc.uusInfo.getUserData())); - riljLogv("Incoming UUS : data (hex): " - + IccUtils.bytesToHexString(dc.uusInfo.getUserData())); - } else { - riljLogv("Incoming UUS : NOT present!"); - } - - // Make sure there's a leading + on addresses with a TOA of 145 - dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA); - - response.add(dc); - - if (dc.isVoicePrivacy) { - mVoicePrivacyOnRegistrants.notifyRegistrants(); - riljLog("InCall VoicePrivacy is enabled"); - } else { - mVoicePrivacyOffRegistrants.notifyRegistrants(); - riljLog("InCall VoicePrivacy is disabled"); - } - } - - Collections.sort(response); - - if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) { - if (mEmergencyCallbackModeRegistrant != null) { - riljLog("responseCallList: call ended, testing emergency call," + - " notify ECM Registrants"); - mEmergencyCallbackModeRegistrant.notifyRegistrant(); - } - } - - return response; - } - - private DataCallState getDataCallState(Parcel p, int version) { - DataCallState dataCall = new DataCallState(); - - dataCall.version = version; - if (version < 5) { - dataCall.cid = p.readInt(); - dataCall.active = p.readInt(); - dataCall.type = p.readString(); - String addresses = p.readString(); - if (!TextUtils.isEmpty(addresses)) { - dataCall.addresses = addresses.split(" "); - } - } else { - dataCall.status = p.readInt(); - dataCall.suggestedRetryTime = p.readInt(); - dataCall.cid = p.readInt(); - dataCall.active = p.readInt(); - dataCall.type = p.readString(); - dataCall.ifname = p.readString(); - if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) && - TextUtils.isEmpty(dataCall.ifname)) { - throw new RuntimeException("getDataCallState, no ifname"); - } - String addresses = p.readString(); - if (!TextUtils.isEmpty(addresses)) { - dataCall.addresses = addresses.split(" "); - } - String dnses = p.readString(); - if (!TextUtils.isEmpty(dnses)) { - dataCall.dnses = dnses.split(" "); - } - String gateways = p.readString(); - if (!TextUtils.isEmpty(gateways)) { - dataCall.gateways = gateways.split(" "); - } - } - return dataCall; - } - - private Object - responseDataCallList(Parcel p) { - ArrayList response; - - int ver = p.readInt(); - int num = p.readInt(); - riljLog("responseDataCallList ver=" + ver + " num=" + num); - - response = new ArrayList(num); - for (int i = 0; i < num; i++) { - response.add(getDataCallState(p, ver)); - } - - return response; - } - - private Object - responseSetupDataCall(Parcel p) { - int ver = p.readInt(); - int num = p.readInt(); - if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num); - - DataCallState dataCall; - - if (ver < 5) { - dataCall = new DataCallState(); - dataCall.version = ver; - dataCall.cid = Integer.parseInt(p.readString()); - dataCall.ifname = p.readString(); - if (TextUtils.isEmpty(dataCall.ifname)) { - throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response, no ifname"); - } - String addresses = p.readString(); - if (!TextUtils.isEmpty(addresses)) { - dataCall.addresses = addresses.split(" "); - } - if (num >= 4) { - String dnses = p.readString(); - if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses); - if (!TextUtils.isEmpty(dnses)) { - dataCall.dnses = dnses.split(" "); - } - } - if (num >= 5) { - String gateways = p.readString(); - if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways); - if (!TextUtils.isEmpty(gateways)) { - dataCall.gateways = gateways.split(" "); - } - } - } else { - if (num != 1) { - throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5" - + " got " + num); - } - dataCall = getDataCallState(p, ver); - } - - return dataCall; - } - - private Object - responseOperatorInfos(Parcel p) { - String strings[] = (String [])responseStrings(p); - ArrayList ret; - - if (strings.length % 4 != 0) { - throw new RuntimeException( - "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " - + strings.length + " strings, expected multible of 4"); - } - - ret = new ArrayList(strings.length / 4); - - for (int i = 0 ; i < strings.length ; i += 4) { - ret.add ( - new OperatorInfo( - strings[i+0], - strings[i+1], - strings[i+2], - strings[i+3])); - } - - return ret; - } - - private Object - responseCellList(Parcel p) { - int num, rssi; - String location; - ArrayList response; - NeighboringCellInfo cell; - - num = p.readInt(); - response = new ArrayList(); - - // Determine the radio access type - String radioString = SystemProperties.get( - TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown"); - int radioType; - if (radioString.equals("GPRS")) { - radioType = NETWORK_TYPE_GPRS; - } else if (radioString.equals("EDGE")) { - radioType = NETWORK_TYPE_EDGE; - } else if (radioString.equals("UMTS")) { - radioType = NETWORK_TYPE_UMTS; - } else if (radioString.equals("HSDPA")) { - radioType = NETWORK_TYPE_HSDPA; - } else if (radioString.equals("HSUPA")) { - radioType = NETWORK_TYPE_HSUPA; - } else if (radioString.equals("HSPA")) { - radioType = NETWORK_TYPE_HSPA; - } else { - radioType = NETWORK_TYPE_UNKNOWN; - } - - // Interpret the location based on radio access type - if (radioType != NETWORK_TYPE_UNKNOWN) { - for (int i = 0 ; i < num ; i++) { - rssi = p.readInt(); - location = p.readString(); - cell = new NeighboringCellInfo(rssi, location, radioType); - response.add(cell); - } - } - return response; - } - - private Object responseGetPreferredNetworkType(Parcel p) { - int [] response = (int[]) responseInts(p); - - if (response.length >= 1) { - // Since this is the response for getPreferredNetworkType - // we'll assume that it should be the value we want the - // vendor ril to take if we reestablish a connection to it. - mPreferredNetworkType = response[0]; - } - return response; - } - - private Object responseGmsBroadcastConfig(Parcel p) { - int num; - ArrayList response; - SmsBroadcastConfigInfo info; - - num = p.readInt(); - response = new ArrayList(num); - - for (int i = 0; i < num; i++) { - int fromId = p.readInt(); - int toId = p.readInt(); - int fromScheme = p.readInt(); - int toScheme = p.readInt(); - boolean selected = (p.readInt() == 1); - - info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme, - toScheme, selected); - response.add(info); - } - return response; - } - - private Object - responseCdmaBroadcastConfig(Parcel p) { - int numServiceCategories; - int response[]; - - numServiceCategories = p.readInt(); - - if (numServiceCategories == 0) { - // TODO: The logic of providing default values should - // not be done by this transport layer. And needs to - // be done by the vendor ril or application logic. - int numInts; - numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1; - response = new int[numInts]; - - // Faking a default record for all possible records. - response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES; - - // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as - // default language and selection status to false for all. - for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) { - response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT; - response[i + 1] = 1; - response[i + 2] = 0; - } - } else { - int numInts; - numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1; - response = new int[numInts]; - - response[0] = numServiceCategories; - for (int i = 1 ; i < numInts; i++) { - response[i] = p.readInt(); - } - } - - return response; - } - - private Object - responseSignalStrength(Parcel p) { - int numInts = 12; - int response[]; - - /* TODO: Add SignalStrength class to match RIL_SignalStrength */ - response = new int[numInts]; - for (int i = 0 ; i < numInts ; i++) { - response[i] = p.readInt(); - } - - return response; - } - - private ArrayList - responseCdmaInformationRecord(Parcel p) { - int numberOfInfoRecs; - ArrayList response; - - /** - * Loop through all of the information records unmarshalling them - * and converting them to Java Objects. - */ - numberOfInfoRecs = p.readInt(); - response = new ArrayList(numberOfInfoRecs); - - for (int i = 0; i < numberOfInfoRecs; i++) { - CdmaInformationRecords InfoRec = new CdmaInformationRecords(p); - response.add(InfoRec); - } - - return response; - } - - private Object - responseCdmaCallWaiting(Parcel p) { - CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification(); - - notification.number = p.readString(); - notification.numberPresentation = notification.presentationFromCLIP(p.readInt()); - notification.name = p.readString(); - notification.namePresentation = notification.numberPresentation; - notification.isPresent = p.readInt(); - notification.signalType = p.readInt(); - notification.alertPitch = p.readInt(); - notification.signal = p.readInt(); - notification.numberType = p.readInt(); - notification.numberPlan = p.readInt(); - - return notification; - } - - private Object - responseCallRing(Parcel p){ - char response[] = new char[4]; - - response[0] = (char) p.readInt(); // isPresent - response[1] = (char) p.readInt(); // signalType - response[2] = (char) p.readInt(); // alertPitch - response[3] = (char) p.readInt(); // signal - - return response; - } - - private void - notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) { - int response = RIL_UNSOL_CDMA_INFO_REC; - if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) { - if (mDisplayInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mDisplayInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) { - if (mSignalInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mSignalInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) { - if (mNumberInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mNumberInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) { - if (mRedirNumInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mRedirNumInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) { - if (mLineControlInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mLineControlInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) { - if (mT53ClirInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mT53ClirInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) { - if (mT53AudCntrlInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.record); - mT53AudCntrlInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.record, null)); - } - } - } - - static String - requestToString(int request) { -/* - cat libs/telephony/ril_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' -*/ - switch(request) { - 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"; - case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2"; - 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"; - 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"; - case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; - case RIL_REQUEST_HANGUP: return "HANGUP"; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND"; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND"; - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"; - case RIL_REQUEST_CONFERENCE: return "CONFERENCE"; - case RIL_REQUEST_UDUB: return "UDUB"; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE"; - case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH"; - case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE"; - case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE"; - case RIL_REQUEST_OPERATOR: return "OPERATOR"; - case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER"; - 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_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"; - case RIL_REQUEST_GET_CLIR: return "GET_CLIR"; - case RIL_REQUEST_SET_CLIR: return "SET_CLIR"; - case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS"; - case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD"; - case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING"; - case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING"; - case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE"; - 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_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"; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS "; - case RIL_REQUEST_DTMF_START: return "DTMF_START"; - case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; - case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; - case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; - 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_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"; - case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; - case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; - case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; - case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; - case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; - case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; - case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE"; - case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE"; - case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND"; - case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE"; - case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; - case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER"; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS"; - case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES"; - case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE"; - case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE"; - case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE"; - case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE"; - case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE"; - case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH"; - case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF"; - case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS"; - case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE"; - case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG"; - case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG"; - case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG"; - case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG"; - case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION"; - case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY"; - case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION"; - 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"; - case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY"; - case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS"; - case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS"; - case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE"; - case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS"; - case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING"; - case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE"; - case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION"; - case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; - case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS"; - case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH"; - default: return ""; - } - } - - static String - responseToString(int request) - { -/* - cat libs/telephony/ril_unsol_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' -*/ - switch(request) { - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS"; - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; - case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; - case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; - case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; - case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; - case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; - case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; - case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; - case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; - case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; - case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; - case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; - case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; - case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; - case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; - case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; - case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED"; - case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; - case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING"; - case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; - case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; - case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; - case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG"; - case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; - case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED"; - case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED"; - case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE"; - case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; - case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; - default: return ""; - } - } - - private void riljLog(String msg) { - Log.d(LOG_TAG, msg); - } - - private void riljLogv(String msg) { - Log.v(LOG_TAG, msg); - } - - private void unsljLog(int response) { - riljLog("[UNSL]< " + responseToString(response)); - } - - private void unsljLogMore(int response, String more) { - riljLog("[UNSL]< " + responseToString(response) + " " + more); - } - - private void unsljLogRet(int response, Object ret) { - riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); - } - - private void unsljLogvRet(int response, Object ret) { - riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); - } - - - // ***** Methods for CDMA support - public void - getDeviceIdentity(Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getCDMASubscription(Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - @Override - public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor - if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType); - mPhoneType = phoneType; - } - - /** - * {@inheritDoc} - */ - public void queryCdmaRoamingPreference(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(cdmaRoamingType); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + cdmaRoamingType); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(cdmaSubscription); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + cdmaSubscription); - - send(rr); - } - - /** - * {@inheritDoc} - */ - @Override - public void getCdmaSubscriptionSource(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void queryTTYMode(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setTTYMode(int ttyMode, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_SET_TTY_MODE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(ttyMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + ttyMode); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void - sendCDMAFeatureCode(String FeatureCode, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response); - - rr.mp.writeString(FeatureCode); - - if (RILJ_LOGD) 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); - } - - // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig - public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response); - - for(int i = 0; i < configValuesArray.length; i++) { - rr.mp.writeInt(configValuesArray[i]); - } - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void setCdmaBroadcastActivation(boolean activate, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(activate ? 0 :1); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void exitEmergencyCallbackMode(Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void requestIsimAuthentication(String nonce, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response); - - rr.mp.writeString(nonce); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /* (non-Javadoc) - * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall() - */ - @Override - public void testingEmergencyCall() { - if (RILJ_LOGD) riljLog("testingEmergencyCall"); - mTestingEmergencyCall.set(true); - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("RIL:"); - pw.println(" mSocket=" + mSocket); - pw.println(" mSenderThread=" + mSenderThread); - pw.println(" mSender=" + mSender); - pw.println(" mReceiverThread=" + mReceiverThread); - pw.println(" mReceiver=" + mReceiver); - pw.println(" mWakeLock=" + mWakeLock); - pw.println(" mWakeLockTimeout=" + mWakeLockTimeout); - synchronized (mRequestsList) { - pw.println(" mRequestMessagesPending=" + mRequestMessagesPending); - pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting); - int count = mRequestsList.size(); - pw.println(" mRequestList count=" + count); - for (int i = 0; i < count; i++) { - RILRequest rr = mRequestsList.get(i); - pw.println(" [" + rr.mSerial + "] " + requestToString(rr.mRequest)); - } - } - pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo); - pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get()); - } -} diff --git a/telephony/java/com/android/internal/telephony/RestrictedState.java b/telephony/java/com/android/internal/telephony/RestrictedState.java deleted file mode 100644 index ad2b88d584da..000000000000 --- a/telephony/java/com/android/internal/telephony/RestrictedState.java +++ /dev/null @@ -1,122 +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; - -import android.telephony.ServiceState; - -public class RestrictedState { - - /** - * Set true to block packet data access due to restriction - */ - private boolean mPsRestricted; - /** - * Set true to block all normal voice/SMS/USSD/SS/AV64 due to restriction - */ - private boolean mCsNormalRestricted; - /** - * Set true to block emergency call due to restriction - */ - private boolean mCsEmergencyRestricted; - - public RestrictedState() { - setPsRestricted(false); - setCsNormalRestricted(false); - setCsEmergencyRestricted(false); - } - - /** - * @param csEmergencyRestricted the csEmergencyRestricted to set - */ - public void setCsEmergencyRestricted(boolean csEmergencyRestricted) { - mCsEmergencyRestricted = csEmergencyRestricted; - } - - /** - * @return the csEmergencyRestricted - */ - public boolean isCsEmergencyRestricted() { - return mCsEmergencyRestricted; - } - - /** - * @param csNormalRestricted the csNormalRestricted to set - */ - public void setCsNormalRestricted(boolean csNormalRestricted) { - mCsNormalRestricted = csNormalRestricted; - } - - /** - * @return the csNormalRestricted - */ - public boolean isCsNormalRestricted() { - return mCsNormalRestricted; - } - - /** - * @param psRestricted the psRestricted to set - */ - public void setPsRestricted(boolean psRestricted) { - mPsRestricted = psRestricted; - } - - /** - * @return the psRestricted - */ - public boolean isPsRestricted() { - return mPsRestricted; - } - - public boolean isCsRestricted() { - return mCsNormalRestricted && mCsEmergencyRestricted; - } - - @Override - public boolean equals (Object o) { - RestrictedState s; - - try { - s = (RestrictedState) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } - - return mPsRestricted == s.mPsRestricted - && mCsNormalRestricted == s.mCsNormalRestricted - && mCsEmergencyRestricted == s.mCsEmergencyRestricted; - } - - @Override - public String toString() { - String csString = "none"; - - if (mCsEmergencyRestricted && mCsNormalRestricted) { - csString = "all"; - } else if (mCsEmergencyRestricted && !mCsNormalRestricted) { - csString = "emergency"; - } else if (!mCsEmergencyRestricted && mCsNormalRestricted) { - csString = "normal call"; - } - - return "Restricted State CS: " + csString + " PS:" + mPsRestricted; - } - -} diff --git a/telephony/java/com/android/internal/telephony/RetryManager.java b/telephony/java/com/android/internal/telephony/RetryManager.java deleted file mode 100644 index ae451b92850a..000000000000 --- a/telephony/java/com/android/internal/telephony/RetryManager.java +++ /dev/null @@ -1,404 +0,0 @@ -/** - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.util.Log; -import android.util.Pair; -import android.text.TextUtils; - -import java.util.Random; -import java.util.ArrayList; - -/** - * Retry manager allows a simple way to declare a series of - * retry timeouts. After creating a RetryManager the configure - * method is used to define the sequence. A simple linear series - * may be initialized using configure with three integer parameters - * The other configure method allows a series to be declared using - * a string. - *

- * The format of the configuration string is a series of parameters - * separated by a comma. There are two name value pair parameters plus a series - * of delay times. The units of of these delay times is unspecified. - * The name value pairs which may be specified are: - *

    - *
  • max_retries= - *
  • default_randomizationTime= - *
- *

- * max_retries is the number of times that incrementRetryCount - * maybe called before isRetryNeeded will return false. if value - * is infinite then isRetryNeeded will always return true. - * - * default_randomizationTime will be used as the randomizationTime - * for delay times which have no supplied randomizationTime. If - * default_randomizationTime is not defined it defaults to 0. - *

- * The other parameters define The series of delay times and each - * may have an optional randomization value separated from the - * delay time by a colon. - *

- * Examples: - *

    - *
  • 3 retries with no randomization value which means its 0: - *
    • "1000, 2000, 3000"
    - * - *
  • 10 retries with a 500 default randomization value for each and - * the 4..10 retries all using 3000 as the delay: - *
    • "max_retries=10, default_randomization=500, 1000, 2000, 3000"
    - * - *
  • 4 retries with a 100 as the default randomization value for the first 2 values and - * the other two having specified values of 500: - *
    • "default_randomization=100, 1000, 2000, 4000:500, 5000:500"
    - * - *
  • Infinite number of retries with the first one at 1000, the second at 2000 all - * others will be at 3000. - *
    • "max_retries=infinite,1000,2000,3000
    - *
- * - * {@hide} - */ -public class RetryManager { - static public final String LOG_TAG = "RetryManager"; - static public final boolean DBG = true; - static public final boolean VDBG = false; - - /** - * Retry record with times in milli-seconds - */ - private static class RetryRec { - RetryRec(int delayTime, int randomizationTime) { - mDelayTime = delayTime; - mRandomizationTime = randomizationTime; - } - - int mDelayTime; - int mRandomizationTime; - } - - /** The array of retry records */ - private ArrayList mRetryArray = new ArrayList(); - - /** When true isRetryNeeded() will always return true */ - private boolean mRetryForever; - - /** - * The maximum number of retries to attempt before - * isRetryNeeded returns false - */ - private int mMaxRetryCount; - - /** The current number of retries */ - private int mRetryCount; - - /** Random number generator */ - private Random rng = new Random(); - - private String mConfig; - - /** Constructor */ - public RetryManager() { - if (VDBG) log("constructor"); - } - - public String toString() { - String ret = "RetryManager: forever=" + mRetryForever + ", maxRetry=" + mMaxRetryCount + - ", retry=" + mRetryCount + ",\n " + mConfig; - for (RetryRec r : mRetryArray) { - ret += "\n " + r.mDelayTime + ":" + r.mRandomizationTime; - } - return ret; - } - - /** - * Configure for a simple linear sequence of times plus - * a random value. - * - * @param maxRetryCount is the maximum number of retries - * before isRetryNeeded returns false. - * @param retryTime is a time that will be returned by getRetryTime. - * @param randomizationTime a random value between 0 and - * randomizationTime will be added to retryTime. this - * parameter may be 0. - * @return true if successful - */ - public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) { - Pair value; - - if (VDBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime); - - if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) { - return false; - } - - if (!validateNonNegativeInt("retryTime", retryTime)) { - return false; - } - - if (!validateNonNegativeInt("randomizationTime", randomizationTime)) { - return false; - } - - mMaxRetryCount = maxRetryCount; - resetRetryCount(); - mRetryArray.clear(); - mRetryArray.add(new RetryRec(retryTime, randomizationTime)); - - return true; - } - - /** - * Configure for using string which allow arbitrary - * sequences of times. See class comments for the - * string format. - * - * @return true if successful - */ - public boolean configure(String configStr) { - // Strip quotes if present. - if ((configStr.startsWith("\"") && configStr.endsWith("\""))) { - configStr = configStr.substring(1, configStr.length()-1); - } - if (VDBG) log("configure: '" + configStr + "'"); - mConfig = configStr; - - if (!TextUtils.isEmpty(configStr)) { - int defaultRandomization = 0; - - if (VDBG) log("configure: not empty"); - - mMaxRetryCount = 0; - resetRetryCount(); - mRetryArray.clear(); - - String strArray[] = configStr.split(","); - for (int i = 0; i < strArray.length; i++) { - if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'"); - Pair value; - String splitStr[] = strArray[i].split("=", 2); - splitStr[0] = splitStr[0].trim(); - if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'"); - if (splitStr.length > 1) { - splitStr[1] = splitStr[1].trim(); - if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'"); - if (TextUtils.equals(splitStr[0], "default_randomization")) { - value = parseNonNegativeInt(splitStr[0], splitStr[1]); - if (!value.first) return false; - defaultRandomization = value.second; - } else if (TextUtils.equals(splitStr[0], "max_retries")) { - if (TextUtils.equals("infinite",splitStr[1])) { - mRetryForever = true; - } else { - value = parseNonNegativeInt(splitStr[0], splitStr[1]); - if (!value.first) return false; - mMaxRetryCount = value.second; - } - } else { - Log.e(LOG_TAG, "Unrecognized configuration name value pair: " - + strArray[i]); - return false; - } - } else { - /** - * Assume a retry time with an optional randomization value - * following a ":" - */ - splitStr = strArray[i].split(":", 2); - splitStr[0] = splitStr[0].trim(); - RetryRec rr = new RetryRec(0, 0); - value = parseNonNegativeInt("delayTime", splitStr[0]); - if (!value.first) return false; - rr.mDelayTime = value.second; - - // Check if optional randomization value present - if (splitStr.length > 1) { - splitStr[1] = splitStr[1].trim(); - if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'"); - value = parseNonNegativeInt("randomizationTime", splitStr[1]); - if (!value.first) return false; - rr.mRandomizationTime = value.second; - } else { - rr.mRandomizationTime = defaultRandomization; - } - mRetryArray.add(rr); - } - } - if (mRetryArray.size() > mMaxRetryCount) { - mMaxRetryCount = mRetryArray.size(); - if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount); - } - if (VDBG) log("configure: true"); - return true; - } else { - if (VDBG) log("configure: false it's empty"); - return false; - } - } - - /** - * Report whether data reconnection should be retried - * - * @return {@code true} if the max retries has not been reached. {@code - * false} otherwise. - */ - public boolean isRetryNeeded() { - boolean retVal = mRetryForever || (mRetryCount < mMaxRetryCount); - if (DBG) log("isRetryNeeded: " + retVal); - return retVal; - } - - /** - * Return the timer that should be used to trigger the data reconnection - */ - public int getRetryTimer() { - int index; - if (mRetryCount < mRetryArray.size()) { - index = mRetryCount; - } else { - index = mRetryArray.size() - 1; - } - - int retVal; - if ((index >= 0) && (index < mRetryArray.size())) { - retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index); - } else { - retVal = 0; - } - - if (DBG) log("getRetryTimer: " + retVal); - return retVal; - } - - /** - * @return retry count - */ - public int getRetryCount() { - if (DBG) log("getRetryCount: " + mRetryCount); - return mRetryCount; - } - - /** - * Increase the retry counter, does not change retry forever. - */ - public void increaseRetryCount() { - mRetryCount++; - if (mRetryCount > mMaxRetryCount) { - mRetryCount = mMaxRetryCount; - } - if (DBG) log("increaseRetryCount: " + mRetryCount); - } - - /** - * Set retry count to the specified value - * and turns off retrying forever. - */ - public void setRetryCount(int count) { - mRetryCount = count; - if (mRetryCount > mMaxRetryCount) { - mRetryCount = mMaxRetryCount; - } - - if (mRetryCount < 0) { - mRetryCount = 0; - } - - mRetryForever = false; - if (DBG) log("setRetryCount: " + mRetryCount); - } - - /** - * Clear the data-retry counter - */ - public void resetRetryCount() { - mRetryCount = 0; - if (DBG) log("resetRetryCount: " + mRetryCount); - } - - /** - * Retry forever using last timeout time. - */ - public void retryForeverUsingLastTimeout() { - mRetryCount = mMaxRetryCount; - mRetryForever = true; - if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount); - } - - /** - * @return true if retrying forever - */ - public boolean isRetryForever() { - if (DBG) log("isRetryForever: " + mRetryForever); - return mRetryForever; - } - - /** - * Parse an integer validating the value is not negative. - * - * @param name - * @param stringValue - * @return Pair.first == true if stringValue an integer >= 0 - */ - private Pair parseNonNegativeInt(String name, String stringValue) { - int value; - Pair retVal; - try { - value = Integer.parseInt(stringValue); - retVal = new Pair(validateNonNegativeInt(name, value), value); - } catch (NumberFormatException e) { - Log.e(LOG_TAG, name + " bad value: " + stringValue, e); - retVal = new Pair(false, 0); - } - if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", " - + retVal.first + ", " + retVal.second); - return retVal; - } - - /** - * Validate an integer is >= 0 and logs an error if not - * - * @param name - * @param value - * @return Pair.first - */ - private boolean validateNonNegativeInt(String name, int value) { - boolean retVal; - if (value < 0) { - Log.e(LOG_TAG, name + " bad value: is < 0"); - retVal = false; - } else { - retVal = true; - } - if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal); - return retVal; - } - - /** - * Return next random number for the index - */ - private int nextRandomizationTime(int index) { - int randomTime = mRetryArray.get(index).mRandomizationTime; - if (randomTime == 0) { - return 0; - } else { - return rng.nextInt(randomTime); - } - } - - private void log(String s) { - Log.d(LOG_TAG, s); - } -} diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java deleted file mode 100644 index 41125dd119bd..000000000000 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ /dev/null @@ -1,1251 +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; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.app.PendingIntent.CanceledException; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.database.Cursor; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Binder; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.SystemProperties; -import android.provider.Telephony; -import android.provider.Telephony.Sms.Intents; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.SmsCbMessage; -import android.telephony.SmsMessage; -import android.telephony.TelephonyManager; -import android.text.Html; -import android.text.Spanned; -import android.util.Log; -import android.view.WindowManager; - -import com.android.internal.R; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; -import com.android.internal.util.HexDump; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Random; - -import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; -import static android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE; -import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; -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 { - static final String TAG = "SMS"; // accessed from inner class - private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg"; - - /** Permission required to receive SMS and SMS-CB messages. */ - public static final String RECEIVE_SMS_PERMISSION = "android.permission.RECEIVE_SMS"; - - /** Permission required to receive ETWS and CMAS emergency broadcasts. */ - public static final String RECEIVE_EMERGENCY_BROADCAST_PERMISSION = - "android.permission.RECEIVE_EMERGENCY_BROADCAST"; - - /** Permission required to send SMS to short codes without user confirmation. */ - private static final String SEND_SMS_NO_CONFIRMATION_PERMISSION = - "android.permission.SEND_SMS_NO_CONFIRMATION"; - - /** Query projection for checking for duplicate message segments. */ - private static final String[] PDU_PROJECTION = new String[] { - "pdu" - }; - - /** Query projection for combining concatenated message segments. */ - private static final String[] PDU_SEQUENCE_PORT_PROJECTION = new String[] { - "pdu", - "sequence", - "destination_port" - }; - - private static final int PDU_COLUMN = 0; - private static final int SEQUENCE_COLUMN = 1; - private static final int DESTINATION_PORT_COLUMN = 2; - - /** New SMS received. */ - protected static final int EVENT_NEW_SMS = 1; - - /** SMS send complete. */ - protected static final int EVENT_SEND_SMS_COMPLETE = 2; - - /** Retry sending a previously failed SMS message */ - private static final int EVENT_SEND_RETRY = 3; - - /** Confirmation required for sending a large number of messages. */ - private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4; - - /** Send the user confirmed SMS */ - static final int EVENT_SEND_CONFIRMED_SMS = 5; // accessed from inner class - - /** Don't send SMS (user did not confirm). */ - static final int EVENT_STOP_SENDING = 7; // accessed from inner class - - /** Confirmation required for third-party apps sending to an SMS short code. */ - private static final int EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE = 8; - - /** Confirmation required for third-party apps sending to an SMS short code. */ - private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9; - - protected final Phone mPhone; - protected final Context mContext; - protected final ContentResolver mResolver; - protected final CommandsInterface mCm; - protected final SmsStorageMonitor mStorageMonitor; - protected final TelephonyManager mTelephonyManager; - - protected final WapPushOverSms mWapPush; - - protected static 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; - /** single part SMS */ - private static final int SINGLE_PART_SMS = 1; - /** Message sending queue limit */ - private static final int MO_MSG_QUEUE_LIMIT = 5; - - /** - * Message reference for a CONCATENATED_8_BIT_REFERENCE or - * CONCATENATED_16_BIT_REFERENCE message set. Should be - * incremented for each set of concatenated messages. - * Static field shared by all dispatcher objects. - */ - private static int sConcatenatedRef = new Random().nextInt(256); - - /** Outgoing message counter. Shared by all dispatchers. */ - private final SmsUsageMonitor mUsageMonitor; - - /** Number of outgoing SmsTrackers waiting for user confirmation. */ - private int mPendingTrackerCount; - - /** Wake lock to ensure device stays awake while dispatching the SMS intent. */ - private PowerManager.WakeLock mWakeLock; - - /** - * Hold the wake lock for 5 seconds, which should be enough time for - * any receiver(s) to grab its own wake lock. - */ - private static final int WAKE_LOCK_TIMEOUT = 5000; - - /* Flags indicating whether the current device allows sms service */ - protected boolean mSmsCapable = true; - protected boolean mSmsReceiveDisabled; - protected boolean mSmsSendDisabled; - - protected int mRemainingMessages = -1; - - protected static int getNextConcatenatedRef() { - sConcatenatedRef += 1; - return sConcatenatedRef; - } - - /** - * Create a new SMS dispatcher. - * @param phone the Phone to use - * @param storageMonitor the SmsStorageMonitor to use - * @param usageMonitor the SmsUsageMonitor to use - */ - protected SMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor, - SmsUsageMonitor usageMonitor) { - mPhone = phone; - mWapPush = new WapPushOverSms(phone, this); - mContext = phone.getContext(); - mResolver = mContext.getContentResolver(); - mCm = phone.mCM; - mStorageMonitor = storageMonitor; - mUsageMonitor = usageMonitor; - mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - - createWakelock(); - - mSmsCapable = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sms_capable); - mSmsReceiveDisabled = !SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_SMS_RECEIVE, mSmsCapable); - mSmsSendDisabled = !SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_SMS_SEND, mSmsCapable); - Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat() - + " mSmsReceiveDisabled=" + mSmsReceiveDisabled - + " mSmsSendDisabled=" + mSmsSendDisabled); - } - - /** Unregister for incoming SMS events. */ - public abstract void dispose(); - - /** - * The format of the message PDU in the associated broadcast intent. - * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format - * or "3gpp2" for CDMA/LTE messages in 3GPP2 format. - * - * Note: All applications which handle incoming SMS messages by processing the - * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent - * into the new methods in {@link android.telephony.SmsMessage} which take an - * extra format parameter. This is required in order to correctly decode the PDU on - * devices which require support for both 3GPP and 3GPP2 formats at the same time, - * such as CDMA/LTE devices and GSM/CDMA world phones. - * - * @return the format of the message PDU - */ - protected abstract String getFormat(); - - @Override - 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. */ - protected final ArrayList deliveryPendingList = new ArrayList(); - - /** - * 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 (false) { - Log.d(TAG, "New SMS Message Received"); - } - - SmsMessage sms; - - ar = (AsyncResult) msg.obj; - - if (ar.exception != null) { - Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception); - return; - } - - sms = (SmsMessage) ar.result; - try { - int result = dispatchMessage(sms.mWrappedSmsMessage); - if (result != Activity.RESULT_OK) { - // RESULT_OK means that message was broadcast for app(s) to handle. - // Any other result, we should ack here. - boolean handled = (result == Intents.RESULT_SMS_HANDLED); - notifyAndAcknowledgeLastIncomingSms(handled, result, null); - } - } catch (RuntimeException ex) { - Log.e(TAG, "Exception dispatching message", ex); - notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); - } - - break; - - case EVENT_SEND_SMS_COMPLETE: - // An outbound SMS has been successfully transferred, or failed. - handleSendComplete((AsyncResult) msg.obj); - break; - - case EVENT_SEND_RETRY: - sendSms((SmsTracker) msg.obj); - break; - - case EVENT_SEND_LIMIT_REACHED_CONFIRMATION: - handleReachSentLimit((SmsTracker)(msg.obj)); - break; - - case EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE: - handleConfirmShortCode(false, (SmsTracker)(msg.obj)); - break; - - case EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE: - handleConfirmShortCode(true, (SmsTracker)(msg.obj)); - break; - - case EVENT_SEND_CONFIRMED_SMS: - { - SmsTracker tracker = (SmsTracker) msg.obj; - if (tracker.isMultipart()) { - sendMultipartSms(tracker); - } else { - sendSms(tracker); - } - mPendingTrackerCount--; - break; - } - - case EVENT_STOP_SENDING: - { - SmsTracker tracker = (SmsTracker) msg.obj; - if (tracker.mSentIntent != null) { - try { - tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED); - } catch (CanceledException ex) { - Log.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED"); - } - } - mPendingTrackerCount--; - break; - } - } - } - - private void createWakelock() { - PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SMSDispatcher"); - mWakeLock.setReferenceCounted(true); - } - - /** - * Grabs a wake lock and sends intent as an ordered broadcast. - * The resultReceiver will check for errors and ACK/NACK back - * to the RIL. - * - * @param intent intent to broadcast - * @param permission Receivers are required to have this permission - */ - public void dispatch(Intent intent, String permission) { - // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any - // receivers time to take their own wake locks. - mWakeLock.acquire(WAKE_LOCK_TIMEOUT); - mContext.sendOrderedBroadcast(intent, permission, mResultReceiver, - this, Activity.RESULT_OK, null, null); - } - - /** - * Called when 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. - */ - protected void handleSendComplete(AsyncResult ar) { - SmsTracker tracker = (SmsTracker) ar.userObj; - PendingIntent sentIntent = tracker.mSentIntent; - - if (ar.exception == null) { - if (false) { - 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 { - if (mRemainingMessages > -1) { - mRemainingMessages--; - } - - if (mRemainingMessages == 0) { - Intent sendNext = new Intent(); - sendNext.putExtra(SEND_NEXT_MSG_EXTRA, true); - sentIntent.send(mContext, Activity.RESULT_OK, sendNext); - } else { - sentIntent.send(Activity.RESULT_OK); - } - } catch (CanceledException ex) {} - } - } else { - if (false) { - Log.d(TAG, "SMS send failed"); - } - - int ss = mPhone.getServiceState().getState(); - - if (ss != ServiceState.STATE_IN_SERVICE) { - handleNotInService(ss, tracker.mSentIntent); - } 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) { - int error = RESULT_ERROR_GENERIC_FAILURE; - - if (((CommandException)(ar.exception)).getCommandError() - == CommandException.Error.FDN_CHECK_FAILURE) { - error = RESULT_ERROR_FDN_CHECK_FAILURE; - } - // Done retrying; return an error to the app. - try { - Intent fillIn = new Intent(); - if (ar.result != null) { - fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode); - } - if (mRemainingMessages > -1) { - mRemainingMessages--; - } - - if (mRemainingMessages == 0) { - fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true); - } - - tracker.mSentIntent.send(mContext, error, fillIn); - } 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 sentIntent the PendingIntent to send the error to - */ - protected static void handleNotInService(int ss, PendingIntent sentIntent) { - if (sentIntent != null) { - try { - if (ss == ServiceState.STATE_POWER_OFF) { - sentIntent.send(RESULT_ERROR_RADIO_OFF); - } else { - sentIntent.send(RESULT_ERROR_NO_SERVICE); - } - } catch (CanceledException ex) {} - } - } - - /** - * Dispatches an incoming SMS messages. - * - * @param sms the incoming message from the phone - * @return a result code from {@link Telephony.Sms.Intents}, or - * {@link Activity#RESULT_OK} if the message has been broadcast - * to applications - */ - public abstract int dispatchMessage(SmsMessageBase sms); - - /** - * Dispatch a normal incoming SMS. This is called from the format-specific - * {@link #dispatchMessage(SmsMessageBase)} if no format-specific handling is required. - * - * @param sms - * @return - */ - protected int dispatchNormalMessage(SmsMessageBase sms) { - SmsHeader smsHeader = sms.getUserDataHeader(); - - // See if message is partial or port addressed. - if ((smsHeader == null) || (smsHeader.concatRef == null)) { - // Message is not partial (not part of concatenated sequence). - byte[][] pdus = new byte[1][]; - pdus[0] = sms.getPdu(); - - if (smsHeader != null && smsHeader.portAddrs != null) { - if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { - // GSM-style WAP indication - return mWapPush.dispatchWapPdu(sms.getUserData()); - } else { - // The message was sent to a port, so concoct a URI for it. - dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); - } - } else { - // Normal short and non-port-addressed message, dispatch it. - dispatchPdus(pdus); - } - return Activity.RESULT_OK; - } else { - // Process the message part. - SmsHeader.ConcatRef concatRef = smsHeader.concatRef; - SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs; - return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(), - concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, - sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort : -1), false); - } - } - - /** - * If this is the last part send the parts out to the application, otherwise - * the part is stored for later processing. Handles both 3GPP concatenated messages - * as well as 3GPP2 format WAP push messages processed by - * {@link com.android.internal.telephony.cdma.CdmaSMSDispatcher#processCdmaWapPdu}. - * - * @param pdu the message PDU, or the datagram portion of a CDMA WDP datagram segment - * @param address the originating address - * @param referenceNumber distinguishes concatenated messages from the same sender - * @param sequenceNumber the order of this segment in the message - * (starting at 0 for CDMA WDP datagrams and 1 for concatenated messages). - * @param messageCount the number of segments in the message - * @param timestamp the service center timestamp in millis - * @param destPort the destination port for the message, or -1 for no destination port - * @param isCdmaWapPush true if pdu is a CDMA WDP datagram segment and not an SM PDU - * - * @return a result code from {@link Telephony.Sms.Intents}, or - * {@link Activity#RESULT_OK} if the message has been broadcast - * to applications - */ - protected int processMessagePart(byte[] pdu, String address, int referenceNumber, - int sequenceNumber, int messageCount, long timestamp, int destPort, - boolean isCdmaWapPush) { - byte[][] pdus = null; - Cursor cursor = null; - try { - // used by several query selection arguments - String refNumber = Integer.toString(referenceNumber); - String seqNumber = Integer.toString(sequenceNumber); - - // Check for duplicate message segment - cursor = mResolver.query(mRawUri, PDU_PROJECTION, - "address=? AND reference_number=? AND sequence=?", - new String[] {address, refNumber, seqNumber}, null); - - // moveToNext() returns false if no duplicates were found - if (cursor.moveToNext()) { - Log.w(TAG, "Discarding duplicate message segment from address=" + address - + " refNumber=" + refNumber + " seqNumber=" + seqNumber); - String oldPduString = cursor.getString(PDU_COLUMN); - byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString); - if (!Arrays.equals(oldPdu, pdu)) { - Log.e(TAG, "Warning: dup message segment PDU of length " + pdu.length - + " is different from existing PDU of length " + oldPdu.length); - } - return Intents.RESULT_SMS_HANDLED; - } - cursor.close(); - - // not a dup, query for all other segments of this concatenated message - String where = "address=? AND reference_number=?"; - String[] whereArgs = new String[] {address, refNumber}; - cursor = mResolver.query(mRawUri, PDU_SEQUENCE_PORT_PROJECTION, where, whereArgs, null); - - int cursorCount = cursor.getCount(); - if (cursorCount != messageCount - 1) { - // We don't have all the parts yet, store this one away - ContentValues values = new ContentValues(); - values.put("date", timestamp); - values.put("pdu", HexDump.toHexString(pdu)); - values.put("address", address); - values.put("reference_number", referenceNumber); - values.put("count", messageCount); - values.put("sequence", sequenceNumber); - if (destPort != -1) { - values.put("destination_port", destPort); - } - mResolver.insert(mRawUri, values); - return Intents.RESULT_SMS_HANDLED; - } - - // All the parts are in place, deal with them - pdus = new byte[messageCount][]; - for (int i = 0; i < cursorCount; i++) { - cursor.moveToNext(); - int cursorSequence = cursor.getInt(SEQUENCE_COLUMN); - // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0 - if (!isCdmaWapPush) { - cursorSequence--; - } - pdus[cursorSequence] = HexDump.hexStringToByteArray( - cursor.getString(PDU_COLUMN)); - - // Read the destination port from the first segment (needed for CDMA WAP PDU). - // It's not a bad idea to prefer the port from the first segment for 3GPP as well. - if (cursorSequence == 0 && !cursor.isNull(DESTINATION_PORT_COLUMN)) { - destPort = cursor.getInt(DESTINATION_PORT_COLUMN); - } - } - // This one isn't in the DB, so add it - // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0 - if (isCdmaWapPush) { - pdus[sequenceNumber] = pdu; - } else { - pdus[sequenceNumber - 1] = pdu; - } - - // Remove the parts from the database - mResolver.delete(mRawUri, where, whereArgs); - } catch (SQLException e) { - Log.e(TAG, "Can't access multipart SMS database", e); - return Intents.RESULT_SMS_GENERIC_ERROR; - } finally { - if (cursor != null) cursor.close(); - } - - // Special handling for CDMA WDP datagrams - if (isCdmaWapPush) { - // Build up the data stream - ByteArrayOutputStream output = new ByteArrayOutputStream(); - for (int i = 0; i < messageCount; i++) { - // reassemble the (WSP-)pdu - output.write(pdus[i], 0, pdus[i].length); - } - byte[] datagram = output.toByteArray(); - - // Dispatch the PDU to applications - if (destPort == SmsHeader.PORT_WAP_PUSH) { - // Handle the PUSH - return mWapPush.dispatchWapPdu(datagram); - } else { - pdus = new byte[1][]; - pdus[0] = datagram; - // The messages were sent to any other WAP port - dispatchPortAddressedPdus(pdus, destPort); - return Activity.RESULT_OK; - } - } - - // Dispatch the PDUs to applications - if (destPort != -1) { - if (destPort == SmsHeader.PORT_WAP_PUSH) { - // Build up the data stream - ByteArrayOutputStream output = new ByteArrayOutputStream(); - for (int i = 0; i < messageCount; i++) { - SmsMessage msg = SmsMessage.createFromPdu(pdus[i], getFormat()); - byte[] data = msg.getUserData(); - output.write(data, 0, data.length); - } - // Handle the PUSH - return mWapPush.dispatchWapPdu(output.toByteArray()); - } else { - // The messages were sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destPort); - } - } else { - // The messages were not sent to a port - dispatchPdus(pdus); - } - return Activity.RESULT_OK; - } - - /** - * Dispatches standard PDUs to interested applications - * - * @param pdus The raw PDUs making up the message - */ - protected void dispatchPdus(byte[][] pdus) { - Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION); - intent.putExtra("pdus", pdus); - intent.putExtra("format", getFormat()); - dispatch(intent, RECEIVE_SMS_PERMISSION); - } - - /** - * Dispatches port addressed PDUs to interested applications - * - * @param pdus The raw PDUs making up the message - * @param port The destination port of the messages - */ - 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); - intent.putExtra("format", getFormat()); - dispatch(intent, RECEIVE_SMS_PERMISSION); - } - - /** - * Send a data based SMS to a specific application port. - * - * @param destAddr the address to send the message to - * @param scAddr is the service center address or null to use - * the current default SMSC - * @param destPort the port to deliver the message to - * @param data the body of the message to send - * @param sentIntent if not NULL this PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * RESULT_ERROR_NO_SERVICE
. - * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - protected abstract void sendData(String destAddr, String scAddr, int destPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent); - - /** - * Send a text based SMS. - * - * @param destAddr the address to send the message to - * @param scAddr 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 PendingIntent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors:
- * RESULT_ERROR_GENERIC_FAILURE
- * RESULT_ERROR_RADIO_OFF
- * RESULT_ERROR_NULL_PDU
- * RESULT_ERROR_NO_SERVICE
. - * For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.
- * 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 PendingIntent is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - protected abstract void sendText(String destAddr, String scAddr, - String text, PendingIntent sentIntent, PendingIntent deliveryIntent); - - /** - * Calculate the number of septets needed to encode the message. - * - * @param messageBody the message to encode - * @param use7bitOnly ignore (but still count) illegal characters if true - * @return TextEncodingDetails - */ - protected abstract TextEncodingDetails calculateLength(CharSequence messageBody, - boolean use7bitOnly); - - /** - * Send a multi-part text based SMS. - * - * @param destAddr the address to send the message to - * @param scAddr is the service center address or null to use - * the current default SMSC - * @param parts an ArrayList of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an ArrayList of - * PendingIntents (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU - * RESULT_ERROR_NO_SERVICE. - * 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 deliveryIntents if not null, an ArrayList of - * PendingIntents (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"). - */ - protected void sendMultipartText(String destAddr, String scAddr, - ArrayList parts, ArrayList sentIntents, - ArrayList deliveryIntents) { - - int refNumber = getNextConcatenatedRef() & 0x00FF; - int msgCount = parts.size(); - int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN; - - mRemainingMessages = msgCount; - - TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount]; - for (int i = 0; i < msgCount; i++) { - TextEncodingDetails details = calculateLength(parts.get(i), false); - if (encoding != details.codeUnitSize - && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN - || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) { - encoding = details.codeUnitSize; - } - encodingForParts[i] = details; - } - - for (int i = 0; i < msgCount; i++) { - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = refNumber; - concatRef.seqNumber = i + 1; // 1-based sequence - concatRef.msgCount = msgCount; - // TODO: We currently set this to true since our messaging app will never - // send more than 255 parts (it converts the message to MMS well before that). - // However, we should support 3rd party messaging apps that might need 16-bit - // references - // Note: It's not sufficient to just flip this bit to true; it will have - // ripple effects (several calculations assume 8-bit ref). - concatRef.isEightBits = true; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - - // Set the national language tables for 3GPP 7-bit encoding, if enabled. - if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) { - smsHeader.languageTable = encodingForParts[i].languageTable; - smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable; - } - - PendingIntent sentIntent = null; - if (sentIntents != null && sentIntents.size() > i) { - sentIntent = sentIntents.get(i); - } - - PendingIntent deliveryIntent = null; - if (deliveryIntents != null && deliveryIntents.size() > i) { - deliveryIntent = deliveryIntents.get(i); - } - - sendNewSubmitPdu(destAddr, scAddr, parts.get(i), smsHeader, encoding, - sentIntent, deliveryIntent, (i == (msgCount - 1))); - } - - } - - /** - * Create a new SubmitPdu and send it. - */ - protected abstract void sendNewSubmitPdu(String destinationAddress, String scAddress, - String message, SmsHeader smsHeader, int encoding, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart); - - /** - * Send a SMS - * - * @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 Intent is - * broadcast when the message is successfully sent, or failed. - * The result code will be Activity.RESULT_OK for success, - * or one of these errors: - * RESULT_ERROR_GENERIC_FAILURE - * RESULT_ERROR_RADIO_OFF - * RESULT_ERROR_NULL_PDU - * RESULT_ERROR_NO_SERVICE. - * 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 Intent is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param destAddr the destination phone number (for short code confirmation) - */ - protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent, String destAddr) { - if (mSmsSendDisabled) { - if (sentIntent != null) { - try { - sentIntent.send(RESULT_ERROR_NO_SERVICE); - } catch (CanceledException ex) {} - } - Log.d(TAG, "Device does not support sending sms."); - return; - } - - if (pdu == null) { - if (sentIntent != null) { - try { - sentIntent.send(RESULT_ERROR_NULL_PDU); - } catch (CanceledException ex) {} - } - return; - } - - HashMap map = new HashMap(); - map.put("smsc", smsc); - map.put("pdu", pdu); - - // Get calling app package name via UID from Binder call - PackageManager pm = mContext.getPackageManager(); - String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid()); - - if (packageNames == null || packageNames.length == 0) { - // Refuse to send SMS if we can't get the calling package name. - Log.e(TAG, "Can't get calling app package name: refusing to send SMS"); - if (sentIntent != null) { - try { - sentIntent.send(RESULT_ERROR_GENERIC_FAILURE); - } catch (CanceledException ex) { - Log.e(TAG, "failed to send error result"); - } - } - return; - } - - String appPackage = packageNames[0]; - - // Strip non-digits from destination phone number before checking for short codes - // and before displaying the number to the user if confirmation is required. - SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appPackage, - PhoneNumberUtils.extractNetworkPortion(destAddr)); - - // checkDestination() returns true if the destination is not a premium short code or the - // sending app is approved to send to short codes. Otherwise, a message is sent to our - // handler with the SmsTracker to request user confirmation before sending. - if (checkDestination(tracker)) { - // check for excessive outgoing SMS usage by this app - if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) { - sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker)); - return; - } - - int ss = mPhone.getServiceState().getState(); - - if (ss != ServiceState.STATE_IN_SERVICE) { - handleNotInService(ss, tracker.mSentIntent); - } else { - sendSms(tracker); - } - } - } - - /** - * Check if destination is a potential premium short code and sender is not pre-approved to - * send to short codes. - * - * @param tracker the tracker for the SMS to send - * @return true if the destination is approved; false if user confirmation event was sent - */ - boolean checkDestination(SmsTracker tracker) { - if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION_PERMISSION) - == PackageManager.PERMISSION_GRANTED) { - return true; // app is pre-approved to send to short codes - } else { - String countryIso = mTelephonyManager.getSimCountryIso(); - if (countryIso == null || countryIso.length() != 2) { - Log.e(TAG, "Can't get SIM country code: trying network country code"); - countryIso = mTelephonyManager.getNetworkCountryIso(); - } - - switch (mUsageMonitor.checkDestination(tracker.mDestAddress, countryIso)) { - case SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE: - sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE, - tracker)); - return false; // wait for user confirmation before sending - - case SmsUsageMonitor.CATEGORY_PREMIUM_SHORT_CODE: - sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE, - tracker)); - return false; // wait for user confirmation before sending - - case SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE: - case SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE: - case SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE: - default: - return true; // destination is not a premium short code - } - } - } - - /** - * Deny sending an SMS if the outgoing queue limit is reached. Used when the message - * must be confirmed by the user due to excessive usage or potential premium SMS detected. - * @param tracker the SmsTracker for the message to send - * @return true if the message was denied; false to continue with send confirmation - */ - private boolean denyIfQueueLimitReached(SmsTracker tracker) { - if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) { - // Deny sending message when the queue limit is reached. - try { - tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED); - } catch (CanceledException ex) { - Log.e(TAG, "failed to send back RESULT_ERROR_LIMIT_EXCEEDED"); - } - return true; - } - mPendingTrackerCount++; - return false; - } - - /** - * Returns the label for the specified app package name. - * @param appPackage the package name of the app requesting to send an SMS - * @return the label for the specified app, or the package name if getApplicationInfo() fails - */ - private CharSequence getAppLabel(String appPackage) { - PackageManager pm = mContext.getPackageManager(); - try { - ApplicationInfo appInfo = pm.getApplicationInfo(appPackage, 0); - return appInfo.loadLabel(pm); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "PackageManager Name Not Found for package " + appPackage); - return appPackage; // fall back to package name if we can't get app label - } - } - - /** - * Post an alert when SMS needs confirmation due to excessive usage. - * @param tracker an SmsTracker for the current message. - */ - protected void handleReachSentLimit(SmsTracker tracker) { - if (denyIfQueueLimitReached(tracker)) { - return; // queue limit reached; error was returned to caller - } - - CharSequence appLabel = getAppLabel(tracker.mAppPackage); - Resources r = Resources.getSystem(); - Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel)); - - ConfirmDialogListener listener = new ConfirmDialogListener(tracker); - - AlertDialog d = new AlertDialog.Builder(mContext) - .setTitle(R.string.sms_control_title) - .setIcon(R.drawable.stat_sys_warning) - .setMessage(messageText) - .setPositiveButton(r.getString(R.string.sms_control_yes), listener) - .setNegativeButton(r.getString(R.string.sms_control_no), listener) - .setOnCancelListener(listener) - .create(); - - d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - d.show(); - } - - /** - * Post an alert for user confirmation when sending to a potential short code. - * @param isPremium true if the destination is known to be a premium short code - * @param tracker the SmsTracker for the current message. - */ - protected void handleConfirmShortCode(boolean isPremium, SmsTracker tracker) { - if (denyIfQueueLimitReached(tracker)) { - return; // queue limit reached; error was returned to caller - } - - int messageId; - int titleId; - if (isPremium) { - messageId = R.string.sms_premium_short_code_confirm_message; - titleId = R.string.sms_premium_short_code_confirm_title; - } else { - messageId = R.string.sms_short_code_confirm_message; - titleId = R.string.sms_short_code_confirm_title; - } - - CharSequence appLabel = getAppLabel(tracker.mAppPackage); - Resources r = Resources.getSystem(); - Spanned messageText = Html.fromHtml(r.getString(messageId, appLabel, tracker.mDestAddress)); - - ConfirmDialogListener listener = new ConfirmDialogListener(tracker); - - AlertDialog d = new AlertDialog.Builder(mContext) - .setTitle(titleId) - .setIcon(R.drawable.stat_sys_warning) - .setMessage(messageText) - .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener) - .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener) -// TODO: add third button for "Report malicious app" feature -// .setNeutralButton(r.getString(R.string.sms_short_code_confirm_report), listener) - .setOnCancelListener(listener) - .create(); - - d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - d.show(); - } - - /** - * Send the message along to the radio. - * - * @param tracker holds the SMS message to send - */ - protected abstract void sendSms(SmsTracker tracker); - - /** - * Send the multi-part SMS based on multipart Sms tracker - * - * @param tracker holds the multipart Sms tracker ready to be sent - */ - private void sendMultipartSms(SmsTracker tracker) { - ArrayList parts; - ArrayList sentIntents; - ArrayList deliveryIntents; - - HashMap map = tracker.mData; - - String destinationAddress = (String) map.get("destination"); - String scAddress = (String) map.get("scaddress"); - - parts = (ArrayList) map.get("parts"); - sentIntents = (ArrayList) map.get("sentIntents"); - deliveryIntents = (ArrayList) map.get("deliveryIntents"); - - // check if in service - int ss = mPhone.getServiceState().getState(); - if (ss != ServiceState.STATE_IN_SERVICE) { - for (int i = 0, count = parts.size(); i < count; i++) { - PendingIntent sentIntent = null; - if (sentIntents != null && sentIntents.size() > i) { - sentIntent = sentIntents.get(i); - } - handleNotInService(ss, sentIntent); - } - return; - } - - sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents); - } - - /** - * Send an acknowledge message. - * @param success indicates that last message was successfully received. - * @param result result code indicating any error - * @param response callback message sent when operation completes. - */ - protected abstract void acknowledgeLastIncomingSms(boolean success, - int result, Message response); - - /** - * Notify interested apps if the framework has rejected an incoming SMS, - * and send an acknowledge message to the network. - * @param success indicates that last message was successfully received. - * @param result result code indicating any error - * @param response callback message sent when operation completes. - */ - private void notifyAndAcknowledgeLastIncomingSms(boolean success, - int result, Message response) { - if (!success) { - // broadcast SMS_REJECTED_ACTION intent - Intent intent = new Intent(Intents.SMS_REJECTED_ACTION); - intent.putExtra("result", result); - mWakeLock.acquire(WAKE_LOCK_TIMEOUT); - mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS"); - } - acknowledgeLastIncomingSms(success, result, response); - } - - /** - * Keeps track of an SMS that has been sent to the RIL, until it has - * successfully been sent, or we're done trying. - * - */ - protected static final class SmsTracker { - // fields need to be public for derived SmsDispatchers - public final HashMap mData; - public int mRetryCount; - public int mMessageRef; - - public final PendingIntent mSentIntent; - public final PendingIntent mDeliveryIntent; - - public final String mAppPackage; - public final String mDestAddress; - - public SmsTracker(HashMap data, PendingIntent sentIntent, - PendingIntent deliveryIntent, String appPackage, String destAddr) { - mData = data; - mSentIntent = sentIntent; - mDeliveryIntent = deliveryIntent; - mRetryCount = 0; - mAppPackage = appPackage; - mDestAddress = destAddr; - } - - /** - * Returns whether this tracker holds a multi-part SMS. - * @return true if the tracker holds a multi-part SMS; false otherwise - */ - protected boolean isMultipart() { - HashMap map = mData; - return map.containsKey("parts"); - } - } - - /** - * Dialog listener for SMS confirmation dialog. - */ - private final class ConfirmDialogListener - implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener { - - private final SmsTracker mTracker; - - ConfirmDialogListener(SmsTracker tracker) { - mTracker = tracker; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - Log.d(TAG, "CONFIRM sending SMS"); - sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTracker)); - } else if (which == DialogInterface.BUTTON_NEGATIVE) { - Log.d(TAG, "DENY sending SMS"); - sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker)); - } - } - - @Override - public void onCancel(DialogInterface dialog) { - Log.d(TAG, "dialog dismissed: don't send SMS"); - sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker)); - } - } - - private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - // Assume the intent is one of the SMS receive intents that - // was sent as an ordered broadcast. Check result and ACK. - int rc = getResultCode(); - boolean success = (rc == Activity.RESULT_OK) - || (rc == Intents.RESULT_SMS_HANDLED); - - // For a multi-part message, this only ACKs the last part. - // Previous parts were ACK'd as they were received. - acknowledgeLastIncomingSms(success, rc, null); - } - }; - - protected void dispatchBroadcastMessage(SmsCbMessage message) { - if (message.isEmergencyMessage()) { - Intent intent = new Intent(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION); - intent.putExtra("message", message); - Log.d(TAG, "Dispatching emergency SMS CB"); - dispatch(intent, RECEIVE_EMERGENCY_BROADCAST_PERMISSION); - } else { - Intent intent = new Intent(Intents.SMS_CB_RECEIVED_ACTION); - intent.putExtra("message", message); - Log.d(TAG, "Dispatching SMS CB"); - dispatch(intent, RECEIVE_SMS_PERMISSION); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java deleted file mode 100644 index e4cfb23f412b..000000000000 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ /dev/null @@ -1,538 +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; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.util.TimeUtils; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -/** - * {@hide} - */ -public abstract class ServiceStateTracker extends Handler { - - protected CommandsInterface cm; - - public ServiceState ss; - protected ServiceState newSS; - - public SignalStrength mSignalStrength; - - // TODO - this should not be public - public RestrictedState mRestrictedState = new RestrictedState(); - - /* The otaspMode passed to PhoneStateListener#onOtaspChanged */ - static public final int OTASP_UNINITIALIZED = 0; - static public final int OTASP_UNKNOWN = 1; - static public final int OTASP_NEEDED = 2; - static public final int OTASP_NOT_NEEDED = 3; - - /** - * A unique identifier to track requests associated with a poll - * and ignore stale responses. The value is a count-down of - * expected responses in this pollingContext. - */ - protected int[] pollingContext; - protected boolean mDesiredPowerState; - - /** - * Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions. - */ - protected int mRilRadioTechnology = 0; - protected int mNewRilRadioTechnology = 0; - - /** - * By default, strength polling is enabled. However, if we're - * getting unsolicited signal strength updates from the radio, set - * value to true and don't bother polling any more. - */ - protected boolean dontPollSignalStrength = false; - - protected RegistrantList mRoamingOnRegistrants = new RegistrantList(); - protected RegistrantList mRoamingOffRegistrants = new RegistrantList(); - protected RegistrantList mAttachedRegistrants = new RegistrantList(); - protected RegistrantList mDetachedRegistrants = new RegistrantList(); - protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList(); - protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList(); - protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList(); - - /* Radio power off pending flag and tag counter */ - private boolean mPendingRadioPowerOffAfterDataOff = false; - private int mPendingRadioPowerOffAfterDataOffTag = 0; - - protected static final boolean DBG = true; - - /** Signal strength poll rate. */ - protected static final int POLL_PERIOD_MILLIS = 20 * 1000; - - /** Waiting period before recheck gprs and voice registration. */ - public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000; - - /** GSM 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; - protected static final int EVENT_POLL_STATE_REGISTRATION = 4; - protected static final int EVENT_POLL_STATE_GPRS = 5; - protected static final int EVENT_POLL_STATE_OPERATOR = 6; - protected static final int EVENT_POLL_SIGNAL_STRENGTH = 10; - protected static final int EVENT_NITZ_TIME = 11; - protected static final int EVENT_SIGNAL_STRENGTH_UPDATE = 12; - protected static final int EVENT_RADIO_AVAILABLE = 13; - protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14; - protected static final int EVENT_GET_LOC_DONE = 15; - protected static final int EVENT_SIM_RECORDS_LOADED = 16; - protected static final int EVENT_SIM_READY = 17; - protected static final int EVENT_LOCATION_UPDATES_ENABLED = 18; - protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE = 19; - protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE = 20; - protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE = 21; - protected static final int EVENT_CHECK_REPORT_GPRS = 22; - protected static final int EVENT_RESTRICTED_STATE_CHANGED = 23; - - /** CDMA events */ - protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA = 24; - protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 25; - protected static final int EVENT_RUIM_READY = 26; - protected static final int EVENT_RUIM_RECORDS_LOADED = 27; - protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 28; - protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 29; - protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 30; - protected static final int EVENT_GET_LOC_DONE_CDMA = 31; - protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 32; - protected static final int EVENT_NV_LOADED = 33; - protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION = 34; - protected static final int EVENT_NV_READY = 35; - protected static final int EVENT_ERI_FILE_LOADED = 36; - protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37; - protected static final int EVENT_SET_RADIO_POWER_OFF = 38; - protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 39; - protected static final int EVENT_CDMA_PRL_VERSION_CHANGED = 40; - protected static final int EVENT_RADIO_ON = 41; - - - protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; - - /** - * List of ISO codes for countries that can have an offset of - * GMT+0 when not in daylight savings time. This ignores some - * small places such as the Canary Islands (Spain) and - * Danmarkshavn (Denmark). The list must be sorted by code. - */ - protected static final String[] GMT_COUNTRY_CODES = { - "bf", // Burkina Faso - "ci", // Cote d'Ivoire - "eh", // Western Sahara - "fo", // Faroe Islands, Denmark - "gb", // United Kingdom of Great Britain and Northern Ireland - "gh", // Ghana - "gm", // Gambia - "gn", // Guinea - "gw", // Guinea Bissau - "ie", // Ireland - "lr", // Liberia - "is", // Iceland - "ma", // Morocco - "ml", // Mali - "mr", // Mauritania - "pt", // Portugal - "sl", // Sierra Leone - "sn", // Senegal - "st", // Sao Tome and Principe - "tg", // Togo - }; - - /** Reason for registration denial. */ - protected static final String REGISTRATION_DENIED_GEN = "General"; - protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure"; - - public ServiceStateTracker() { - } - - public boolean getDesiredPowerState() { - return mDesiredPowerState; - } - - /** - * Registration point for combined roaming on - * combined roaming is true when roaming is true and ONS differs SPN - * - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForRoamingOn(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mRoamingOnRegistrants.add(r); - - if (ss.getRoaming()) { - r.notifyRegistrant(); - } - } - - public void unregisterForRoamingOn(Handler h) { - mRoamingOnRegistrants.remove(h); - } - - /** - * Registration point for combined roaming off - * combined roaming is true when roaming is true and ONS differs SPN - * - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForRoamingOff(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mRoamingOffRegistrants.add(r); - - if (!ss.getRoaming()) { - r.notifyRegistrant(); - } - } - - public void unregisterForRoamingOff(Handler h) { - mRoamingOffRegistrants.remove(h); - } - - /** - * Re-register network by toggling preferred network type. - * This is a work-around to deregister and register network since there is - * no ril api to set COPS=2 (deregister) only. - * - * @param onComplete is dispatched when this is complete. it will be - * an AsyncResult, and onComplete.obj.exception will be non-null - * on failure. - */ - public void reRegisterNetwork(Message onComplete) { - cm.getPreferredNetworkType( - obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete)); - } - - public void - setRadioPower(boolean power) { - mDesiredPowerState = power; - - setPowerStateToDesired(); - } - - /** - * These two flags manage the behavior of the cell lock -- the - * lock should be held if either flag is true. The intention is - * to allow temporary acquisition of the lock to get a single - * update. Such a lock grab and release can thus be made to not - * interfere with more permanent lock holds -- in other words, the - * lock will only be released if both flags are false, and so - * releases by temporary users will only affect the lock state if - * there is no continuous user. - */ - private boolean mWantContinuousLocationUpdates; - private boolean mWantSingleLocationUpdate; - - public void enableSingleLocationUpdate() { - if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return; - mWantSingleLocationUpdate = true; - cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED)); - } - - public void enableLocationUpdates() { - if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return; - mWantContinuousLocationUpdates = true; - cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED)); - } - - protected void disableSingleLocationUpdate() { - mWantSingleLocationUpdate = false; - if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) { - cm.setLocationUpdates(false, null); - } - } - - public void disableLocationUpdates() { - mWantContinuousLocationUpdates = false; - if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) { - cm.setLocationUpdates(false, null); - } - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_SET_RADIO_POWER_OFF: - synchronized(this) { - if (mPendingRadioPowerOffAfterDataOff && - (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) { - if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now."); - hangupAndPowerOff(); - mPendingRadioPowerOffAfterDataOffTag += 1; - mPendingRadioPowerOffAfterDataOff = false; - } else { - log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 + - "!= tag=" + mPendingRadioPowerOffAfterDataOffTag); - } - } - break; - - default: - log("Unhandled message with number: " + msg.what); - break; - } - } - - protected abstract Phone getPhone(); - protected abstract void handlePollStateResult(int what, AsyncResult ar); - protected abstract void updateSpnDisplay(); - protected abstract void setPowerStateToDesired(); - protected abstract void log(String s); - protected abstract void loge(String s); - - public abstract int getCurrentDataConnectionState(); - public abstract boolean isConcurrentVoiceAndDataAllowed(); - - /** - * Registration point for transition into DataConnection attached. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForDataConnectionAttached(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mAttachedRegistrants.add(r); - - if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) { - r.notifyRegistrant(); - } - } - public void unregisterForDataConnectionAttached(Handler h) { - mAttachedRegistrants.remove(h); - } - - /** - * Registration point for transition into DataConnection detached. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForDataConnectionDetached(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mDetachedRegistrants.add(r); - - if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) { - r.notifyRegistrant(); - } - } - public void unregisterForDataConnectionDetached(Handler h) { - mDetachedRegistrants.remove(h); - } - - /** - * Registration point for transition into network attached. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj in Message.obj - */ - public void registerForNetworkAttached(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - - mNetworkAttachedRegistrants.add(r); - if (ss.getState() == ServiceState.STATE_IN_SERVICE) { - r.notifyRegistrant(); - } - } - public void unregisterForNetworkAttached(Handler h) { - mNetworkAttachedRegistrants.remove(h); - } - - /** - * Registration point for transition into packet service restricted zone. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mPsRestrictEnabledRegistrants.add(r); - - if (mRestrictedState.isPsRestricted()) { - r.notifyRegistrant(); - } - } - - public void unregisterForPsRestrictedEnabled(Handler h) { - mPsRestrictEnabledRegistrants.remove(h); - } - - /** - * Registration point for transition out of packet service restricted zone. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - mPsRestrictDisabledRegistrants.add(r); - - if (mRestrictedState.isPsRestricted()) { - r.notifyRegistrant(); - } - } - - public void unregisterForPsRestrictedDisabled(Handler h) { - mPsRestrictDisabledRegistrants.remove(h); - } - - /** - * Clean up existing voice and data connection then turn off radio power. - * - * Hang up the existing voice calls to decrease call drop rate. - */ - public void powerOffRadioSafely(DataConnectionTracker dcTracker) { - synchronized (this) { - if (!mPendingRadioPowerOffAfterDataOff) { - // To minimize race conditions we call cleanUpAllConnections on - // both if else paths instead of before this isDisconnected test. - if (dcTracker.isDisconnected()) { - // To minimize race conditions we do this after isDisconnected - dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF); - if (DBG) log("Data disconnected, turn off radio right away."); - hangupAndPowerOff(); - } else { - dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF); - Message msg = Message.obtain(this); - msg.what = EVENT_SET_RADIO_POWER_OFF; - msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag; - if (sendMessageDelayed(msg, 30000)) { - if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio."); - mPendingRadioPowerOffAfterDataOff = true; - } else { - log("Cannot send delayed Msg, turn off radio right away."); - hangupAndPowerOff(); - } - } - } - } - } - - /** - * process the pending request to turn radio off after data is disconnected - * - * return true if there is pending request to process; false otherwise. - */ - public boolean processPendingRadioPowerOffAfterDataOff() { - synchronized(this) { - if (mPendingRadioPowerOffAfterDataOff) { - if (DBG) log("Process pending request to turn radio off."); - mPendingRadioPowerOffAfterDataOffTag += 1; - hangupAndPowerOff(); - mPendingRadioPowerOffAfterDataOff = false; - return true; - } - return false; - } - } - - /** - * Hang up all voice call and turn off radio. Implemented by derived class. - */ - protected abstract void hangupAndPowerOff(); - - /** Cancel a pending (if any) pollState() operation */ - protected void cancelPollState() { - // This will effectively cancel the rest of the poll requests. - pollingContext = new int[1]; - } - - /** - * Return true if time zone needs fixing. - * - * @param phoneBase - * @param operatorNumeric - * @param prevOperatorNumeric - * @param needToFixTimeZone - * @return true if time zone needs to be fixed - */ - protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric, - String prevOperatorNumeric, boolean needToFixTimeZone) { - // Return false if the mcc isn't valid as we don't know where we are. - // Return true if we have an IccCard and the mcc changed or we - // need to fix it because when the NITZ time came in we didn't - // know the country code. - - // If mcc is invalid then we'll return false - int mcc; - try { - mcc = Integer.parseInt(operatorNumeric.substring(0, 3)); - } catch (Exception e) { - if (DBG) { - log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric + - " retVal=false"); - } - return false; - } - - // If prevMcc is invalid will make it different from mcc - // so we'll return true if the card exists. - int prevMcc; - try { - prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3)); - } catch (Exception e) { - prevMcc = mcc + 1; - } - - // Determine if the Icc card exists - IccCard iccCard = phoneBase.getIccCard(); - boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist(); - - // Determine retVal - boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone); - if (DBG) { - long ctm = System.currentTimeMillis(); - log("shouldFixTimeZoneNow: retVal=" + retVal + - " iccCard=" + iccCard + - " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) + - " iccCardExist=" + iccCardExist + - " operatorNumeric=" + operatorNumeric + " mcc=" + mcc + - " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc + - " needToFixTimeZone=" + needToFixTimeZone + - " ltod=" + TimeUtils.logTimeOfDay(ctm)); - } - return retVal; - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("ServiceStateTracker:"); - pw.println(" ss=" + ss); - pw.println(" newSS=" + newSS); - pw.println(" mSignalStrength=" + mSignalStrength); - pw.println(" mRestrictedState=" + mRestrictedState); - pw.println(" pollingContext=" + pollingContext); - pw.println(" mDesiredPowerState=" + mDesiredPowerState); - pw.println(" mRilRadioTechnology=" + mRilRadioTechnology); - pw.println(" mNewRilRadioTechnology=" + mNewRilRadioTechnology); - pw.println(" dontPollSignalStrength=" + dontPollSignalStrength); - pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff); - pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag); - } -} diff --git a/telephony/java/com/android/internal/telephony/SmsAddress.java b/telephony/java/com/android/internal/telephony/SmsAddress.java deleted file mode 100644 index b3892cb0b342..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsAddress.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -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/SmsConstants.java b/telephony/java/com/android/internal/telephony/SmsConstants.java new file mode 100644 index 000000000000..1ccdc3b24eef --- /dev/null +++ b/telephony/java/com/android/internal/telephony/SmsConstants.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 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; + +/** + * SMS Constants and must be the same as the corresponding + * deprecated version in SmsMessage. + * + * @hide + */ +public class SmsConstants { + /** User data text encoding code unit size */ + public static final int ENCODING_UNKNOWN = 0; + public static final int ENCODING_7BIT = 1; + public static final int ENCODING_8BIT = 2; + public static final int ENCODING_16BIT = 3; + + /** 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; + + /** + * This value is not defined in global standard. Only in Korea, this is used. + */ + public static final int ENCODING_KSC5601 = 4; + + /** The maximum number of payload bytes per message */ + public static final int MAX_USER_DATA_BYTES = 140; + + /** + * 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. + */ + public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134; + + /** + * SMS Class enumeration. + * See TS 23.038. + */ + public enum MessageClass{ + UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3; + } + + /** + * Indicates a 3GPP format SMS message. + * @hide pending API council approval + */ + public static final String FORMAT_3GPP = "3gpp"; + + /** + * Indicates a 3GPP2 format SMS message. + * @hide pending API council approval + */ + public static final String FORMAT_3GPP2 = "3gpp2"; +} diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java deleted file mode 100644 index c32388f85ee1..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsHeader.java +++ /dev/null @@ -1,289 +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; - -import android.telephony.SmsMessage; - -import com.android.internal.util.HexDump; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import java.util.ArrayList; - -/** - * SMS user data header, as specified in TS 23.040 9.2.3.24. - */ -public class SmsHeader { - - // TODO(cleanup): this data structure is generally referred to as - // the 'user data header' or UDH, and so the class name should - // change to reflect this... - - /** SMS user data header information element identifiers. - * (see TS 23.040 9.2.3.24) - */ - public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00; - public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01; - public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04; - public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05; - public static final int ELT_ID_SMSC_CONTROL_PARAMS = 0x06; - public static final int ELT_ID_UDH_SOURCE_INDICATION = 0x07; - public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08; - public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09; - public static final int ELT_ID_TEXT_FORMATTING = 0x0A; - public static final int ELT_ID_PREDEFINED_SOUND = 0x0B; - public static final int ELT_ID_USER_DEFINED_SOUND = 0x0C; - public static final int ELT_ID_PREDEFINED_ANIMATION = 0x0D; - public static final int ELT_ID_LARGE_ANIMATION = 0x0E; - public static final int ELT_ID_SMALL_ANIMATION = 0x0F; - public static final int ELT_ID_LARGE_PICTURE = 0x10; - public static final int ELT_ID_SMALL_PICTURE = 0x11; - public static final int ELT_ID_VARIABLE_PICTURE = 0x12; - public static final int ELT_ID_USER_PROMPT_INDICATOR = 0x13; - public static final int ELT_ID_EXTENDED_OBJECT = 0x14; - public static final int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15; - public static final int ELT_ID_COMPRESSION_CONTROL = 0x16; - public static final int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17; - public static final int ELT_ID_STANDARD_WVG_OBJECT = 0x18; - public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19; - public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A; - public static final int ELT_ID_RFC_822_EMAIL_HEADER = 0x20; - public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21; - public static final int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22; - public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23; - public static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24; - public static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25; - - public static final int PORT_WAP_PUSH = 2948; - public static final int PORT_WAP_WSP = 9200; - - public static class PortAddrs { - public int destPort; - public int origPort; - public boolean areEightBits; - } - - public static class ConcatRef { - public int refNumber; - public int seqNumber; - public int msgCount; - public boolean isEightBits; - } - - /** - * A header element that is not explicitly parsed, meaning not - * PortAddrs or ConcatRef. - */ - public static class MiscElt { - public int id; - public byte[] data; - } - - public PortAddrs portAddrs; - public ConcatRef concatRef; - public ArrayList miscEltList = new ArrayList(); - - /** 7 bit national language locking shift table, or 0 for GSM default 7 bit alphabet. */ - public int languageTable; - - /** 7 bit national language single shift table, or 0 for GSM default 7 bit extension table. */ - public int languageShiftTable; - - public SmsHeader() {} - - /** - * Create structured SmsHeader object from serialized byte array representation. - * (see TS 23.040 9.2.3.24) - * @param data is user data header bytes - * @return SmsHeader object - */ - public static SmsHeader fromByteArray(byte[] data) { - ByteArrayInputStream inStream = new ByteArrayInputStream(data); - SmsHeader smsHeader = new SmsHeader(); - while (inStream.available() > 0) { - /** - * NOTE: as defined in the spec, ConcatRef and PortAddr - * fields should not reoccur, but if they do the last - * occurrence is to be used. Also, for ConcatRef - * elements, if the count is zero, sequence is zero, or - * sequence is larger than count, the entire element is to - * be ignored. - */ - int id = inStream.read(); - int length = inStream.read(); - ConcatRef concatRef; - PortAddrs portAddrs; - switch (id) { - case ELT_ID_CONCATENATED_8_BIT_REFERENCE: - concatRef = new ConcatRef(); - concatRef.refNumber = inStream.read(); - concatRef.msgCount = inStream.read(); - concatRef.seqNumber = inStream.read(); - concatRef.isEightBits = true; - if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 && - concatRef.seqNumber <= concatRef.msgCount) { - smsHeader.concatRef = concatRef; - } - break; - case ELT_ID_CONCATENATED_16_BIT_REFERENCE: - concatRef = new ConcatRef(); - concatRef.refNumber = (inStream.read() << 8) | inStream.read(); - concatRef.msgCount = inStream.read(); - concatRef.seqNumber = inStream.read(); - concatRef.isEightBits = false; - if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 && - concatRef.seqNumber <= concatRef.msgCount) { - smsHeader.concatRef = concatRef; - } - break; - case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT: - portAddrs = new PortAddrs(); - portAddrs.destPort = inStream.read(); - portAddrs.origPort = inStream.read(); - portAddrs.areEightBits = true; - smsHeader.portAddrs = portAddrs; - break; - case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT: - portAddrs = new PortAddrs(); - portAddrs.destPort = (inStream.read() << 8) | inStream.read(); - portAddrs.origPort = (inStream.read() << 8) | inStream.read(); - portAddrs.areEightBits = false; - smsHeader.portAddrs = portAddrs; - break; - case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT: - smsHeader.languageShiftTable = inStream.read(); - break; - case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT: - smsHeader.languageTable = inStream.read(); - break; - default: - MiscElt miscElt = new MiscElt(); - miscElt.id = id; - miscElt.data = new byte[length]; - inStream.read(miscElt.data, 0, length); - smsHeader.miscEltList.add(miscElt); - } - } - return smsHeader; - } - - /** - * Create serialized byte array representation from structured SmsHeader object. - * (see TS 23.040 9.2.3.24) - * @return Byte array representing the SmsHeader - */ - public static byte[] toByteArray(SmsHeader smsHeader) { - if ((smsHeader.portAddrs == null) && - (smsHeader.concatRef == null) && - (smsHeader.miscEltList.isEmpty()) && - (smsHeader.languageShiftTable == 0) && - (smsHeader.languageTable == 0)) { - return null; - } - - ByteArrayOutputStream outStream = new ByteArrayOutputStream(SmsMessage.MAX_USER_DATA_BYTES); - ConcatRef concatRef = smsHeader.concatRef; - if (concatRef != null) { - if (concatRef.isEightBits) { - outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE); - outStream.write(3); - outStream.write(concatRef.refNumber); - } else { - outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE); - outStream.write(4); - outStream.write(concatRef.refNumber >>> 8); - outStream.write(concatRef.refNumber & 0x00FF); - } - outStream.write(concatRef.msgCount); - outStream.write(concatRef.seqNumber); - } - PortAddrs portAddrs = smsHeader.portAddrs; - if (portAddrs != null) { - if (portAddrs.areEightBits) { - outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT); - outStream.write(2); - outStream.write(portAddrs.destPort); - outStream.write(portAddrs.origPort); - } else { - outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT); - outStream.write(4); - outStream.write(portAddrs.destPort >>> 8); - outStream.write(portAddrs.destPort & 0x00FF); - outStream.write(portAddrs.origPort >>> 8); - outStream.write(portAddrs.origPort & 0x00FF); - } - } - if (smsHeader.languageShiftTable != 0) { - outStream.write(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT); - outStream.write(1); - outStream.write(smsHeader.languageShiftTable); - } - if (smsHeader.languageTable != 0) { - outStream.write(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT); - outStream.write(1); - outStream.write(smsHeader.languageTable); - } - for (MiscElt miscElt : smsHeader.miscEltList) { - outStream.write(miscElt.id); - outStream.write(miscElt.data.length); - outStream.write(miscElt.data, 0, miscElt.data.length); - } - return outStream.toByteArray(); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("UserDataHeader "); - builder.append("{ ConcatRef "); - if (concatRef == null) { - builder.append("unset"); - } else { - builder.append("{ refNumber=" + concatRef.refNumber); - builder.append(", msgCount=" + concatRef.msgCount); - builder.append(", seqNumber=" + concatRef.seqNumber); - builder.append(", isEightBits=" + concatRef.isEightBits); - builder.append(" }"); - } - builder.append(", PortAddrs "); - if (portAddrs == null) { - builder.append("unset"); - } else { - builder.append("{ destPort=" + portAddrs.destPort); - builder.append(", origPort=" + portAddrs.origPort); - builder.append(", areEightBits=" + portAddrs.areEightBits); - builder.append(" }"); - } - if (languageShiftTable != 0) { - builder.append(", languageShiftTable=" + languageShiftTable); - } - if (languageTable != 0) { - builder.append(", languageTable=" + languageTable); - } - for (MiscElt miscElt : miscEltList) { - builder.append(", MiscElt "); - builder.append("{ id=" + miscElt.id); - builder.append(", length=" + miscElt.data.length); - builder.append(", data=" + HexDump.toHexString(miscElt.data)); - builder.append(" }"); - } - builder.append(" }"); - return builder.toString(); - } - -} diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java deleted file mode 100644 index fcd038ce8d82..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import com.android.internal.telephony.SmsHeader; -import java.util.Arrays; - -import static android.telephony.SmsMessage.MessageClass; -import android.provider.Telephony; - -/** - * 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; - - /** - * For a specific text string, this object describes protocol - * properties of encoding it for transmission as message user - * data. - */ - public static class TextEncodingDetails { - /** - *The number of SMS's required to encode the text. - */ - public int msgCount; - - /** - * The number of code units consumed so far, where code units - * are basically characters in the encoding -- for example, - * septets for the standard ASCII and GSM encodings, and 16 - * bits for Unicode. - */ - public int codeUnitCount; - - /** - * How many code units are still available without spilling - * into an additional message. - */ - public int codeUnitsRemaining; - - /** - * The encoding code unit size (specified using - * android.telephony.SmsMessage ENCODING_*). - */ - public int codeUnitSize; - - /** - * The GSM national language table to use, or 0 for the default 7-bit alphabet. - */ - public int languageTable; - - /** - * The GSM national language shift table to use, or 0 for the default 7-bit extension table. - */ - public int languageShiftTable; - - @Override - public String toString() { - return "TextEncodingDetails " + - "{ msgCount=" + msgCount + - ", codeUnitCount=" + codeUnitCount + - ", codeUnitsRemaining=" + codeUnitsRemaining + - ", codeUnitSize=" + codeUnitSize + - ", languageTable=" + languageTable + - ", languageShiftTable=" + languageShiftTable + - " }"; - } - } - - // TODO(): This class is duplicated in SmsMessage.java. Refactor accordingly. - 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 - * - * {@hide} - */ - public SmsHeader getUserDataHeader() { - return userDataHeader; - } - - /** - * TODO(cleanup): The term PDU is used in a seemingly non-unique - * manner -- for example, what is the difference between this byte - * array and the contents of SubmitPdu objects. Maybe a more - * illustrative term would be appropriate. - */ - - /** - * Returns the raw PDU for the message. - */ - 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 TP-Reply-Path 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() { - // originatingAddress could be null if this message is from a status - // report. - if (originatingAddress != null && originatingAddress.couldBeEmailGateway()) { - extractEmailAddressFromMessageBody(); - } - } - - /** - * Try to parse this message as an email gateway message - * There are two ways specified in TS 23.040 Section 3.8 : - * - SMS message "may have its TP-PID set for Internet electronic mail - MT - * SMS format: [] - "Depending on the - * nature of the gateway, the destination/origination address is either - * derived from the content of the SMS TP-OA or TP-DA field, or the - * TP-OA/TP-DA field contains a generic gateway address and the to/from - * address is added at the beginning as shown above." (which is supported here) - * - Multiple addresses separated by commas, no spaces, Subject field delimited - * by '()' or '##' and '#' Section 9.2.3.24.11 (which are NOT supported here) - */ - protected void extractEmailAddressFromMessageBody() { - - /* Some carriers may use " /" delimiter as below - * - * 1. [x@y][ ]/[subject][ ]/[body] - * -or- - * 2. [x@y][ ]/[body] - */ - String[] parts = messageBody.split("( /)|( )", 2); - if (parts.length < 2) return; - emailFrom = parts[0]; - emailBody = parts[1]; - isEmail = Telephony.Mms.isEmailAddress(emailFrom); - } - -} diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.java b/telephony/java/com/android/internal/telephony/SmsRawData.java deleted file mode 100644 index 891d942b9a13..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsRawData.java +++ /dev/null @@ -1,62 +0,0 @@ -/* -** 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; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * A parcelable holder class of byte[] for ISms aidl implementation - */ -public class SmsRawData implements Parcelable { - byte[] data; - - //Static Methods - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator (){ - public SmsRawData createFromParcel(Parcel source) { - int size; - size = source.readInt(); - byte[] data = new byte[size]; - source.readByteArray(data); - return new SmsRawData(data); - } - - public SmsRawData[] newArray(int size) { - return new SmsRawData[size]; - } - }; - - // Constructor - public SmsRawData(byte[] data) { - this.data = data; - } - - public byte[] getBytes() { - return data; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(data.length); - dest.writeByteArray(data); - } -} diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java deleted file mode 100644 index a7c2840effb7..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsResponse.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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; - -/** - * Object returned by the RIL upon successful completion of sendSMS. - * Contains message reference and ackPdu. - * - */ -public class SmsResponse { - /** Message reference of the just-sent SMS. */ - int messageRef; - /** ackPdu for the just-sent SMS. */ - String ackPdu; - /** - * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS, - * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable. - */ - int errorCode; - - public SmsResponse(int messageRef, String ackPdu, int errorCode) { - this.messageRef = messageRef; - this.ackPdu = ackPdu; - this.errorCode = errorCode; - } - - public String toString() { - String ret = "{ messageRef = " + messageRef - + ", errorCode = " + errorCode - + ", ackPdu = " + ackPdu - + "}"; - return ret; - } -} diff --git a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java b/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java deleted file mode 100644 index 0c06ffc87e39..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2011 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.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.provider.Telephony.Sms.Intents; -import android.util.Log; - -/** - * Monitors the device and ICC storage, and sends the appropriate events. - * - * This code was formerly part of {@link SMSDispatcher}, and has been moved - * into a separate class to support instantiation of multiple SMSDispatchers on - * dual-mode devices that require support for both 3GPP and 3GPP2 format messages. - */ -public final class SmsStorageMonitor extends Handler { - private static final String TAG = "SmsStorageMonitor"; - - /** SIM/RUIM storage is full */ - private static final int EVENT_ICC_FULL = 1; - - /** Memory status reporting is acknowledged by RIL */ - private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2; - - /** Radio is ON */ - private static final int EVENT_RADIO_ON = 3; - - /** Context from phone object passed to constructor. */ - private final Context mContext; - - /** Wake lock to ensure device stays awake while dispatching the SMS intent. */ - private PowerManager.WakeLock mWakeLock; - - private boolean mReportMemoryStatusPending; - - final CommandsInterface mCm; // accessed from inner class - boolean mStorageAvailable = true; // accessed from inner class - - /** - * Hold the wake lock for 5 seconds, which should be enough time for - * any receiver(s) to grab its own wake lock. - */ - private static final int WAKE_LOCK_TIMEOUT = 5000; - - /** - * Creates an SmsStorageMonitor and registers for events. - * @param phone the Phone to use - */ - public SmsStorageMonitor(PhoneBase phone) { - mContext = phone.getContext(); - mCm = phone.mCM; - - createWakelock(); - - mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null); - mCm.registerForOn(this, EVENT_RADIO_ON, null); - - // Register for device storage intents. Use these to notify the RIL - // that storage for SMS is or is not available. - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); - mContext.registerReceiver(mResultReceiver, filter); - } - - public void dispose() { - mCm.unSetOnIccSmsFull(this); - mCm.unregisterForOn(this); - mContext.unregisterReceiver(mResultReceiver); - } - - /** - * 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_ICC_FULL: - handleIccFull(); - break; - - case EVENT_REPORT_MEMORY_STATUS_DONE: - ar = (AsyncResult) msg.obj; - if (ar.exception != null) { - mReportMemoryStatusPending = true; - Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = " - + mStorageAvailable); - } else { - mReportMemoryStatusPending = false; - } - break; - - case EVENT_RADIO_ON: - if (mReportMemoryStatusPending) { - Log.v(TAG, "Sending pending memory status report : mStorageAvailable = " - + mStorageAvailable); - mCm.reportSmsMemoryStatus(mStorageAvailable, - obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); - } - break; - } - } - - private void createWakelock() { - PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor"); - mWakeLock.setReferenceCounted(true); - } - - /** - * Called when SIM_FULL message is received from the RIL. Notifies interested - * parties that SIM storage for SMS messages is full. - */ - private void handleIccFull() { - // broadcast SIM_FULL intent - Intent intent = new Intent(Intents.SIM_FULL_ACTION); - mWakeLock.acquire(WAKE_LOCK_TIMEOUT); - mContext.sendBroadcast(intent, SMSDispatcher.RECEIVE_SMS_PERMISSION); - } - - /** Returns whether or not there is storage available for an incoming SMS. */ - public boolean isStorageAvailable() { - return mStorageAvailable; - } - - private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) { - mStorageAvailable = false; - mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); - } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) { - mStorageAvailable = true; - mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); - } - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java deleted file mode 100644 index 1804d97dee59..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (C) 2011 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.content.ContentResolver; -import android.content.Context; -import android.content.res.XmlResourceParser; -import android.database.ContentObserver; -import android.os.Handler; -import android.os.Message; -import android.provider.Settings; -import android.telephony.PhoneNumberUtils; -import android.util.Log; - -import com.android.internal.util.XmlUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * Implement the per-application based SMS control, which limits the number of - * SMS/MMS messages an app can send in the checking period. - * - * This code was formerly part of {@link SMSDispatcher}, and has been moved - * into a separate class to support instantiation of multiple SMSDispatchers on - * dual-mode devices that require support for both 3GPP and 3GPP2 format messages. - */ -public class SmsUsageMonitor { - private static final String TAG = "SmsUsageMonitor"; - private static final boolean DBG = true; - private static final boolean VDBG = false; - - /** Default checking period for SMS sent without user permission. */ - private static final int DEFAULT_SMS_CHECK_PERIOD = 1800000; // 30 minutes - - /** Default number of SMS sent in checking period without user permission. */ - private static final int DEFAULT_SMS_MAX_COUNT = 30; - - /** Return value from {@link #checkDestination} for regular phone numbers. */ - static final int CATEGORY_NOT_SHORT_CODE = 0; - - /** Return value from {@link #checkDestination} for free (no cost) short codes. */ - static final int CATEGORY_FREE_SHORT_CODE = 1; - - /** Return value from {@link #checkDestination} for standard rate (non-premium) short codes. */ - static final int CATEGORY_STANDARD_SHORT_CODE = 2; - - /** Return value from {@link #checkDestination} for possible premium short codes. */ - static final int CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; - - /** Return value from {@link #checkDestination} for premium short codes. */ - static final int CATEGORY_PREMIUM_SHORT_CODE = 4; - - private final int mCheckPeriod; - private final int mMaxAllowed; - - private final HashMap> mSmsStamp = - new HashMap>(); - - /** Context for retrieving regexes from XML resource. */ - private final Context mContext; - - /** Country code for the cached short code pattern matcher. */ - private String mCurrentCountry; - - /** Cached short code pattern matcher for {@link #mCurrentCountry}. */ - private ShortCodePatternMatcher mCurrentPatternMatcher; - - /** Cached short code regex patterns from secure settings for {@link #mCurrentCountry}. */ - private String mSettingsShortCodePatterns; - - /** Handler for responding to content observer updates. */ - private final SettingsObserverHandler mSettingsObserverHandler; - - /** XML tag for root element. */ - private static final String TAG_SHORTCODES = "shortcodes"; - - /** XML tag for short code patterns for a specific country. */ - private static final String TAG_SHORTCODE = "shortcode"; - - /** XML attribute for the country code. */ - private static final String ATTR_COUNTRY = "country"; - - /** XML attribute for the short code regex pattern. */ - private static final String ATTR_PATTERN = "pattern"; - - /** XML attribute for the premium short code regex pattern. */ - private static final String ATTR_PREMIUM = "premium"; - - /** XML attribute for the free short code regex pattern. */ - private static final String ATTR_FREE = "free"; - - /** XML attribute for the standard rate short code regex pattern. */ - private static final String ATTR_STANDARD = "standard"; - - /** - * SMS short code regex pattern matcher for a specific country. - */ - private static final class ShortCodePatternMatcher { - private final Pattern mShortCodePattern; - private final Pattern mPremiumShortCodePattern; - private final Pattern mFreeShortCodePattern; - private final Pattern mStandardShortCodePattern; - - ShortCodePatternMatcher(String shortCodeRegex, String premiumShortCodeRegex, - String freeShortCodeRegex, String standardShortCodeRegex) { - mShortCodePattern = (shortCodeRegex != null ? Pattern.compile(shortCodeRegex) : null); - mPremiumShortCodePattern = (premiumShortCodeRegex != null ? - Pattern.compile(premiumShortCodeRegex) : null); - mFreeShortCodePattern = (freeShortCodeRegex != null ? - Pattern.compile(freeShortCodeRegex) : null); - mStandardShortCodePattern = (standardShortCodeRegex != null ? - Pattern.compile(standardShortCodeRegex) : null); - } - - int getNumberCategory(String phoneNumber) { - if (mFreeShortCodePattern != null && mFreeShortCodePattern.matcher(phoneNumber) - .matches()) { - return CATEGORY_FREE_SHORT_CODE; - } - if (mStandardShortCodePattern != null && mStandardShortCodePattern.matcher(phoneNumber) - .matches()) { - return CATEGORY_STANDARD_SHORT_CODE; - } - if (mPremiumShortCodePattern != null && mPremiumShortCodePattern.matcher(phoneNumber) - .matches()) { - return CATEGORY_PREMIUM_SHORT_CODE; - } - if (mShortCodePattern != null && mShortCodePattern.matcher(phoneNumber).matches()) { - return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE; - } - return CATEGORY_NOT_SHORT_CODE; - } - } - - /** - * Observe the secure setting for updated regex patterns. - */ - private static class SettingsObserver extends ContentObserver { - private final int mWhat; - private final Handler mHandler; - - SettingsObserver(Handler handler, int what) { - super(handler); - mHandler = handler; - mWhat = what; - } - - @Override - public void onChange(boolean selfChange) { - mHandler.obtainMessage(mWhat).sendToTarget(); - } - } - - /** - * Handler to update regex patterns when secure setting for the current country is updated. - */ - private class SettingsObserverHandler extends Handler { - /** Current content observer, or null. */ - SettingsObserver mSettingsObserver; - - /** Current country code to watch for settings updates. */ - private String mCountryIso; - - /** Request to start observing a secure setting. */ - static final int OBSERVE_SETTING = 1; - - /** Handler event for updated secure settings. */ - static final int SECURE_SETTINGS_CHANGED = 2; - - /** Send a message to this handler requesting to observe the setting for a new country. */ - void observeSettingForCountry(String countryIso) { - obtainMessage(OBSERVE_SETTING, countryIso).sendToTarget(); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case OBSERVE_SETTING: - if (msg.obj != null && msg.obj instanceof String) { - mCountryIso = (String) msg.obj; - String settingName = getSettingNameForCountry(mCountryIso); - ContentResolver resolver = mContext.getContentResolver(); - - if (mSettingsObserver != null) { - if (VDBG) log("Unregistering old content observer"); - resolver.unregisterContentObserver(mSettingsObserver); - } - - mSettingsObserver = new SettingsObserver(this, SECURE_SETTINGS_CHANGED); - resolver.registerContentObserver( - Settings.Secure.getUriFor(settingName), false, mSettingsObserver); - if (VDBG) log("Registered content observer for " + settingName); - } - break; - - case SECURE_SETTINGS_CHANGED: - loadPatternsFromSettings(mCountryIso); - break; - } - } - } - - /** - * Create SMS usage monitor. - * @param context the context to use to load resources and get TelephonyManager service - */ - public SmsUsageMonitor(Context context) { - mContext = context; - ContentResolver resolver = context.getContentResolver(); - - mMaxAllowed = Settings.Secure.getInt(resolver, - Settings.Secure.SMS_OUTGOING_CHECK_MAX_COUNT, - DEFAULT_SMS_MAX_COUNT); - - mCheckPeriod = Settings.Secure.getInt(resolver, - Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS, - DEFAULT_SMS_CHECK_PERIOD); - - mSettingsObserverHandler = new SettingsObserverHandler(); - } - - /** - * Return a pattern matcher object for the specified country. - * @param country the country to search for - * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found - */ - private ShortCodePatternMatcher getPatternMatcher(String country) { - int id = com.android.internal.R.xml.sms_short_codes; - XmlResourceParser parser = mContext.getResources().getXml(id); - - try { - return getPatternMatcher(country, parser); - } catch (XmlPullParserException e) { - Log.e(TAG, "XML parser exception reading short code pattern resource", e); - } catch (IOException e) { - Log.e(TAG, "I/O exception reading short code pattern resource", e); - } finally { - parser.close(); - } - return null; // country not found - } - - /** - * Return a pattern matcher object for the specified country from a secure settings string. - * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found - */ - private static ShortCodePatternMatcher getPatternMatcher(String country, String settingsPattern) { - // embed pattern tag into an XML document. - String document = "" + settingsPattern + ""; - if (VDBG) log("loading updated patterns from: " + document); - - try { - XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); - XmlPullParser parser = factory.newPullParser(); - parser.setInput(new StringReader(document)); - return getPatternMatcher(country, parser); - } catch (XmlPullParserException e) { - Log.e(TAG, "XML parser exception reading short code pattern from settings", e); - } catch (IOException e) { - Log.e(TAG, "I/O exception reading short code pattern from settings", e); - } - return null; // country not found - } - - /** - * Return a pattern matcher object for the specified country and pattern XML parser. - * @param country the country to search for - * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found - */ - private static ShortCodePatternMatcher getPatternMatcher(String country, XmlPullParser parser) - throws XmlPullParserException, IOException - { - XmlUtils.beginDocument(parser, TAG_SHORTCODES); - - while (true) { - XmlUtils.nextElement(parser); - - String element = parser.getName(); - if (element == null) break; - - if (element.equals(TAG_SHORTCODE)) { - String currentCountry = parser.getAttributeValue(null, ATTR_COUNTRY); - if (country.equals(currentCountry)) { - String pattern = parser.getAttributeValue(null, ATTR_PATTERN); - String premium = parser.getAttributeValue(null, ATTR_PREMIUM); - String free = parser.getAttributeValue(null, ATTR_FREE); - String standard = parser.getAttributeValue(null, ATTR_STANDARD); - return new ShortCodePatternMatcher(pattern, premium, free, standard); - } - } else { - Log.e(TAG, "Error: skipping unknown XML tag " + element); - } - } - return null; // country not found - } - - /** Clear the SMS application list for disposal. */ - void dispose() { - mSmsStamp.clear(); - } - - /** - * Check to see if an application is allowed to send new SMS messages, and confirm with - * user if the send limit was reached or if a non-system app is potentially sending to a - * premium SMS short code or number. - * - * @param appName the package name of the app requesting to send an SMS - * @param smsWaiting the number of new messages desired to send - * @return true if application is allowed to send the requested number - * of new sms messages - */ - public boolean check(String appName, int smsWaiting) { - synchronized (mSmsStamp) { - removeExpiredTimestamps(); - - ArrayList sentList = mSmsStamp.get(appName); - if (sentList == null) { - sentList = new ArrayList(); - mSmsStamp.put(appName, sentList); - } - - return isUnderLimit(sentList, smsWaiting); - } - } - - /** - * Check if the destination is a possible premium short code. - * NOTE: the caller is expected to strip non-digits from the destination number with - * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method. - * This happens in {@link SMSDispatcher#sendRawPdu} so that we use the same phone number - * for testing and in the user confirmation dialog if the user needs to confirm the number. - * This makes it difficult for malware to fool the user or the short code pattern matcher - * by using non-ASCII characters to make the number appear to be different from the real - * destination phone number. - * - * @param destAddress the destination address to test for possible short code - * @return {@link #CATEGORY_NOT_SHORT_CODE}, {@link #CATEGORY_FREE_SHORT_CODE}, - * {@link #CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE}, or {@link #CATEGORY_PREMIUM_SHORT_CODE}. - */ - public int checkDestination(String destAddress, String countryIso) { - synchronized (mSettingsObserverHandler) { - // always allow emergency numbers - if (PhoneNumberUtils.isEmergencyNumber(destAddress, countryIso)) { - return CATEGORY_NOT_SHORT_CODE; - } - - ShortCodePatternMatcher patternMatcher = null; - - if (countryIso != null) { - // query secure settings and initialize content observer for updated regex patterns - if (mCurrentCountry == null || !countryIso.equals(mCurrentCountry)) { - loadPatternsFromSettings(countryIso); - mSettingsObserverHandler.observeSettingForCountry(countryIso); - } - - if (countryIso.equals(mCurrentCountry)) { - patternMatcher = mCurrentPatternMatcher; - } else { - patternMatcher = getPatternMatcher(countryIso); - mCurrentCountry = countryIso; - mCurrentPatternMatcher = patternMatcher; // may be null if not found - } - } - - if (patternMatcher != null) { - return patternMatcher.getNumberCategory(destAddress); - } else { - // Generic rule: numbers of 5 digits or less are considered potential short codes - Log.e(TAG, "No patterns for \"" + countryIso + "\": using generic short code rule"); - if (destAddress.length() <= 5) { - return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE; - } else { - return CATEGORY_NOT_SHORT_CODE; - } - } - } - } - - private static String getSettingNameForCountry(String countryIso) { - return Settings.Secure.SMS_SHORT_CODES_PREFIX + countryIso; - } - - /** - * Load regex patterns from secure settings if present. - * @param countryIso the country to search for - */ - void loadPatternsFromSettings(String countryIso) { - synchronized (mSettingsObserverHandler) { - if (VDBG) log("loadPatternsFromSettings(" + countryIso + ") called"); - String settingsPatterns = Settings.Secure.getString( - mContext.getContentResolver(), getSettingNameForCountry(countryIso)); - if (settingsPatterns != null && !settingsPatterns.equals( - mSettingsShortCodePatterns)) { - // settings pattern string has changed: update the pattern matcher - mSettingsShortCodePatterns = settingsPatterns; - ShortCodePatternMatcher matcher = getPatternMatcher(countryIso, settingsPatterns); - if (matcher != null) { - mCurrentCountry = countryIso; - mCurrentPatternMatcher = matcher; - } - } else if (settingsPatterns == null && mSettingsShortCodePatterns != null) { - // pattern string was removed: caller will load default patterns from XML resource - mCurrentCountry = null; - mCurrentPatternMatcher = null; - mSettingsShortCodePatterns = null; - } - } - } - - /** - * Remove keys containing only old timestamps. This can happen if an SMS app is used - * to send messages and then uninstalled. - */ - private void removeExpiredTimestamps() { - long beginCheckPeriod = System.currentTimeMillis() - mCheckPeriod; - - synchronized (mSmsStamp) { - Iterator>> iter = mSmsStamp.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry> entry = iter.next(); - ArrayList oldList = entry.getValue(); - if (oldList.isEmpty() || oldList.get(oldList.size() - 1) < beginCheckPeriod) { - iter.remove(); - } - } - } - } - - private boolean isUnderLimit(ArrayList sent, int smsWaiting) { - Long ct = System.currentTimeMillis(); - long beginCheckPeriod = ct - mCheckPeriod; - - if (VDBG) log("SMS send size=" + sent.size() + " time=" + ct); - - while (!sent.isEmpty() && sent.get(0) < beginCheckPeriod) { - sent.remove(0); - } - - if ((sent.size() + smsWaiting) <= mMaxAllowed) { - for (int i = 0; i < smsWaiting; i++ ) { - sent.add(ct); - } - return true; - } - return false; - } - - private static void log(String msg) { - Log.d(TAG, msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java b/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java deleted file mode 100644 index a122e681584f..000000000000 --- a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.util.Log; - -import com.android.internal.telephony.Phone; - -/** - * Utilities that check if the phone supports specified capabilities. - */ -public class TelephonyCapabilities { - private static final String LOG_TAG = "TelephonyCapabilities"; - - /** This class is never instantiated. */ - private TelephonyCapabilities() { - } - - /** - * Return true if the current phone supports ECM ("Emergency Callback - * Mode"), which is a feature where the device goes into a special - * state for a short period of time after making an outgoing emergency - * call. - * - * (On current devices, that state lasts 5 minutes. It prevents data - * usage by other apps, to avoid conflicts with any possible incoming - * calls. It also puts up a notification in the status bar, showing a - * countdown while ECM is active, and allowing the user to exit ECM.) - * - * Currently this is assumed to be true for CDMA phones, and false - * otherwise. - */ - public static boolean supportsEcm(Phone phone) { - return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - } - - /** - * Return true if the current phone supports Over The Air Service - * Provisioning (OTASP) - * - * Currently this is assumed to be true for CDMA phones, and false - * otherwise. - * - * TODO: Watch out: this is also highly carrier-specific, since the - * OTASP procedure is different from one carrier to the next, *and* the - * different carriers may want very different onscreen UI as well. - * The procedure may even be different for different devices with the - * same carrier. - * - * So we eventually will need a much more flexible, pluggable design. - * This method here is just a placeholder to reduce hardcoded - * "if (CDMA)" checks sprinkled throughout the phone app. - */ - public static boolean supportsOtasp(Phone phone) { - return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - } - - /** - * Return true if the current phone can retrieve the voice message count. - * - * Currently this is assumed to be true on CDMA phones and false otherwise. - */ - public static boolean supportsVoiceMessageCount(Phone phone) { - return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA); - } - - /** - * Return true if this phone allows the user to select which - * network to use. - * - * Currently this is assumed to be true only on GSM phones. - * - * TODO: Should CDMA phones allow this as well? - */ - public static boolean supportsNetworkSelection(Phone phone) { - return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM); - } - - /** - * Returns a resource ID for a label to use when displaying the - * "device id" of the current device. (This is currently used as the - * title of the "device id" dialog.) - * - * This is specific to the device's telephony technology: the device - * id is called "IMEI" on GSM phones and "MEID" on CDMA phones. - */ - public static int getDeviceIdLabel(Phone phone) { - if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM) { - return com.android.internal.R.string.imei; - } else if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { - return com.android.internal.R.string.meid; - } else { - Log.w(LOG_TAG, "getDeviceIdLabel: no known label for phone " - + phone.getPhoneName()); - return 0; - } - } - - /** - * Return true if the current phone supports the ability to explicitly - * manage the state of a conference call (i.e. view the participants, - * and hangup or separate individual callers.) - * - * The in-call screen's "Manage conference" UI is available only on - * devices that support this feature. - * - * Currently this is assumed to be true on GSM phones and false otherwise. - */ - public static boolean supportsConferenceCallManagement(Phone phone) { - return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM) - || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP)); - } - - /** - * Return true if the current phone supports explicit "Hold" and - * "Unhold" actions for an active call. (If so, the in-call UI will - * provide onscreen "Hold" / "Unhold" buttons.) - * - * Currently this is assumed to be true on GSM phones and false - * otherwise. (In particular, CDMA has no concept of "putting a call - * on hold.") - */ - public static boolean supportsHoldAndUnhold(Phone phone) { - return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM) - || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP)); - } - - /** - * Return true if the current phone supports distinct "Answer & Hold" - * and "Answer & End" behaviors in the call-waiting scenario. If so, - * the in-call UI may provide separate buttons or menu items for these - * two actions. - * - * Currently this is assumed to be true on GSM phones and false - * otherwise. (In particular, CDMA has no concept of explicitly - * managing the background call, or "putting a call on hold.") - * - * TODO: It might be better to expose this capability in a more - * generic form, like maybe "supportsExplicitMultipleLineManagement()" - * rather than focusing specifically on call-waiting behavior. - */ - public static boolean supportsAnswerAndHold(Phone phone) { - return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM) - || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP)); - } - - /** - * Return true if phones with the given phone type support ADN - * (Abbreviated Dialing Numbers). - * - * Currently this returns true when the phone type is GSM - * ({@link Phone#PHONE_TYPE_GSM}). - * - * This is using int for an argument for letting apps outside - * Phone process access to it, while other methods in this class is - * using Phone object. - * - * TODO: Theoretically phones other than GSM may have the ADN capability. - * Consider having better check here, or have better capability as part - * of public API, with which the argument should be replaced with - * something more appropriate. - */ - public static boolean supportsAdn(int phoneType) { - return phoneType == Phone.PHONE_TYPE_GSM; - } - - /** - * Returns true if the device can distinguish the phone's dialing state - * (Call.State.DIALING/ALERTING) and connected state (Call.State.ACTIVE). - * - * Currently this returns true for GSM phones as we cannot know when a CDMA - * phone has transitioned from dialing/active to connected. - */ - public static boolean canDistinguishDialingAndConnected(int phoneType) { - return phoneType == Phone.PHONE_TYPE_GSM; - } -} diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index 3355e8aee718..3cfd0bf85ebf 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -230,10 +230,49 @@ public class TelephonyIntents { *

. * This is to pop up a notice to show user that the phone is in emergency callback mode * and atacalls and outgoing sms are blocked. - * + * *

This is a protected intent that can only be sent * by the system. */ public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS"; + + + /** + * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are + * of the form *#*##*#*. The intent will have the data URI:

+ * + *

android_secret_code://<code>

+ */ + public static final String SECRET_CODE_ACTION = + "android.provider.Telephony.SECRET_CODE"; + + /** + * Broadcast Action: The Service Provider string(s) have been updated. Activities or + * services that use these strings should update their display. + * The intent will have the following extra values:

+ *
    + *
  • showPlmn - Boolean that indicates whether the PLMN should be shown.
  • + *
  • plmn - The operator name of the registered network, as a string.
  • + *
  • showSpn - Boolean that indicates whether the SPN should be shown.
  • + *
  • spn - The service provider name, as a string.
  • + *
+ * Note that showPlmn may indicate that plmn should be displayed, even + * though the value for plmn is null. This can happen, for example, if the phone + * has not registered to a network yet. In this case the receiver may substitute an + * appropriate placeholder string (eg, "No service"). + * + * It is recommended to display plmn before / above spn if + * both are displayed. + * + *

Note this is a protected intent that can only be sent + * by the system. + */ + public static final String SPN_STRINGS_UPDATED_ACTION = + "android.provider.Telephony.SPN_STRINGS_UPDATED"; + + public static final String EXTRA_SHOW_PLMN = "showPlmn"; + public static final String EXTRA_PLMN = "plmn"; + public static final String EXTRA_SHOW_SPN = "showSpn"; + public static final String EXTRA_SPN = "spn"; } diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java deleted file mode 100644 index 801b84563c98..000000000000 --- a/telephony/java/com/android/internal/telephony/UUSInfo.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -public class UUSInfo { - - /* - * User-to-User signaling Info activation types derived from 3GPP 23.087 - * v8.0 - */ - - public static final int UUS_TYPE1_IMPLICIT = 0; - - public static final int UUS_TYPE1_REQUIRED = 1; - - public static final int UUS_TYPE1_NOT_REQUIRED = 2; - - public static final int UUS_TYPE2_REQUIRED = 3; - - public static final int UUS_TYPE2_NOT_REQUIRED = 4; - - public static final int UUS_TYPE3_REQUIRED = 5; - - public static final int UUS_TYPE3_NOT_REQUIRED = 6; - - /* - * User-to-User Signaling Information data coding schemes. Possible values - * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have - * been specified in section 10.5.4.25 of 3GPP TS 24.008 - */ - - public static final int UUS_DCS_USP = 0; /* User specified protocol */ - - public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */ - - public static final int UUS_DCS_X244 = 2; /* X.244 */ - - public static final int UUS_DCS_RMCF = 3; /* - * Reserved for system management - * convergence function - */ - - public static final int UUS_DCS_IA5c = 4; /* IA5 characters */ - - private int uusType; - - private int uusDcs; - - private byte[] uusData; - - public UUSInfo() { - this.uusType = UUS_TYPE1_IMPLICIT; - this.uusDcs = UUS_DCS_IA5c; - this.uusData = null; - } - - public UUSInfo(int uusType, int uusDcs, byte[] uusData) { - this.uusType = uusType; - this.uusDcs = uusDcs; - this.uusData = uusData; - } - - public int getDcs() { - return uusDcs; - } - - public void setDcs(int uusDcs) { - this.uusDcs = uusDcs; - } - - public int getType() { - return uusType; - } - - public void setType(int uusType) { - this.uusType = uusType; - } - - public byte[] getUserData() { - return uusData; - } - - public void setUserData(byte[] uusData) { - this.uusData = uusData; - } -} diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java deleted file mode 100644 index 11e5ff9e0858..000000000000 --- a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -/** - * WapPushManager constant value definitions - */ -public class WapPushManagerParams { - /** - * Application type activity - */ - public static final int APP_TYPE_ACTIVITY = 0; - - /** - * Application type service - */ - public static final int APP_TYPE_SERVICE = 1; - - /** - * Process Message return value - * Message is handled - */ - public static final int MESSAGE_HANDLED = 0x1; - - /** - * Process Message return value - * Application ID or content type was not found in the application ID table - */ - public static final int APP_QUERY_FAILED = 0x2; - - /** - * Process Message return value - * Receiver application signature check failed - */ - public static final int SIGNATURE_NO_MATCH = 0x4; - - /** - * Process Message return value - * Receiver application was not found - */ - public static final int INVALID_RECEIVER_NAME = 0x8; - - /** - * Process Message return value - * Unknown exception - */ - public static final int EXCEPTION_CAUGHT = 0x10; - - /** - * Process Message return value - * Need further processing after WapPushManager message processing - */ - public static final int FURTHER_PROCESSING = 0x8000; - -} - diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java deleted file mode 100755 index e2779dc13380..000000000000 --- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.internal.telephony; - -import android.app.Activity; -import android.content.Context; -import android.content.ComponentName; -import android.content.Intent; -import android.content.ServiceConnection; -import android.provider.Telephony; -import android.provider.Telephony.Sms.Intents; -import android.util.Log; -import android.os.IBinder; -import android.os.RemoteException; - -/** - * WAP push handler class. - * - * @hide - */ -public class WapPushOverSms { - private static final String LOG_TAG = "WAP PUSH"; - - private final Context mContext; - private WspTypeDecoder pduDecoder; - private SMSDispatcher mSmsDispatcher; - - /** - * Hold the wake lock for 5 seconds, which should be enough time for - * any receiver(s) to grab its own wake lock. - */ - private final int WAKE_LOCK_TIMEOUT = 5000; - - private final int BIND_RETRY_INTERVAL = 1000; - /** - * A handle to WapPushManager interface - */ - private WapPushConnection mWapConn = null; - private class WapPushConnection implements ServiceConnection { - private IWapPushManager mWapPushMan; - private Context mOwner; - - public WapPushConnection(Context ownerContext) { - mOwner = ownerContext; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - mWapPushMan = IWapPushManager.Stub.asInterface(service); - if (false) Log.v(LOG_TAG, "wappush manager connected to " + - mOwner.hashCode()); - } - - public void onServiceDisconnected(ComponentName name) { - mWapPushMan = null; - if (false) Log.v(LOG_TAG, "wappush manager disconnected."); - // WapPushManager must be always attached. - rebindWapPushManager(); - } - - /** - * bind WapPushManager - */ - public void bindWapPushManager() { - if (mWapPushMan != null) return; - - final ServiceConnection wapPushConnection = this; - - mOwner.bindService(new Intent(IWapPushManager.class.getName()), - wapPushConnection, Context.BIND_AUTO_CREATE); - } - - /** - * rebind WapPushManager - * This method is called when WapPushManager is disconnected unexpectedly. - */ - private void rebindWapPushManager() { - if (mWapPushMan != null) return; - - final ServiceConnection wapPushConnection = this; - new Thread() { - public void run() { - while (mWapPushMan == null) { - mOwner.bindService(new Intent(IWapPushManager.class.getName()), - wapPushConnection, Context.BIND_AUTO_CREATE); - try { - Thread.sleep(BIND_RETRY_INTERVAL); - } catch (InterruptedException e) { - if (false) Log.v(LOG_TAG, "sleep interrupted."); - } - } - } - }.start(); - } - - /** - * Returns interface to WapPushManager - */ - public IWapPushManager getWapPushManager() { - return mWapPushMan; - } - } - - public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) { - mSmsDispatcher = smsDispatcher; - mContext = phone.getContext(); - mWapConn = new WapPushConnection(mContext); - mWapConn.bindWapPushManager(); - } - - - /** - * 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 - * @return a result code from {@link Telephony.Sms.Intents}, or - * {@link Activity#RESULT_OK} if the message has been broadcast - * to applications - */ - public int dispatchWapPdu(byte[] pdu) { - - if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu)); - - int index = 0; - int transactionId = pdu[index++] & 0xFF; - int pduType = pdu[index++] & 0xFF; - int headerLength = 0; - - if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) && - (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) { - if (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType); - return Intents.RESULT_SMS_HANDLED; - } - - pduDecoder = new WspTypeDecoder(pdu); - - /** - * Parse HeaderLen(unsigned integer). - * From wap-230-wsp-20010705-a section 8.1.2 - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - if (pduDecoder.decodeUintvarInteger(index) == false) { - if (false) Log.w(LOG_TAG, "Received PDU. Header Length error."); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - headerLength = (int)pduDecoder.getValue32(); - index += pduDecoder.getDecodedDataLength(); - - int headerStartIndex = index; - - /** - * Parse Content-Type. - * From wap-230-wsp-20010705-a section 8.4.2.24 - * - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - * Value-length = Short-length | (Length-quote Length) - * Short-length = (octet <= WAP_PDU_SHORT_LENGTH_MAX) - * Length-quote = (WAP_PDU_LENGTH_QUOTE) - * Length = Uintvar-integer - */ - if (pduDecoder.decodeContentType(index) == false) { - if (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error."); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - - String mimeType = pduDecoder.getValueString(); - long binaryContentType = pduDecoder.getValue32(); - index += pduDecoder.getDecodedDataLength(); - - byte[] header = new byte[headerLength]; - System.arraycopy(pdu, headerStartIndex, header, 0, header.length); - - byte[] intentData; - - if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) { - intentData = pdu; - } else { - int dataIndex = headerStartIndex + headerLength; - intentData = new byte[pdu.length - dataIndex]; - System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length); - } - - /** - * Seek for application ID field in WSP header. - * If application ID is found, WapPushManager substitute the message - * processing. Since WapPushManager is optional module, if WapPushManager - * is not found, legacy message processing will be continued. - */ - if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) { - index = (int) pduDecoder.getValue32(); - pduDecoder.decodeXWapApplicationId(index); - String wapAppId = pduDecoder.getValueString(); - if (wapAppId == null) { - wapAppId = Integer.toString((int) pduDecoder.getValue32()); - } - - String contentType = ((mimeType == null) ? - Long.toString(binaryContentType) : mimeType); - if (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType); - - try { - boolean processFurther = true; - IWapPushManager wapPushMan = mWapConn.getWapPushManager(); - - if (wapPushMan == null) { - if (false) Log.w(LOG_TAG, "wap push manager not found!"); - } else { - Intent intent = new Intent(); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("header", header); - intent.putExtra("data", intentData); - intent.putExtra("contentTypeParameters", - pduDecoder.getContentParameters()); - - int procRet = wapPushMan.processMessage(wapAppId, contentType, intent); - if (false) Log.v(LOG_TAG, "procRet:" + procRet); - if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0 - && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) { - processFurther = false; - } - } - if (!processFurther) { - return Intents.RESULT_SMS_HANDLED; - } - } catch (RemoteException e) { - if (false) Log.w(LOG_TAG, "remote func failed..."); - } - } - if (false) Log.v(LOG_TAG, "fall back to existing handler"); - - if (mimeType == null) { - if (false) Log.w(LOG_TAG, "Header Content-Type error."); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - - String permission; - - if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) { - permission = "android.permission.RECEIVE_MMS"; - } else { - permission = "android.permission.RECEIVE_WAP_PUSH"; - } - - Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); - intent.setType(mimeType); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("header", header); - intent.putExtra("data", intentData); - intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters()); - - mSmsDispatcher.dispatch(intent, permission); - - return Activity.RESULT_OK; - } -} diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java deleted file mode 100755 index 73260fbc6974..000000000000 --- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import java.util.HashMap; - -/** - * Implement the WSP data type decoder. - * - * @hide - */ -public class WspTypeDecoder { - - private static final int WAP_PDU_SHORT_LENGTH_MAX = 30; - private static final int WAP_PDU_LENGTH_QUOTE = 31; - - public static final int PDU_TYPE_PUSH = 0x06; - public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07; - - private final static HashMap WELL_KNOWN_MIME_TYPES = - new HashMap(); - - private final static HashMap WELL_KNOWN_PARAMETERS = - new HashMap(); - - public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f; - private static final int Q_VALUE = 0x00; - - static { - WELL_KNOWN_MIME_TYPES.put(0x00, "*/*"); - WELL_KNOWN_MIME_TYPES.put(0x01, "text/*"); - WELL_KNOWN_MIME_TYPES.put(0x02, "text/html"); - WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain"); - WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml"); - WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml"); - WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar"); - WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard"); - WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml"); - WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript"); - WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event"); - WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*"); - WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed"); - WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data"); - WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes"); - WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative"); - WELL_KNOWN_MIME_TYPES.put(0x10, "application/*"); - WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm"); - WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded"); - WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc"); - WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc"); - WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc"); - WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc"); - WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof"); - WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate"); - WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate"); - WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert"); - WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert"); - WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*"); - WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif"); - WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg"); - WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff"); - WELL_KNOWN_MIME_TYPES.put(0x20, "image/png"); - WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp"); - WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*"); - WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed"); - WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data"); - WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges"); - WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative"); - WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml"); - WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml"); - WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert"); - WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert"); - WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert"); - WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si"); - WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic"); - WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl"); - WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc"); - WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co"); - WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc"); - WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related"); - WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia"); - WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml"); - WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime"); - WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate"); - WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate"); - WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response"); - WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml"); - WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml"); - WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css"); - WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message"); - WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate"); - WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml"); - WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml"); - WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification"); - WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml"); - WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir"); - WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml"); - WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message"); - WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content"); - WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml"); - WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml"); - WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification"); - WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*"); - WELL_KNOWN_MIME_TYPES.put(0x50, "video/*"); - WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml"); - WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey"); - WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd"); - WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc"); - - WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal"); - WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri"); - WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set"); - WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng"); - WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml"); - WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar"); - WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard"); - WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response"); - WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml"); - WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip"); - WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf"); - WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub"); - WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init"); - WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml"); - WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2"); - WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml"); - WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2"); - WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap"); - WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml"); - WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid"); - WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger"); - - WELL_KNOWN_PARAMETERS.put(0x00, "Q"); - WELL_KNOWN_PARAMETERS.put(0x01, "Charset"); - WELL_KNOWN_PARAMETERS.put(0x02, "Level"); - WELL_KNOWN_PARAMETERS.put(0x03, "Type"); - WELL_KNOWN_PARAMETERS.put(0x07, "Differences"); - WELL_KNOWN_PARAMETERS.put(0x08, "Padding"); - WELL_KNOWN_PARAMETERS.put(0x09, "Type"); - WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age"); - WELL_KNOWN_PARAMETERS.put(0x10, "Secure"); - WELL_KNOWN_PARAMETERS.put(0x11, "SEC"); - WELL_KNOWN_PARAMETERS.put(0x12, "MAC"); - WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date"); - WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date"); - WELL_KNOWN_PARAMETERS.put(0x15, "Read-date"); - WELL_KNOWN_PARAMETERS.put(0x16, "Size"); - WELL_KNOWN_PARAMETERS.put(0x17, "Name"); - WELL_KNOWN_PARAMETERS.put(0x18, "Filename"); - WELL_KNOWN_PARAMETERS.put(0x19, "Start"); - WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info"); - WELL_KNOWN_PARAMETERS.put(0x1B, "Comment"); - WELL_KNOWN_PARAMETERS.put(0x1C, "Domain"); - WELL_KNOWN_PARAMETERS.put(0x1D, "Path"); - } - - public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc"; - public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message"; - public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification"; - - byte[] wspData; - int dataLength; - long unsigned32bit; - String stringValue; - - HashMap contentParameters; - - public WspTypeDecoder(byte[] pdu) { - wspData = pdu; - } - - /** - * Decode the "Text-string" type for WSP pdu - * - * @param startIndex The starting position of the "Text-string" in this pdu - * - * @return false when error(not a Text-string) occur - * return value can be retrieved by getValueString() method length of data in pdu can be - * retrieved by getDecodedDataLength() method - */ - public boolean decodeTextString(int startIndex) { - int index = startIndex; - while (wspData[index] != 0) { - index++; - } - dataLength = index - startIndex + 1; - if (wspData[startIndex] == 127) { - stringValue = new String(wspData, startIndex + 1, dataLength - 2); - } else { - stringValue = new String(wspData, startIndex, dataLength - 1); - } - return true; - } - - /** - * Decode the "Token-text" type for WSP pdu - * - * @param startIndex The starting position of the "Token-text" in this pdu - * - * @return always true - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeTokenText(int startIndex) { - int index = startIndex; - while (wspData[index] != 0) { - index++; - } - dataLength = index - startIndex + 1; - stringValue = new String(wspData, startIndex, dataLength - 1); - - return true; - } - - /** - * Decode the "Short-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Short-integer" in this pdu - * - * @return false when error(not a Short-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeShortInteger(int startIndex) { - if ((wspData[startIndex] & 0x80) == 0) { - return false; - } - unsigned32bit = wspData[startIndex] & 0x7f; - dataLength = 1; - return true; - } - - /** - * Decode the "Long-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Long-integer" in this pdu - * - * @return false when error(not a Long-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeLongInteger(int startIndex) { - int lengthMultiOctet = wspData[startIndex] & 0xff; - - if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) { - return false; - } - unsigned32bit = 0; - for (int i = 1; i <= lengthMultiOctet; i++) { - unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff); - } - dataLength = 1 + lengthMultiOctet; - return true; - } - - /** - * Decode the "Integer-Value" type for WSP pdu - * - * @param startIndex The starting position of the "Integer-Value" in this pdu - * - * @return false when error(not a Integer-Value) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeIntegerValue(int startIndex) { - if (decodeShortInteger(startIndex) == true) { - return true; - } - return decodeLongInteger(startIndex); - } - - /** - * Decode the "Uintvar-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Uintvar-integer" in this pdu - * - * @return false when error(not a Uintvar-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeUintvarInteger(int startIndex) { - int index = startIndex; - - unsigned32bit = 0; - while ((wspData[index] & 0x80) != 0) { - if ((index - startIndex) >= 4) { - return false; - } - unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); - index++; - } - unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); - dataLength = index - startIndex + 1; - return true; - } - - /** - * Decode the "Value-length" type for WSP pdu - * - * @param startIndex The starting position of the "Value-length" in this pdu - * - * @return false when error(not a Value-length) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeValueLength(int startIndex) { - if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) { - return false; - } - if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) { - unsigned32bit = wspData[startIndex]; - dataLength = 1; - } else { - decodeUintvarInteger(startIndex + 1); - dataLength++; - } - return true; - } - - /** - * Decode the "Extension-media" type for WSP PDU. - * - * @param startIndex The starting position of the "Extension-media" in this PDU. - * - * @return false on error, such as if there is no Extension-media at startIndex. - * Side-effects: updates stringValue (available with - * getValueString()), which will be null on error. The length of the - * data in the PDU is available with getValue32(), 0 on error. - */ - public boolean decodeExtensionMedia(int startIndex) { - int index = startIndex; - dataLength = 0; - stringValue = null; - int length = wspData.length; - boolean rtrn = index < length; - - while (index < length && wspData[index] != 0) { - index++; - } - - dataLength = index - startIndex + 1; - stringValue = new String(wspData, startIndex, dataLength - 1); - - return rtrn; - } - - /** - * Decode the "Constrained-encoding" type for WSP pdu - * - * @param startIndex The starting position of the "Constrained-encoding" in this pdu - * - * @return false when error(not a Constrained-encoding) occur - * return value can be retrieved first by getValueString() and second by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeConstrainedEncoding(int startIndex) { - if (decodeShortInteger(startIndex) == true) { - stringValue = null; - return true; - } - return decodeExtensionMedia(startIndex); - } - - /** - * Decode the "Content-type" type for WSP pdu - * - * @param startIndex The starting position of the "Content-type" in this pdu - * - * @return false when error(not a Content-type) occurs - * If a content type exists in the headers (either as inline string, or as well-known - * value), getValueString() will return it. If a 'well known value' is encountered that - * cannot be mapped to a string mime type, getValueString() will return null, and - * getValue32() will return the unknown content type value. - * length of data in pdu can be retrieved by getDecodedDataLength() method - * Any content type parameters will be accessible via getContentParameters() - */ - public boolean decodeContentType(int startIndex) { - int mediaPrefixLength; - contentParameters = new HashMap(); - - try { - if (decodeValueLength(startIndex) == false) { - boolean found = decodeConstrainedEncoding(startIndex); - if (found) { - expandWellKnownMimeType(); - } - return found; - } - int headersLength = (int) unsigned32bit; - mediaPrefixLength = getDecodedDataLength(); - if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) { - dataLength += mediaPrefixLength; - int readLength = dataLength; - stringValue = null; - expandWellKnownMimeType(); - long wellKnownValue = unsigned32bit; - String mimeType = stringValue; - if (readContentParameters(startIndex + dataLength, - (headersLength - (dataLength - mediaPrefixLength)), 0)) { - dataLength += readLength; - unsigned32bit = wellKnownValue; - stringValue = mimeType; - return true; - } - return false; - } - if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) { - dataLength += mediaPrefixLength; - int readLength = dataLength; - expandWellKnownMimeType(); - long wellKnownValue = unsigned32bit; - String mimeType = stringValue; - if (readContentParameters(startIndex + dataLength, - (headersLength - (dataLength - mediaPrefixLength)), 0)) { - dataLength += readLength; - unsigned32bit = wellKnownValue; - stringValue = mimeType; - return true; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - //something doesn't add up - return false; - } - return false; - } - - private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) { - - int totalRead = 0; - - if (leftToRead > 0) { - byte nextByte = wspData[startIndex]; - String value = null; - String param = null; - if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped - decodeTokenText(startIndex); - param = stringValue; - totalRead += dataLength; - } else { // typed - if (decodeIntegerValue(startIndex)) { - totalRead += dataLength; - int wellKnownParameterValue = (int) unsigned32bit; - param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue); - if (param == null) { - param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue); - } - // special case for the "Q" parameter, value is a uintvar - if (wellKnownParameterValue == Q_VALUE) { - if (decodeUintvarInteger(startIndex + totalRead)) { - totalRead += dataLength; - value = String.valueOf(unsigned32bit); - contentParameters.put(param, value); - return readContentParameters(startIndex + totalRead, leftToRead - - totalRead, accumulator + totalRead); - } else { - return false; - } - } - } else { - return false; - } - } - - if (decodeNoValue(startIndex + totalRead)) { - totalRead += dataLength; - value = null; - } else if (decodeIntegerValue(startIndex + totalRead)) { - totalRead += dataLength; - int intValue = (int) unsigned32bit; - if (intValue == 0) { - value = ""; - } else { - value = String.valueOf(intValue); - } - } else { - decodeTokenText(startIndex + totalRead); - totalRead += dataLength; - value = stringValue; - if (value.startsWith("\"")) { - // quoted string, so remove the quote - value = value.substring(1); - } - } - contentParameters.put(param, value); - return readContentParameters(startIndex + totalRead, leftToRead - totalRead, - accumulator + totalRead); - - } else { - dataLength = accumulator; - return true; - } - } - - /** - * Check if the next byte is No-Value - * - * @param startIndex The starting position of the "Content length" in this pdu - * - * @return true if and only if the next byte is 0x00 - */ - private boolean decodeNoValue(int startIndex) { - if (wspData[startIndex] == 0) { - dataLength = 1; - return true; - } else { - return false; - } - } - - /** - * Populate stringValue with the mime type corresponding to the value in unsigned32bit - * - * Sets unsigned32bit to -1 if stringValue is already populated - */ - private void expandWellKnownMimeType() { - if (stringValue == null) { - int binaryContentType = (int) unsigned32bit; - stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType); - } else { - unsigned32bit = -1; - } - } - - /** - * Decode the "Content length" type for WSP pdu - * - * @param startIndex The starting position of the "Content length" in this pdu - * - * @return false when error(not a Content length) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeContentLength(int startIndex) { - return decodeIntegerValue(startIndex); - } - - /** - * Decode the "Content location" type for WSP pdu - * - * @param startIndex The starting position of the "Content location" in this pdu - * - * @return false when error(not a Content location) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeContentLocation(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * Decode the "X-Wap-Application-Id" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu - * - * @return false when error(not a X-Wap-Application-Id) occur - * return value can be retrieved first by getValueString() and second by getValue32() - * method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeXWapApplicationId(int startIndex) { - if (decodeIntegerValue(startIndex) == true) { - stringValue = null; - return true; - } - return decodeTextString(startIndex); - } - - /** - * Seek for the "X-Wap-Application-Id" field for WSP pdu - * - * @param startIndex The starting position of seek pointer - * @param endIndex Valid seek area end point - * - * @return false when error(not a X-Wap-Application-Id) occur - * return value can be retrieved by getValue32() - */ - public boolean seekXWapApplicationId(int startIndex, int endIndex) { - int index = startIndex; - - try { - for (index = startIndex; index <= endIndex; ) { - /** - * 8.4.1.1 Field name - * Field name is integer or text. - */ - if (decodeIntegerValue(index)) { - int fieldValue = (int) getValue32(); - - if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) { - unsigned32bit = index + 1; - return true; - } - } else { - if (!decodeTextString(index)) return false; - } - index += getDecodedDataLength(); - if (index > endIndex) return false; - - /** - * 8.4.1.2 Field values - * Value Interpretation of First Octet - * 0 - 30 This octet is followed by the indicated number (0 - 30) - of data octets - * 31 This octet is followed by a uintvar, which indicates the number - * of data octets after it - * 32 - 127 The value is a text string, terminated by a zero octet - (NUL character) - * 128 - 255 It is an encoded 7-bit value; this header has no more data - */ - byte val = wspData[index]; - if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) { - index += wspData[index] + 1; - } else if (val == WAP_PDU_LENGTH_QUOTE) { - if (index + 1 >= endIndex) return false; - index++; - if (!decodeUintvarInteger(index)) return false; - index += getDecodedDataLength(); - } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) { - if (!decodeTextString(index)) return false; - index += getDecodedDataLength(); - } else { - index++; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - //seek application ID failed. WSP header might be corrupted - return false; - } - return false; - } - - /** - * Decode the "X-Wap-Content-URI" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu - * - * @return false when error(not a X-Wap-Content-URI) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeXWapContentURI(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * Decode the "X-Wap-Initiator-URI" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu - * - * @return false when error(not a X-Wap-Initiator-URI) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getDecodedDataLength() method - */ - public boolean decodeXWapInitiatorURI(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * The data length of latest operation. - */ - public int getDecodedDataLength() { - return dataLength; - } - - /** - * The 32-bits result of latest operation. - */ - public long getValue32() { - return unsigned32bit; - } - - /** - * The String result of latest operation. - */ - public String getValueString() { - return stringValue; - } - - /** - * Any parameters encountered as part of a decodeContentType() invocation. - * - * @return a map of content parameters keyed by their names, or null if - * decodeContentType() has not been called If any unassigned - * well-known parameters are encountered, the key of the map will be - * 'unassigned/0x...', where '...' is the hex value of the - * unassigned parameter. If a parameter has No-Value the value will be null. - * - */ - public HashMap getContentParameters() { - return contentParameters; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java deleted file mode 100644 index 299e1408f5d1..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/AppInterface.java +++ /dev/null @@ -1,96 +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.cat; - -/** - * Interface for communication between STK App and CAT Telephony - * - * {@hide} - */ -public interface AppInterface { - - /* - * Intent's actions which are broadcasted by the Telephony once a new CAT - * proactive command, session end arrive. - */ - public static final String CAT_CMD_ACTION = - "android.intent.action.stk.command"; - public static final String CAT_SESSION_END_ACTION = - "android.intent.action.stk.session_end"; - - /* - * Callback function from app to telephony to pass a result code and user's - * input back to the ICC. - */ - void onCmdResponse(CatResponseMessage resMsg); - - /* - * Enumeration for representing "Type of Command" of proactive commands. - * Those are the only commands which are supported by the Telephony. Any app - * implementation should support those. - * Refer to ETSI TS 102.223 section 9.4 - */ - public static enum CommandType { - DISPLAY_TEXT(0x21), - GET_INKEY(0x22), - GET_INPUT(0x23), - LAUNCH_BROWSER(0x15), - PLAY_TONE(0x20), - REFRESH(0x01), - SELECT_ITEM(0x24), - SEND_SS(0x11), - SEND_USSD(0x12), - SEND_SMS(0x13), - SEND_DTMF(0x14), - SET_UP_EVENT_LIST(0x05), - SET_UP_IDLE_MODE_TEXT(0x28), - SET_UP_MENU(0x25), - SET_UP_CALL(0x10), - PROVIDE_LOCAL_INFORMATION(0x26), - OPEN_CHANNEL(0x40), - CLOSE_CHANNEL(0x41), - RECEIVE_DATA(0x42), - SEND_DATA(0x43); - - private int mValue; - - CommandType(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - - /** - * 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 - * returned. - */ - public static CommandType fromInt(int value) { - for (CommandType e : CommandType.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java deleted file mode 100644 index 095e65b57ebb..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/BerTlv.java +++ /dev/null @@ -1,123 +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.cat; - -import java.util.List; - -/** - * Class for representing BER-TLV objects. - * - * @see "ETSI TS 102 223 Annex C" for more information. - * - * {@hide} - */ -class BerTlv { - private int mTag = BER_UNKNOWN_TAG; - private List mCompTlvs = null; - - public static final int BER_UNKNOWN_TAG = 0x00; - public static final int BER_PROACTIVE_COMMAND_TAG = 0xd0; - public static final int BER_MENU_SELECTION_TAG = 0xd3; - public static final int BER_EVENT_DOWNLOAD_TAG = 0xd6; - - private BerTlv(int tag, List ctlvs) { - mTag = tag; - mCompTlvs = ctlvs; - } - - /** - * Gets a list of ComprehensionTlv objects contained in this BER-TLV object. - * - * @return A list of COMPREHENSION-TLV object - */ - public List getComprehensionTlvs() { - return mCompTlvs; - } - - /** - * Gets a tag id of the BER-TLV object. - * - * @return A tag integer. - */ - public int getTag() { - return mTag; - } - - /** - * 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 - */ - public static BerTlv decode(byte[] data) throws ResultException { - int curIndex = 0; - int endIndex = data.length; - int tag, length = 0; - - try { - /* tag */ - tag = data[curIndex++] & 0xff; - if (tag == BER_PROACTIVE_COMMAND_TAG) { - /* length */ - int temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "length < 0x80 length=" + Integer.toHexString(length) + - " curIndex=" + curIndex + " endIndex=" + endIndex); - - } - length = temp; - } else { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "Expected first byte to be length or a length tag and < 0x81" + - " byte= " + Integer.toHexString(temp) + " curIndex=" + curIndex + - " endIndex=" + endIndex); - } - } else { - if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) { - tag = BER_UNKNOWN_TAG; - curIndex = 0; - } - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING, - "IndexOutOfBoundsException " + - " curIndex=" + curIndex + " endIndex=" + endIndex); - } catch (ResultException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, e.explanation()); - } - - /* COMPREHENSION-TLVs */ - if (endIndex - curIndex < length) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "Command had extra data endIndex=" + endIndex + " curIndex=" + curIndex + - " length=" + length); - } - - List ctlvs = ComprehensionTlv.decodeMany(data, - curIndex); - - return new BerTlv(tag, ctlvs); - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java deleted file mode 100644 index 48c2e2bab7be..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.cat; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Class used to pass CAT messages from telephony to application. Application - * should call getXXX() to get commands's specific values. - * - */ -public class CatCmdMessage implements Parcelable { - // members - CommandDetails mCmdDet; - private TextMessage mTextMsg; - private Menu mMenu; - private Input mInput; - private BrowserSettings mBrowserSettings = null; - private ToneSettings mToneSettings = null; - private CallSettings mCallSettings = null; - - /* - * Container for Launch Browser command settings. - */ - public class BrowserSettings { - public String url; - public LaunchBrowserMode mode; - } - - /* - * Container for Call Setup command settings. - */ - public class CallSettings { - public TextMessage confirmMsg; - public TextMessage callMsg; - } - - CatCmdMessage(CommandParams cmdParams) { - mCmdDet = cmdParams.cmdDet; - switch(getCmdType()) { - case SET_UP_MENU: - case SELECT_ITEM: - mMenu = ((SelectItemParams) cmdParams).menu; - break; - case DISPLAY_TEXT: - case SET_UP_IDLE_MODE_TEXT: - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - mTextMsg = ((DisplayTextParams) cmdParams).textMsg; - break; - case GET_INPUT: - case GET_INKEY: - mInput = ((GetInputParams) cmdParams).input; - break; - case LAUNCH_BROWSER: - mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg; - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url; - mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode; - break; - case PLAY_TONE: - PlayToneParams params = (PlayToneParams) cmdParams; - mToneSettings = params.settings; - mTextMsg = params.textMsg; - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg; - mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg; - break; - case OPEN_CHANNEL: - case CLOSE_CHANNEL: - case RECEIVE_DATA: - case SEND_DATA: - BIPClientParams param = (BIPClientParams) cmdParams; - mTextMsg = param.textMsg; - break; - } - } - - public CatCmdMessage(Parcel in) { - mCmdDet = in.readParcelable(null); - mTextMsg = in.readParcelable(null); - mMenu = in.readParcelable(null); - mInput = in.readParcelable(null); - switch (getCmdType()) { - case LAUNCH_BROWSER: - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = in.readString(); - mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()]; - break; - case PLAY_TONE: - mToneSettings = in.readParcelable(null); - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = in.readParcelable(null); - mCallSettings.callMsg = in.readParcelable(null); - break; - } - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mCmdDet, 0); - dest.writeParcelable(mTextMsg, 0); - dest.writeParcelable(mMenu, 0); - dest.writeParcelable(mInput, 0); - switch(getCmdType()) { - case LAUNCH_BROWSER: - dest.writeString(mBrowserSettings.url); - dest.writeInt(mBrowserSettings.mode.ordinal()); - break; - case PLAY_TONE: - dest.writeParcelable(mToneSettings, 0); - break; - case SET_UP_CALL: - dest.writeParcelable(mCallSettings.confirmMsg, 0); - dest.writeParcelable(mCallSettings.callMsg, 0); - break; - } - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public CatCmdMessage createFromParcel(Parcel in) { - return new CatCmdMessage(in); - } - - public CatCmdMessage[] newArray(int size) { - return new CatCmdMessage[size]; - } - }; - - public int describeContents() { - return 0; - } - - /* external API to be used by application */ - public AppInterface.CommandType getCmdType() { - return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand); - } - - public Menu getMenu() { - return mMenu; - } - - public Input geInput() { - return mInput; - } - - public TextMessage geTextMessage() { - return mTextMsg; - } - - public BrowserSettings getBrowserSettings() { - return mBrowserSettings; - } - - public ToneSettings getToneSettings() { - return mToneSettings; - } - - public CallSettings getCallSettings() { - return mCallSettings; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CatException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java deleted file mode 100644 index 1bf13696b85b..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CatException.java +++ /dev/null @@ -1,31 +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.cat; - -import android.util.AndroidException; - - -/** - * Base class for all the exceptions in CAT service. - * - * {@hide} - */ -class CatException extends AndroidException { - public CatException() { - super(); - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CatLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java deleted file mode 100644 index e19ff435bce6..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CatLog.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.cat; - -import android.util.Log; - -public abstract class CatLog { - static final boolean DEBUG = true; - - public static void d(Object caller, String msg) { - if (!DEBUG) { - return; - } - - String className = caller.getClass().getName(); - Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": " - + msg); - } - - public static void d(String caller, String msg) { - if (!DEBUG) { - return; - } - - Log.d("CAT", caller + ": " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java deleted file mode 100644 index cfcac36b5880..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.cat; - -public class CatResponseMessage { - CommandDetails cmdDet = null; - ResultCode resCode = ResultCode.OK; - int usersMenuSelection = 0; - String usersInput = null; - boolean usersYesNoSelection = false; - boolean usersConfirm = false; - - public CatResponseMessage(CatCmdMessage cmdMsg) { - this.cmdDet = cmdMsg.mCmdDet; - } - - public void setResultCode(ResultCode resCode) { - this.resCode = resCode; - } - - public void setMenuSelection(int selection) { - this.usersMenuSelection = selection; - } - - public void setInput(String input) { - this.usersInput = input; - } - - public void setYesNo(boolean yesNo) { - usersYesNoSelection = yesNo; - } - - public void setConfirmation(boolean confirm) { - usersConfirm = confirm; - } - - CommandDetails getCmdDetails() { - return cmdDet; - } - } \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java deleted file mode 100644 index 2b370729085d..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CatService.java +++ /dev/null @@ -1,750 +0,0 @@ -/* - * 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.cat; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Message; -import android.os.SystemProperties; - -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccRecords; - - -import java.io.ByteArrayOutputStream; -import java.util.List; -import java.util.Locale; - -class RilMessage { - int mId; - Object mData; - ResultCode mResCode; - - RilMessage(int msgId, String rawData) { - mId = msgId; - mData = rawData; - } - - RilMessage(RilMessage other) { - this.mId = other.mId; - this.mData = other.mData; - this.mResCode = other.mResCode; - } -} - -/** - * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL - * and application. - * - * {@hide} - */ -public class CatService extends Handler implements AppInterface { - - // Class members - private static IccRecords mIccRecords; - - // Service members. - // Protects singleton instance lazy initialization. - private static final Object sInstanceLock = new Object(); - private static CatService sInstance; - private CommandsInterface mCmdIf; - private Context mContext; - private CatCmdMessage mCurrntCmd = null; - private CatCmdMessage mMenuCmd = null; - - private RilMessageDecoder mMsgDecoder = null; - private boolean mStkAppInstalled = false; - - // Service constants. - static final int MSG_ID_SESSION_END = 1; - static final int MSG_ID_PROACTIVE_COMMAND = 2; - static final int MSG_ID_EVENT_NOTIFY = 3; - static final int MSG_ID_CALL_SETUP = 4; - static final int MSG_ID_REFRESH = 5; - static final int MSG_ID_RESPONSE = 6; - static final int MSG_ID_SIM_READY = 7; - - static final int MSG_ID_RIL_MSG_DECODED = 10; - - // Events to signal SIM presence or absent in the device. - private static final int MSG_ID_ICC_RECORDS_LOADED = 20; - - private static final int DEV_ID_KEYPAD = 0x01; - private static final int DEV_ID_DISPLAY = 0x02; - private static final int DEV_ID_EARPIECE = 0x03; - private static final int DEV_ID_UICC = 0x81; - private static final int DEV_ID_TERMINAL = 0x82; - private static final int DEV_ID_NETWORK = 0x83; - - static final String STK_DEFAULT = "Defualt Message"; - - /* Intentionally private for singleton */ - private CatService(CommandsInterface ci, IccRecords ir, Context context, - IccFileHandler fh, IccCard ic) { - if (ci == null || ir == null || context == null || fh == null - || ic == null) { - throw new NullPointerException( - "Service: Input parameters must not be null"); - } - mCmdIf = ci; - mContext = context; - - // Get the RilMessagesDecoder for decoding the messages. - mMsgDecoder = RilMessageDecoder.getInstance(this, fh); - - // Register ril events handling. - mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null); - mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null); - mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null); - mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null); - //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); - - mIccRecords = ir; - - // Register for SIM ready event. - ic.registerForReady(this, MSG_ID_SIM_READY, null); - mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null); - - // Check if STK application is availalbe - mStkAppInstalled = isStkAppInstalled(); - - CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled); - } - - public void dispose() { - mIccRecords.unregisterForRecordsLoaded(this); - mCmdIf.unSetOnCatSessionEnd(this); - mCmdIf.unSetOnCatProactiveCmd(this); - mCmdIf.unSetOnCatEvent(this); - mCmdIf.unSetOnCatCallSetUp(this); - - this.removeCallbacksAndMessages(null); - } - - protected void finalize() { - CatLog.d(this, "Service finalized"); - } - - private void handleRilMsg(RilMessage rilMsg) { - if (rilMsg == null) { - return; - } - - // dispatch messages - CommandParams cmdParams = null; - switch (rilMsg.mId) { - case MSG_ID_EVENT_NOTIFY: - if (rilMsg.mResCode == ResultCode.OK) { - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleCommand(cmdParams, false); - } - } - break; - case MSG_ID_PROACTIVE_COMMAND: - try { - cmdParams = (CommandParams) rilMsg.mData; - } catch (ClassCastException e) { - // for error handling : cast exception - CatLog.d(this, "Fail to parse proactive command"); - sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD, - false, 0x00, null); - break; - } - if (cmdParams != null) { - if (rilMsg.mResCode == ResultCode.OK) { - handleCommand(cmdParams, true); - } else { - // for proactive commands that couldn't be decoded - // successfully respond with the code generated by the - // message decoder. - sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode, - false, 0, null); - } - } - break; - case MSG_ID_REFRESH: - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleCommand(cmdParams, false); - } - break; - case MSG_ID_SESSION_END: - handleSessionEnd(); - break; - case MSG_ID_CALL_SETUP: - // prior event notify command supplied all the information - // needed for set up call processing. - break; - } - } - - /** - * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command - * from RIL. - * Sends valid proactive command data to the application using intents. - * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is - * from RIL_UNSOL_STK_PROACTIVE_COMMAND. - */ - private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) { - CatLog.d(this, cmdParams.getCommandType().name()); - - CharSequence message; - CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams); - switch (cmdParams.getCommandType()) { - case SET_UP_MENU: - if (removeMenu(cmdMsg.getMenu())) { - mMenuCmd = null; - } else { - mMenuCmd = cmdMsg; - } - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - break; - case DISPLAY_TEXT: - // when application is not required to respond, send an immediate response. - if (!cmdMsg.geTextMessage().responseNeeded) { - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - } - break; - case REFRESH: - // ME side only handles refresh commands which meant to remove IDLE - // MODE TEXT. - cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value(); - break; - case SET_UP_IDLE_MODE_TEXT: - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - break; - case PROVIDE_LOCAL_INFORMATION: - ResponseData resp; - switch (cmdParams.cmdDet.commandQualifier) { - case CommandParamsFactory.DTTZ_SETTING: - resp = new DTTZResponseData(null); - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); - break; - case CommandParamsFactory.LANGUAGE_SETTING: - resp = new LanguageResponseData(Locale.getDefault().getLanguage()); - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); - break; - default: - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - } - // No need to start STK app here. - return; - case LAUNCH_BROWSER: - if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null) - && (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) { - message = mContext.getText(com.android.internal.R.string.launchBrowserDefault); - ((LaunchBrowserParams) cmdParams).confirmMsg.text = message.toString(); - } - break; - case SELECT_ITEM: - case GET_INPUT: - case GET_INKEY: - break; - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - if ((((DisplayTextParams)cmdParams).textMsg.text != null) - && (((DisplayTextParams)cmdParams).textMsg.text.equals(STK_DEFAULT))) { - message = mContext.getText(com.android.internal.R.string.sending); - ((DisplayTextParams)cmdParams).textMsg.text = message.toString(); - } - break; - case PLAY_TONE: - break; - case SET_UP_CALL: - if ((((CallSetupParams) cmdParams).confirmMsg.text != null) - && (((CallSetupParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) { - message = mContext.getText(com.android.internal.R.string.SetupCallDefault); - ((CallSetupParams) cmdParams).confirmMsg.text = message.toString(); - } - break; - case OPEN_CHANNEL: - case CLOSE_CHANNEL: - case RECEIVE_DATA: - case SEND_DATA: - BIPClientParams cmd = (BIPClientParams) cmdParams; - if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) { - CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id"); - // If alpha length is zero, we just respond with OK. - if (isProactiveCmd) { - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - } - return; - } - // Respond with permanent failure to avoid retry if STK app is not present. - if (!mStkAppInstalled) { - CatLog.d(this, "No STK application found."); - if (isProactiveCmd) { - sendTerminalResponse(cmdParams.cmdDet, - ResultCode.BEYOND_TERMINAL_CAPABILITY, - false, 0, null); - return; - } - } - /* - * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by - * either PROACTIVE_COMMAND or EVENT_NOTIFY. - * If PROACTIVE_COMMAND is used for those commands, send terminal - * response here. - */ - if (isProactiveCmd && - ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) || - (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) || - (cmdParams.getCommandType() == CommandType.SEND_DATA))) { - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - } - break; - default: - CatLog.d(this, "Unsupported command"); - return; - } - mCurrntCmd = cmdMsg; - Intent intent = new Intent(AppInterface.CAT_CMD_ACTION); - intent.putExtra("STK CMD", cmdMsg); - mContext.sendBroadcast(intent); - } - - /** - * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL. - * - */ - private void handleSessionEnd() { - CatLog.d(this, "SESSION END"); - - mCurrntCmd = mMenuCmd; - Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION); - mContext.sendBroadcast(intent); - } - - private void sendTerminalResponse(CommandDetails cmdDet, - ResultCode resultCode, boolean includeAdditionalInfo, - int additionalInfo, ResponseData resp) { - - if (cmdDet == null) { - return; - } - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - Input cmdInput = null; - if (mCurrntCmd != null) { - cmdInput = mCurrntCmd.geInput(); - } - - // command details - int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); - if (cmdDet.compRequired) { - tag |= 0x80; - } - buf.write(tag); - buf.write(0x03); // length - buf.write(cmdDet.commandNumber); - buf.write(cmdDet.typeOfCommand); - buf.write(cmdDet.commandQualifier); - - // device identities - // According to TS102.223/TS31.111 section 6.8 Structure of - // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N, - // the ME should set the CR(comprehension required) flag to - // comprehension not required.(CR=0)" - // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N, - // the CR flag is not set. - tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_TERMINAL); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // result - tag = 0x80 | ComprehensionTlvTag.RESULT.value(); - buf.write(tag); - int length = includeAdditionalInfo ? 2 : 1; - buf.write(length); - buf.write(resultCode.value()); - - // additional info - if (includeAdditionalInfo) { - buf.write(additionalInfo); - } - - // Fill optional data for each corresponding command - if (resp != null) { - resp.format(buf); - } else { - encodeOptionalTags(cmdDet, resultCode, cmdInput, buf); - } - - byte[] rawData = buf.toByteArray(); - String hexString = IccUtils.bytesToHexString(rawData); - if (false) { - CatLog.d(this, "TERMINAL RESPONSE: " + hexString); - } - - mCmdIf.sendTerminalResponse(hexString, null); - } - - private void encodeOptionalTags(CommandDetails cmdDet, - ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) { - CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); - if (cmdType != null) { - switch (cmdType) { - case GET_INKEY: - // ETSI TS 102 384,27.22.4.2.8.4.2. - // If it is a response for GET_INKEY command and the response timeout - // occured, then add DURATION TLV for variable timeout case. - if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) && - (cmdInput != null) && (cmdInput.duration != null)) { - getInKeyResponse(buf, cmdInput); - } - break; - case PROVIDE_LOCAL_INFORMATION: - if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) && - (resultCode.value() == ResultCode.OK.value())) { - getPliResponse(buf); - } - break; - default: - CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet); - break; - } - } else { - CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet); - } - } - - private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) { - int tag = ComprehensionTlvTag.DURATION.value(); - - buf.write(tag); - buf.write(0x02); // length - buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds) - buf.write(cmdInput.duration.timeInterval); // Time Duration - } - - private void getPliResponse(ByteArrayOutputStream buf) { - - // Locale Language Setting - String lang = SystemProperties.get("persist.sys.language"); - - if (lang != null) { - // tag - int tag = ComprehensionTlvTag.LANGUAGE.value(); - buf.write(tag); - ResponseData.writeLength(buf, lang.length()); - buf.write(lang.getBytes(), 0, lang.length()); - } - } - - private void sendMenuSelection(int menuId, boolean helpRequired) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_MENU_SELECTION_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_KEYPAD); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // item identifier - tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(menuId); // menu identifier chosen - - // help request - if (helpRequired) { - tag = ComprehensionTlvTag.HELP_REQUEST.value(); - buf.write(tag); - buf.write(0x00); // length - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = IccUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - private void eventDownload(int event, int sourceId, int destinationId, - byte[] additionalInfo, boolean oneShot) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder, assume length < 128. - - // event list - tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(event); // event value - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(sourceId); // source device id - buf.write(destinationId); // destination device id - - // additional information - if (additionalInfo != null) { - for (byte b : additionalInfo) { - buf.write(b); - } - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = IccUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - /** - * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor. - * - * @param ci CommandsInterface object - * @param ir IccRecords object - * @param context phone app context - * @param fh Icc file handler - * @param ic Icc card - * @return The only Service object in the system - */ - public static CatService getInstance(CommandsInterface ci, IccRecords ir, - Context context, IccFileHandler fh, IccCard ic) { - synchronized (sInstanceLock) { - if (sInstance == null) { - if (ci == null || ir == null || context == null || fh == null - || ic == null) { - return null; - } - HandlerThread thread = new HandlerThread("Cat Telephony service"); - thread.start(); - sInstance = new CatService(ci, ir, context, fh, ic); - CatLog.d(sInstance, "NEW sInstance"); - } else if ((ir != null) && (mIccRecords != ir)) { - CatLog.d(sInstance, "Reinitialize the Service with SIMRecords"); - mIccRecords = ir; - - // re-Register for SIM ready event. - mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null); - CatLog.d(sInstance, "sr changed reinitialize and return current sInstance"); - } else { - CatLog.d(sInstance, "Return current sInstance"); - } - return sInstance; - } - } - - /** - * Used by application to get an AppInterface object. - * - * @return The only Service object in the system - */ - public static AppInterface getInstance() { - return getInstance(null, null, null, null, null); - } - - @Override - public void handleMessage(Message msg) { - - switch (msg.what) { - case MSG_ID_SESSION_END: - case MSG_ID_PROACTIVE_COMMAND: - case MSG_ID_EVENT_NOTIFY: - case MSG_ID_REFRESH: - CatLog.d(this, "ril message arrived"); - String data = null; - if (msg.obj != null) { - AsyncResult ar = (AsyncResult) msg.obj; - if (ar != null && ar.result != null) { - try { - data = (String) ar.result; - } catch (ClassCastException e) { - break; - } - } - } - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data)); - break; - case MSG_ID_CALL_SETUP: - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null)); - break; - case MSG_ID_ICC_RECORDS_LOADED: - break; - case MSG_ID_RIL_MSG_DECODED: - handleRilMsg((RilMessage) msg.obj); - break; - case MSG_ID_RESPONSE: - handleCmdResponse((CatResponseMessage) msg.obj); - break; - case MSG_ID_SIM_READY: - CatLog.d(this, "SIM ready. Reporting STK service running now..."); - mCmdIf.reportStkServiceIsRunning(null); - break; - default: - throw new AssertionError("Unrecognized CAT command: " + msg.what); - } - } - - public synchronized void onCmdResponse(CatResponseMessage resMsg) { - if (resMsg == null) { - return; - } - // queue a response message. - Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg); - msg.sendToTarget(); - } - - private boolean validateResponse(CatResponseMessage resMsg) { - if (mCurrntCmd != null) { - return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet)); - } - return false; - } - - private boolean removeMenu(Menu menu) { - try { - if (menu.items.size() == 1 && menu.items.get(0) == null) { - return true; - } - } catch (NullPointerException e) { - CatLog.d(this, "Unable to get Menu's items size"); - return true; - } - return false; - } - - private void handleCmdResponse(CatResponseMessage resMsg) { - // Make sure the response details match the last valid command. An invalid - // response is a one that doesn't have a corresponding proactive command - // and sending it can "confuse" the baseband/ril. - // One reason for out of order responses can be UI glitches. For example, - // if the application launch an activity, and that activity is stored - // by the framework inside the history stack. That activity will be - // available for relaunch using the latest application dialog - // (long press on the home button). Relaunching that activity can send - // the same command's result again to the CatService and can cause it to - // get out of sync with the SIM. - if (!validateResponse(resMsg)) { - return; - } - ResponseData resp = null; - boolean helpRequired = false; - CommandDetails cmdDet = resMsg.getCmdDetails(); - - switch (resMsg.resCode) { - case HELP_INFO_REQUIRED: - helpRequired = true; - // fall through - case OK: - case PRFRMD_WITH_PARTIAL_COMPREHENSION: - case PRFRMD_WITH_MISSING_INFO: - case PRFRMD_WITH_ADDITIONAL_EFS_READ: - case PRFRMD_ICON_NOT_DISPLAYED: - case PRFRMD_MODIFIED_BY_NAA: - case PRFRMD_LIMITED_SERVICE: - case PRFRMD_WITH_MODIFICATION: - case PRFRMD_NAA_NOT_ACTIVE: - case PRFRMD_TONE_NOT_PLAYED: - switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) { - case SET_UP_MENU: - helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED; - sendMenuSelection(resMsg.usersMenuSelection, helpRequired); - return; - case SELECT_ITEM: - resp = new SelectItemResponseData(resMsg.usersMenuSelection); - break; - case GET_INPUT: - case GET_INKEY: - Input input = mCurrntCmd.geInput(); - if (!input.yesNo) { - // when help is requested there is no need to send the text - // string object. - if (!helpRequired) { - resp = new GetInkeyInputResponseData(resMsg.usersInput, - input.ucs2, input.packed); - } - } else { - resp = new GetInkeyInputResponseData( - resMsg.usersYesNoSelection); - } - break; - case DISPLAY_TEXT: - case LAUNCH_BROWSER: - break; - case SET_UP_CALL: - mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null); - // No need to send terminal response for SET UP CALL. The user's - // confirmation result is send back using a dedicated ril message - // invoked by the CommandInterface call above. - mCurrntCmd = null; - return; - } - break; - case NO_RESPONSE_FROM_USER: - case UICC_SESSION_TERM_BY_USER: - case BACKWARD_MOVE_BY_USER: - case USER_NOT_ACCEPT: - resp = null; - break; - default: - return; - } - sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); - mCurrntCmd = null; - } - - private boolean isStkAppInstalled() { - Intent intent = new Intent(AppInterface.CAT_CMD_ACTION); - PackageManager pm = mContext.getPackageManager(); - List broadcastReceivers = - pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA); - int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size(); - - return (numReceiver > 0); - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java deleted file mode 100644 index 3e7f722d3689..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.cat; - -import android.os.Parcel; -import android.os.Parcelable; - -abstract class ValueObject { - abstract ComprehensionTlvTag getTag(); -} - -/** - * Class for Command Detailes object of proactive commands from SIM. - * {@hide} - */ -class CommandDetails extends ValueObject implements Parcelable { - public boolean compRequired; - public int commandNumber; - public int typeOfCommand; - public int commandQualifier; - - public ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.COMMAND_DETAILS; - } - - CommandDetails() { - } - - public boolean compareTo(CommandDetails other) { - return (this.compRequired == other.compRequired && - this.commandNumber == other.commandNumber && - this.commandQualifier == other.commandQualifier && - this.typeOfCommand == other.typeOfCommand); - } - - public CommandDetails(Parcel in) { - compRequired = in.readInt() != 0; - commandNumber = in.readInt(); - typeOfCommand = in.readInt(); - commandQualifier = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(compRequired ? 1 : 0); - dest.writeInt(commandNumber); - dest.writeInt(typeOfCommand); - dest.writeInt(commandQualifier); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public CommandDetails createFromParcel(Parcel in) { - return new CommandDetails(in); - } - - public CommandDetails[] newArray(int size) { - return new CommandDetails[size]; - } - }; - - public int describeContents() { - return 0; - } - - @Override - public String toString() { - return "CmdDetails: compRequired=" + compRequired + - " commandNumber=" + commandNumber + - " typeOfCommand=" + typeOfCommand + - " commandQualifier=" + commandQualifier; - } -} - -class DeviceIdentities extends ValueObject { - public int sourceId; - public int destinationId; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.DEVICE_IDENTITIES; - } -} - -// Container class to hold icon identifier value. -class IconId extends ValueObject { - int recordNumber; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ICON_ID; - } -} - -// Container class to hold item icon identifier list value. -class ItemsIconId extends ValueObject { - int [] recordNumbers; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ITEM_ICON_ID_LIST; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java deleted file mode 100644 index 79f6ad2f014a..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CommandParams.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.cat; - -import android.graphics.Bitmap; - -/** - * Container class for proactive command parameters. - * - */ -class CommandParams { - CommandDetails cmdDet; - - CommandParams(CommandDetails cmdDet) { - this.cmdDet = cmdDet; - } - - AppInterface.CommandType getCommandType() { - return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); - } - - boolean setIcon(Bitmap icon) { return true; } - - @Override - public String toString() { - return cmdDet.toString(); - } -} - -class DisplayTextParams extends CommandParams { - TextMessage textMsg; - - DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) { - super(cmdDet); - this.textMsg = textMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class LaunchBrowserParams extends CommandParams { - TextMessage confirmMsg; - LaunchBrowserMode mode; - String url; - - LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg, - String url, LaunchBrowserMode mode) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.mode = mode; - this.url = url; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && confirmMsg != null) { - confirmMsg.icon = icon; - return true; - } - return false; - } -} - -class PlayToneParams extends CommandParams { - TextMessage textMsg; - ToneSettings settings; - - PlayToneParams(CommandDetails cmdDet, TextMessage textMsg, - Tone tone, Duration duration, boolean vibrate) { - super(cmdDet); - this.textMsg = textMsg; - this.settings = new ToneSettings(duration, tone, vibrate); - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class CallSetupParams extends CommandParams { - TextMessage confirmMsg; - TextMessage callMsg; - - CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg, - TextMessage callMsg) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.callMsg = callMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon == null) { - return false; - } - if (confirmMsg != null && confirmMsg.icon == null) { - confirmMsg.icon = icon; - return true; - } else if (callMsg != null && callMsg.icon == null) { - callMsg.icon = icon; - return true; - } - return false; - } -} - -class SelectItemParams extends CommandParams { - Menu menu = null; - boolean loadTitleIcon = false; - - SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) { - super(cmdDet); - this.menu = menu; - this.loadTitleIcon = loadTitleIcon; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && menu != null) { - if (loadTitleIcon && menu.titleIcon == null) { - menu.titleIcon = icon; - } else { - for (Item item : menu.items) { - if (item.icon != null) { - continue; - } - item.icon = icon; - break; - } - } - return true; - } - return false; - } -} - -class GetInputParams extends CommandParams { - Input input = null; - - GetInputParams(CommandDetails cmdDet, Input input) { - super(cmdDet); - this.input = input; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && input != null) { - input.icon = icon; - } - return true; - } -} - -/* - * BIP (Bearer Independent Protocol) is the mechanism for SIM card applications - * to access data connection through the mobile device. - * - * SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and - * RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for - * the details of proactive commands procedures and their structures. - */ -class BIPClientParams extends CommandParams { - TextMessage textMsg; - boolean bHasAlphaId; - - BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) { - super(cmdDet); - this.textMsg = textMsg; - this.bHasAlphaId = has_alpha_id; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java deleted file mode 100644 index a55401212eb1..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java +++ /dev/null @@ -1,943 +0,0 @@ -/* - * 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.cat; - -import android.graphics.Bitmap; -import android.os.Handler; -import android.os.Message; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccFileHandler; - -import java.util.Iterator; -import java.util.List; - -/** - * Factory class, used for decoding raw byte arrays, received from baseband, - * into a CommandParams object. - * - */ -class CommandParamsFactory extends Handler { - private static CommandParamsFactory sInstance = null; - private IconLoader mIconLoader; - private CommandParams mCmdParams = null; - private int mIconLoadState = LOAD_NO_ICON; - private RilMessageDecoder mCaller = null; - - // constants - static final int MSG_ID_LOAD_ICON_DONE = 1; - - // loading icons state parameters. - static final int LOAD_NO_ICON = 0; - static final int LOAD_SINGLE_ICON = 1; - static final int LOAD_MULTI_ICONS = 2; - - // Command Qualifier values for refresh command - static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00; - static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02; - static final int REFRESH_NAA_INIT = 0x03; - static final int REFRESH_UICC_RESET = 0x04; - - // Command Qualifier values for PLI command - static final int DTTZ_SETTING = 0x03; - static final int LANGUAGE_SETTING = 0x04; - - static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller, - IccFileHandler fh) { - if (sInstance != null) { - return sInstance; - } - if (fh != null) { - return new CommandParamsFactory(caller, fh); - } - return null; - } - - private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) { - mCaller = caller; - mIconLoader = IconLoader.getInstance(this, fh); - } - - private CommandDetails processCommandDetails(List ctlvs) { - CommandDetails cmdDet = null; - - if (ctlvs != null) { - // Search for the Command Details object. - ComprehensionTlv ctlvCmdDet = searchForTag( - ComprehensionTlvTag.COMMAND_DETAILS, ctlvs); - if (ctlvCmdDet != null) { - try { - cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet); - } catch (ResultException e) { - CatLog.d(this, - "processCommandDetails: Failed to procees command details e=" + e); - } - } - } - return cmdDet; - } - - void make(BerTlv berTlv) { - if (berTlv == null) { - return; - } - // reset global state parameters. - mCmdParams = null; - mIconLoadState = LOAD_NO_ICON; - // only proactive command messages are processed. - if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - boolean cmdPending = false; - List ctlvs = berTlv.getComprehensionTlvs(); - // process command dtails from the tlv list. - CommandDetails cmdDet = processCommandDetails(ctlvs); - if (cmdDet == null) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - - // extract command type enumeration from the raw value stored inside - // the Command Details object. - AppInterface.CommandType cmdType = AppInterface.CommandType - .fromInt(cmdDet.typeOfCommand); - if (cmdType == null) { - // This PROACTIVE COMMAND is presently not handled. Hence set - // result code as BEYOND_TERMINAL_CAPABILITY in TR. - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); - return; - } - - try { - switch (cmdType) { - case SET_UP_MENU: - cmdPending = processSelectItem(cmdDet, ctlvs); - break; - case SELECT_ITEM: - cmdPending = processSelectItem(cmdDet, ctlvs); - break; - case DISPLAY_TEXT: - cmdPending = processDisplayText(cmdDet, ctlvs); - break; - case SET_UP_IDLE_MODE_TEXT: - cmdPending = processSetUpIdleModeText(cmdDet, ctlvs); - break; - case GET_INKEY: - cmdPending = processGetInkey(cmdDet, ctlvs); - break; - case GET_INPUT: - cmdPending = processGetInput(cmdDet, ctlvs); - break; - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - cmdPending = processEventNotify(cmdDet, ctlvs); - break; - case SET_UP_CALL: - cmdPending = processSetupCall(cmdDet, ctlvs); - break; - case REFRESH: - processRefresh(cmdDet, ctlvs); - cmdPending = false; - break; - case LAUNCH_BROWSER: - cmdPending = processLaunchBrowser(cmdDet, ctlvs); - break; - case PLAY_TONE: - cmdPending = processPlayTone(cmdDet, ctlvs); - break; - case PROVIDE_LOCAL_INFORMATION: - cmdPending = processProvideLocalInfo(cmdDet, ctlvs); - break; - case OPEN_CHANNEL: - case CLOSE_CHANNEL: - case RECEIVE_DATA: - case SEND_DATA: - cmdPending = processBIPClient(cmdDet, ctlvs); - break; - default: - // unsupported proactive commands - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); - return; - } - } catch (ResultException e) { - CatLog.d(this, "make: caught ResultException e=" + e); - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(e.result()); - return; - } - if (!cmdPending) { - sendCmdParams(ResultCode.OK); - } - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_ID_LOAD_ICON_DONE: - sendCmdParams(setIcons(msg.obj)); - break; - } - } - - private ResultCode setIcons(Object data) { - Bitmap[] icons = null; - int iconIndex = 0; - - if (data == null) { - return ResultCode.PRFRMD_ICON_NOT_DISPLAYED; - } - switch(mIconLoadState) { - case LOAD_SINGLE_ICON: - mCmdParams.setIcon((Bitmap) data); - break; - case LOAD_MULTI_ICONS: - icons = (Bitmap[]) data; - // set each item icon. - for (Bitmap icon : icons) { - mCmdParams.setIcon(icon); - } - break; - } - return ResultCode.OK; - } - - private void sendCmdParams(ResultCode resCode) { - mCaller.sendMsgParamsDecoded(resCode, mCmdParams); - } - - /** - * 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. - */ - private ComprehensionTlv searchForTag(ComprehensionTlvTag tag, - List ctlvs) { - Iterator iter = ctlvs.iterator(); - return searchForNextTag(tag, iter); - } - - /** - * Search for the next COMPREHENSION-TLV object with the given tag from a - * 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. - */ - private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag, - Iterator iter) { - int tagValue = tag.value(); - while (iter.hasNext()) { - ComprehensionTlv ctlv = iter.next(); - if (ctlv.getTag() == tagValue) { - return ctlv; - } - } - return null; - } - - /** - * Processes DISPLAY_TEXT proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processDisplayText(CommandDetails cmdDet, - List ctlvs) - throws ResultException { - - CatLog.d(this, "process DisplayText"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveTextString(ctlv); - } - // If the tlv object doesn't exist or the it is a null object reply - // with command not understood. - if (textMsg.text == null) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs); - if (ctlv != null) { - textMsg.responseNeeded = false; - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - // parse tone duration - ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); - if (ctlv != null) { - textMsg.duration = ValueParser.retrieveDuration(ctlv); - } - - // Parse command qualifier parameters. - textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0; - textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processSetUpIdleModeText(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process SetUpIdleModeText"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveTextString(ctlv); - } - // load icons only when text exist. - if (textMsg.text != null) { - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - } - - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes GET_INKEY proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processGetInkey(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process GetInkey"); - - Input input = new Input(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - input.text = ValueParser.retrieveTextString(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - } - - // parse duration - ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); - if (ctlv != null) { - input.duration = ValueParser.retrieveDuration(ctlv); - } - - input.minLen = 1; - input.maxLen = 1; - - input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; - input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; - input.yesNo = (cmdDet.commandQualifier & 0x04) != 0; - input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - input.echo = true; - - mCmdParams = new GetInputParams(cmdDet, input); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes GET_INPUT proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processGetInput(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process GetInput"); - - Input input = new Input(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - input.text = ValueParser.retrieveTextString(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs); - if (ctlv != null) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - input.minLen = rawValue[valueIndex] & 0xff; - input.maxLen = rawValue[valueIndex + 1] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs); - if (ctlv != null) { - input.defaultText = ValueParser.retrieveTextString(ctlv); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - } - - input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; - input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; - input.echo = (cmdDet.commandQualifier & 0x04) == 0; - input.packed = (cmdDet.commandQualifier & 0x08) != 0; - input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new GetInputParams(cmdDet, input); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes REFRESH proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - */ - private boolean processRefresh(CommandDetails cmdDet, - List ctlvs) { - - CatLog.d(this, "process Refresh"); - - // 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" - switch (cmdDet.commandQualifier) { - case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE: - case REFRESH_NAA_INIT_AND_FILE_CHANGE: - case REFRESH_NAA_INIT: - case REFRESH_UICC_RESET: - mCmdParams = new DisplayTextParams(cmdDet, null); - break; - } - return false; - } - - /** - * Processes SELECT_ITEM proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processSelectItem(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process SelectItem"); - - Menu menu = new Menu(); - IconId titleIconId = null; - ItemsIconId itemsIconId = null; - Iterator iter = ctlvs.iterator(); - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, - ctlvs); - if (ctlv != null) { - menu.title = ValueParser.retrieveAlphaId(ctlv); - } - - while (true) { - ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter); - if (ctlv != null) { - menu.items.add(ValueParser.retrieveItem(ctlv)); - } else { - break; - } - } - - // We must have at least one menu item. - if (menu.items.size() == 0) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs); - if (ctlv != null) { - // CAT items are listed 1...n while list start at 0, need to - // subtract one. - menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1; - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - mIconLoadState = LOAD_SINGLE_ICON; - titleIconId = ValueParser.retrieveIconId(ctlv); - menu.titleIconSelfExplanatory = titleIconId.selfExplanatory; - } - - ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs); - if (ctlv != null) { - mIconLoadState = LOAD_MULTI_ICONS; - itemsIconId = ValueParser.retrieveItemsIconId(ctlv); - menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory; - } - - boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0; - if (presentTypeSpecified) { - if ((cmdDet.commandQualifier & 0x02) == 0) { - menu.presentationType = PresentationType.DATA_VALUES; - } else { - menu.presentationType = PresentationType.NAVIGATION_OPTIONS; - } - } - menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0; - menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null); - - // Load icons data if needed. - switch(mIconLoadState) { - case LOAD_NO_ICON: - return false; - case LOAD_SINGLE_ICON: - mIconLoader.loadIcon(titleIconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - break; - case LOAD_MULTI_ICONS: - int[] recordNumbers = itemsIconId.recordNumbers; - if (titleIconId != null) { - // Create a new array for all the icons (title and items). - recordNumbers = new int[itemsIconId.recordNumbers.length + 1]; - recordNumbers[0] = titleIconId.recordNumber; - System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers, - 1, itemsIconId.recordNumbers.length); - } - mIconLoader.loadIcons(recordNumbers, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - break; - } - return true; - } - - /** - * Processes EVENT_NOTIFY message from baseband. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - */ - private boolean processEventNotify(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process EventNotify"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, - ctlvs); - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - textMsg.responseNeeded = false; - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SET_UP_EVENT_LIST proactive command from the SIM card. - * - * @param cmdDet Command Details object retrieved. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - */ - private boolean processSetUpEventList(CommandDetails cmdDet, - List ctlvs) { - - CatLog.d(this, "process SetUpEventList"); - // - // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST, - // ctlvs); - // if (ctlv != null) { - // try { - // byte[] rawValue = ctlv.getRawValue(); - // int valueIndex = ctlv.getValueIndex(); - // int valueLen = ctlv.getLength(); - // - // } catch (IndexOutOfBoundsException e) {} - // } - return true; - } - - /** - * Processes LAUNCH_BROWSER proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processLaunchBrowser(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process LaunchBrowser"); - - TextMessage confirmMsg = new TextMessage(); - IconId iconId = null; - String url = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs); - if (ctlv != null) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int valueLen = ctlv.getLength(); - if (valueLen > 0) { - url = GsmAlphabet.gsm8BitUnpackedToString(rawValue, - valueIndex, valueLen); - } else { - url = null; - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - // parse alpha identifier. - ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); - confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); - - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - confirmMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - // parse command qualifier value. - LaunchBrowserMode mode; - switch (cmdDet.commandQualifier) { - case 0x00: - default: - mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED; - break; - case 0x02: - mode = LaunchBrowserMode.USE_EXISTING_BROWSER; - break; - case 0x03: - mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER; - break; - } - - mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes PLAY_TONE proactive command from the SIM card. - * - * @param cmdDet Command Details container 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 - * asynchronous processing is required.t - * @throws ResultException - */ - private boolean processPlayTone(CommandDetails cmdDet, - List ctlvs) throws ResultException { - - CatLog.d(this, "process PlayTone"); - - Tone tone = null; - TextMessage textMsg = new TextMessage(); - Duration duration = null; - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs); - if (ctlv != null) { - // Nothing to do for null objects. - if (ctlv.getLength() > 0) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int toneVal = rawValue[valueIndex]; - tone = Tone.fromInt(toneVal); - } catch (IndexOutOfBoundsException e) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - } - // parse alpha identifier - ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - // parse tone duration - ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); - if (ctlv != null) { - duration = ValueParser.retrieveDuration(ctlv); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00; - - textMsg.responseNeeded = false; - mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SETUP_CALL proactive command from the SIM card. - * - * @param cmdDet Command Details 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 - * asynchronous processing is required. - */ - private boolean processSetupCall(CommandDetails cmdDet, - List ctlvs) throws ResultException { - CatLog.d(this, "process SetupCall"); - - Iterator iter = ctlvs.iterator(); - ComprehensionTlv ctlv = null; - // User confirmation phase message. - TextMessage confirmMsg = new TextMessage(); - // Call set up phase message. - TextMessage callMsg = new TextMessage(); - IconId confirmIconId = null; - IconId callIconId = null; - - // get confirmation message string. - ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); - confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - confirmIconId = ValueParser.retrieveIconId(ctlv); - confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory; - } - - // get call set up message string. - ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); - if (ctlv != null) { - callMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - callIconId = ValueParser.retrieveIconId(ctlv); - callMsg.iconSelfExplanatory = callIconId.selfExplanatory; - } - - mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg); - - if (confirmIconId != null || callIconId != null) { - mIconLoadState = LOAD_MULTI_ICONS; - int[] recordNumbers = new int[2]; - recordNumbers[0] = confirmIconId != null - ? confirmIconId.recordNumber : -1; - recordNumbers[1] = callIconId != null ? callIconId.recordNumber - : -1; - - mIconLoader.loadIcons(recordNumbers, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - private boolean processProvideLocalInfo(CommandDetails cmdDet, List ctlvs) - throws ResultException { - CatLog.d(this, "process ProvideLocalInfo"); - switch (cmdDet.commandQualifier) { - case DTTZ_SETTING: - CatLog.d(this, "PLI [DTTZ_SETTING]"); - mCmdParams = new CommandParams(cmdDet); - break; - case LANGUAGE_SETTING: - CatLog.d(this, "PLI [LANGUAGE_SETTING]"); - mCmdParams = new CommandParams(cmdDet); - break; - default: - CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported"); - mCmdParams = new CommandParams(cmdDet); - throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY); - } - return false; - } - - private boolean processBIPClient(CommandDetails cmdDet, - List ctlvs) throws ResultException { - AppInterface.CommandType commandType = - AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); - if (commandType != null) { - CatLog.d(this, "process "+ commandType.name()); - } - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - ComprehensionTlv ctlv = null; - boolean has_alpha_id = false; - - // parse alpha identifier - ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - CatLog.d(this, "alpha TLV text=" + textMsg.text); - has_alpha_id = true; - } - - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - textMsg.responseNeeded = false; - mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java deleted file mode 100644 index 22cd5a4cfa6d..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2011 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.cat; - -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Class for representing COMPREHENSION-TLV objects. - * - * @see "ETSI TS 101 220 subsection 7.1.1" - * - * {@hide} - */ -class ComprehensionTlv { - private static final String LOG_TAG = "ComprehensionTlv"; - private int mTag; - private boolean mCr; - private int mLength; - private int mValueIndex; - private byte[] mRawValue; - - /** - * 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 - * @param data Byte array containing the value - * @param valueIndex Index in data at which the value starts - */ - protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data, - int valueIndex) { - mTag = tag; - mCr = cr; - mLength = length; - mValueIndex = valueIndex; - mRawValue = data; - } - - public int getTag() { - return mTag; - } - - public boolean isComprehensionRequired() { - return mCr; - } - - public int getLength() { - return mLength; - } - - public int getValueIndex() { - return mValueIndex; - } - - public byte[] getRawValue() { - return mRawValue; - } - - /** - * 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 - * @throws ResultException - */ - public static List decodeMany(byte[] data, int startIndex) - throws ResultException { - ArrayList items = new ArrayList(); - int endIndex = data.length; - while (startIndex < endIndex) { - ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex); - if (ctlv != null) { - items.add(ctlv); - startIndex = ctlv.mValueIndex + ctlv.mLength; - } else { - CatLog.d(LOG_TAG, "decodeMany: ctlv is null, stop decoding"); - break; - } - } - - return items; - } - - /** - * 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 - * @throws ResultException - */ - public static ComprehensionTlv decode(byte[] data, int startIndex) - throws ResultException { - int curIndex = startIndex; - int endIndex = data.length; - - try { - /* tag */ - int tag; - boolean cr; // Comprehension required flag - int temp = data[curIndex++] & 0xff; - switch (temp) { - case 0: - case 0xff: - case 0x80: - Log.d("CAT ", "decode: unexpected first tag byte=" + Integer.toHexString(temp) + - ", startIndex=" + startIndex + " curIndex=" + curIndex + - " endIndex=" + endIndex); - // Return null which will stop decoding, this has occurred - // with Ghana MTN simcard and JDI simcard. - return null; - - case 0x7f: // tag is in three-byte format - tag = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - cr = (tag & 0x8000) != 0; - tag &= ~0x8000; - curIndex += 2; - break; - - default: // tag is in single-byte format - tag = temp; - cr = (tag & 0x80) != 0; - tag &= ~0x80; - break; - } - - /* length */ - int length; - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - length = data[curIndex++] & 0xff; - if (length < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "length < 0x80 length=" + Integer.toHexString(length) + - " startIndex=" + startIndex + " curIndex=" + curIndex + - " endIndex=" + endIndex); - } - } else if (temp == 0x82) { - length = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - curIndex += 2; - if (length < 0x100) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "two byte length < 0x100 length=" + Integer.toHexString(length) + - " startIndex=" + startIndex + " curIndex=" + curIndex + - " endIndex=" + endIndex); - } - } else if (temp == 0x83) { - length = ((data[curIndex] & 0xff) << 16) - | ((data[curIndex + 1] & 0xff) << 8) - | (data[curIndex + 2] & 0xff); - curIndex += 3; - if (length < 0x10000) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "three byte length < 0x10000 length=0x" + Integer.toHexString(length) + - " startIndex=" + startIndex + " curIndex=" + curIndex + - " endIndex=" + endIndex); - } - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "Bad length modifer=" + temp + - " startIndex=" + startIndex + " curIndex=" + curIndex + - " endIndex=" + endIndex); - - } - - return new ComprehensionTlv(tag, cr, length, data, curIndex); - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, - "IndexOutOfBoundsException" + " startIndex=" + startIndex + - " curIndex=" + curIndex + " endIndex=" + endIndex); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java deleted file mode 100644 index 973dbc8132e2..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 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.cat; - -/** - * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If - * you want to get the actual value, call {@link #value() value} method. - * - * {@hide} - */ -public enum ComprehensionTlvTag { - COMMAND_DETAILS(0x01), - DEVICE_IDENTITIES(0x02), - RESULT(0x03), - DURATION(0x04), - ALPHA_ID(0x05), - ADDRESS(0x06), - USSD_STRING(0x0a), - SMS_TPDU(0x0b), - 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), - URL(0x31), - BROWSER_TERMINATION_CAUSE(0x34), - TEXT_ATTRIBUTE(0x50); - - private int mValue; - - ComprehensionTlvTag(int value) { - mValue = value; - } - - /** - * Returns the actual value of this COMPREHENSION-TLV object. - * - * @return Actual tag value of this object - */ - public int value() { - return mValue; - } - - public static ComprehensionTlvTag fromInt(int value) { - for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java deleted file mode 100644 index e8cd404ce7b1..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/Duration.java +++ /dev/null @@ -1,79 +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.cat; - -import android.os.Parcel; -import android.os.Parcelable; - - -/** - * Class for representing "Duration" object for CAT. - * - * {@hide} - */ -public class Duration implements Parcelable { - public int timeInterval; - public TimeUnit timeUnit; - - public enum TimeUnit { - MINUTE(0x00), - SECOND(0x01), - TENTH_SECOND(0x02); - - private int mValue; - - TimeUnit(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - } - - /** - * @param timeInterval Between 1 and 255 inclusive. - */ - public Duration(int timeInterval, TimeUnit timeUnit) { - this.timeInterval = timeInterval; - this.timeUnit = timeUnit; - } - - private Duration(Parcel in) { - timeInterval = in.readInt(); - timeUnit = TimeUnit.values()[in.readInt()]; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(timeInterval); - dest.writeInt(timeUnit.ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Duration createFromParcel(Parcel in) { - return new Duration(in); - } - - public Duration[] newArray(int size) { - return new Duration[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/cat/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java deleted file mode 100644 index 02c7ea0f6a7e..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/FontSize.java +++ /dev/null @@ -1,50 +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.cat; - - -/** - * Enumeration for representing text font size. - * - * {@hide} - */ -public enum FontSize { - NORMAL(0x0), - LARGE(0x1), - SMALL(0x2); - - private int mValue; - - FontSize(int value) { - mValue = value; - } - - /** - * Create a FontSize object. - * @param value Integer value to be converted to a FontSize object. - * @return FontSize object whose value is {@code value}. If no - * FontSize object has that value, null is returned. - */ - public static FontSize fromInt(int value) { - for (FontSize e : FontSize.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java deleted file mode 100644 index 2fa18119c78a..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/IconLoader.java +++ /dev/null @@ -1,362 +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.cat; - -import com.android.internal.telephony.IccFileHandler; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.util.HashMap; - -/** - * 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 - private int mState = STATE_SINGLE_ICON; - private ImageDescriptor mId = null; - private Bitmap mCurrentIcon = null; - private int mRecordNumber; - private IccFileHandler mSimFH = null; - private Message mEndMsg = null; - private byte[] mIconData = null; - // multi icons state members - private int[] mRecordNumbers = null; - private int mCurrentRecordIndex = 0; - private Bitmap[] mIcons = null; - private HashMap mIconsCache = null; - - private static IconLoader sLoader = null; - - // 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. - private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1; - // 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; - - // Color lookup table offset inside the EF. - private static final int CLUT_LOCATION_OFFSET = 4; - // CLUT entry size, {Red, Green, Black} - private static final int CLUT_ENTRY_SIZE = 3; - - - private IconLoader(Looper looper , IccFileHandler fh) { - super(looper); - mSimFH = fh; - - mIconsCache = new HashMap(50); - } - - static IconLoader getInstance(Handler caller, IccFileHandler fh) { - if (sLoader != null) { - return sLoader; - } - if (fh != null) { - HandlerThread thread = new HandlerThread("Cat Icon Loader"); - thread.start(); - return new IconLoader(thread.getLooper(), fh); - } - return null; - } - - void loadIcons(int[] recordNumbers, Message msg) { - if (recordNumbers == null || recordNumbers.length == 0 || msg == null) { - return; - } - mEndMsg = msg; - // initialize multi icons load variables. - mIcons = new Bitmap[recordNumbers.length]; - mRecordNumbers = recordNumbers; - mCurrentRecordIndex = 0; - mState = STATE_MULTI_ICONS; - startLoadingIcon(recordNumbers[0]); - } - - void loadIcon(int recordNumber, Message msg) { - if (msg == null) { - return; - } - mEndMsg = msg; - mState = STATE_SINGLE_ICON; - startLoadingIcon(recordNumber); - } - - private void startLoadingIcon(int recordNumber) { - // Reset the load variables. - mId = null; - mIconData = null; - mCurrentIcon = null; - mRecordNumber = recordNumber; - - // make sure the icon was not already loaded and saved in the local cache. - if (mIconsCache.containsKey(recordNumber)) { - mCurrentIcon = mIconsCache.get(recordNumber); - postIcon(); - return; - } - - // start the first phase ==> loading Image Descriptor. - readId(); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - try { - switch (msg.what) { - case EVENT_READ_EF_IMG_RECOED_DONE: - ar = (AsyncResult) msg.obj; - if (handleImageDescriptor((byte[]) ar.result)) { - readIconData(); - } else { - throw new Exception("Unable to parse image descriptor"); - } - break; - case EVENT_READ_ICON_DONE: - ar = (AsyncResult) msg.obj; - byte[] rawData = ((byte[]) ar.result); - if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) { - mCurrentIcon = parseToBnW(rawData, rawData.length); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) { - mIconData = rawData; - readClut(); - } - break; - case EVENT_READ_CLUT_DONE: - ar = (AsyncResult) msg.obj; - byte [] clut = ((byte[]) ar.result); - mCurrentIcon = parseToRGB(mIconData, mIconData.length, - false, clut); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - break; - } - } catch (Exception e) { - CatLog.d(this, "Icon load failed"); - // post null icon back to the caller. - postIcon(); - } - } - - /** - * 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 - * TS 51.011. - */ - private boolean handleImageDescriptor(byte[] rawData) { - mId = ImageDescriptor.parse(rawData, 1); - if (mId == null) { - return false; - } - return true; - } - - // Start reading colour lookup table from SIM card. - private void readClut() { - int length = mIconData[3] * CLUT_ENTRY_SIZE; - Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, - mIconData[CLUT_LOCATION_OFFSET], - mIconData[CLUT_LOCATION_OFFSET + 1], length, msg); - } - - // Start reading Image Descriptor from SIM card. - private void readId() { - if (mRecordNumber < 0) { - mCurrentIcon = null; - postIcon(); - return; - } - Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE); - mSimFH.loadEFImgLinearFixed(mRecordNumber, msg); - } - - // Start reading icon bytes array from SIM card. - private void readIconData() { - Message msg = this.obtainMessage(EVENT_READ_ICON_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg); - } - - // When all is done pass icon back to caller. - private void postIcon() { - if (mState == STATE_SINGLE_ICON) { - mEndMsg.obj = mCurrentIcon; - mEndMsg.sendToTarget(); - } else if (mState == STATE_MULTI_ICONS) { - mIcons[mCurrentRecordIndex++] = mCurrentIcon; - // If not all icons were loaded, start loading the next one. - if (mCurrentRecordIndex < mRecordNumbers.length) { - startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]); - } else { - mEndMsg.obj = mIcons; - mEndMsg.sendToTarget(); - } - } - } - - /** - * Convert a TS 131.102 image instance of code scheme '11' into Bitmap - * @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; - int height = data[valueIndex++] & 0xFF; - int numOfPixels = width*height; - - int[] pixels = new int[numOfPixels]; - - int pixelIndex = 0; - int bitIndex = 7; - byte currentByte = 0x00; - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (pixelIndex % 8 == 0) { - currentByte = data[valueIndex++]; - bitIndex = 7; - } - pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01); - } - - if (pixelIndex != numOfPixels) { - CatLog.d("IconLoader", "parseToBnW; size error"); - } - return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); - } - - /** - * Decode one bit to a black and white color: - * 0 is black - * 1 is white - * @param bit to decode - * @return RGB color - */ - private static int bitToBnW(int bit){ - if(bit == 1){ - return Color.WHITE; - } else { - return Color.BLACK; - } - } - - /** - * 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 - * @return The color bitmap - */ - public static Bitmap parseToRGB(byte[] data, int length, - boolean transparency, byte[] clut) { - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int bitsPerImg = data[valueIndex++] & 0xFF; - int numOfClutEntries = data[valueIndex++] & 0xFF; - - if (true == transparency) { - clut[numOfClutEntries - 1] = Color.TRANSPARENT; - } - - int numOfPixels = width * height; - int[] pixels = new int[numOfPixels]; - - valueIndex = 6; - int pixelIndex = 0; - int bitsStartOffset = 8 - bitsPerImg; - int bitIndex = bitsStartOffset; - byte currentByte = data[valueIndex++]; - int mask = getMask(bitsPerImg); - boolean bitsOverlaps = (8 % bitsPerImg == 0); - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (bitIndex < 0) { - currentByte = data[valueIndex++]; - bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1); - } - int clutEntry = ((currentByte >> bitIndex) & mask); - int clutIndex = clutEntry * CLUT_ENTRY_SIZE; - pixels[pixelIndex++] = Color.rgb(clut[clutIndex], - clut[clutIndex + 1], clut[clutIndex + 2]); - bitIndex -= bitsPerImg; - } - - return Bitmap.createBitmap(pixels, width, height, - Bitmap.Config.ARGB_8888); - } - - /** - * 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 - */ - private static int getMask(int numOfBits) { - int mask = 0x00; - - switch (numOfBits) { - case 1: - mask = 0x01; - break; - case 2: - mask = 0x03; - break; - case 3: - mask = 0x07; - break; - case 4: - mask = 0x0F; - break; - case 5: - mask = 0x1F; - break; - case 6: - mask = 0x3F; - break; - case 7: - mask = 0x7F; - break; - case 8: - mask = 0xFF; - break; - } - return mask; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java deleted file mode 100644 index 711d97793653..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java +++ /dev/null @@ -1,77 +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.cat; - -/** - * {@hide} - */ -public class ImageDescriptor { - // members - int width; - int height; - int codingScheme; - int imageId; - int highOffset; - int lowOffset; - int length; - - // constants - static final int CODING_SCHEME_BASIC = 0x11; - static final int CODING_SCHEME_COLOUR = 0x21; - - // public static final int ID_LENGTH = 9; - // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES - - ImageDescriptor() { - width = 0; - height = 0; - codingScheme = 0; - imageId = 0; - highOffset = 0; - lowOffset = 0; - length = 0; - } - - /** - * Extract descriptor information about image instance. - * - * @param rawData - * @param valueIndex - * @return ImageDescriptor - */ - static ImageDescriptor parse(byte[] rawData, int valueIndex) { - ImageDescriptor d = new ImageDescriptor(); - try { - d.width = rawData[valueIndex++] & 0xff; - d.height = rawData[valueIndex++] & 0xff; - d.codingScheme = rawData[valueIndex++] & 0xff; - - // parse image id - d.imageId = (rawData[valueIndex++] & 0xff) << 8; - d.imageId |= rawData[valueIndex++] & 0xff; - // parse offset - d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset - d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset - - d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff)); - } catch (IndexOutOfBoundsException e) { - CatLog.d("ImageDescripter", "parse; failed parsing image descriptor"); - d = null; - } - return d; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java deleted file mode 100644 index 13a5ad46cb32..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/Input.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.cat; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for CAT GET INPUT, GET IN KEY commands parameters. - * - */ -public class Input implements Parcelable { - public String text; - public String defaultText; - public Bitmap icon; - public int minLen; - public int maxLen; - public boolean ucs2; - public boolean packed; - public boolean digitOnly; - public boolean echo; - public boolean yesNo; - public boolean helpAvailable; - public Duration duration; - - Input() { - text = ""; - defaultText = null; - icon = null; - minLen = 0; - maxLen = 1; - ucs2 = false; - packed = false; - digitOnly = false; - echo = false; - yesNo = false; - helpAvailable = false; - duration = null; - } - - private Input(Parcel in) { - text = in.readString(); - defaultText = in.readString(); - icon = in.readParcelable(null); - minLen = in.readInt(); - maxLen = in.readInt(); - ucs2 = in.readInt() == 1 ? true : false; - packed = in.readInt() == 1 ? true : false; - digitOnly = in.readInt() == 1 ? true : false; - echo = in.readInt() == 1 ? true : false; - yesNo = in.readInt() == 1 ? true : false; - helpAvailable = in.readInt() == 1 ? true : false; - duration = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(text); - dest.writeString(defaultText); - dest.writeParcelable(icon, 0); - dest.writeInt(minLen); - dest.writeInt(maxLen); - dest.writeInt(ucs2 ? 1 : 0); - dest.writeInt(packed ? 1 : 0); - dest.writeInt(digitOnly ? 1 : 0); - dest.writeInt(echo ? 1 : 0); - dest.writeInt(yesNo ? 1 : 0); - dest.writeInt(helpAvailable ? 1 : 0); - dest.writeParcelable(duration, 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Input createFromParcel(Parcel in) { - return new Input(in); - } - - public Input[] newArray(int size) { - return new Input[size]; - } - }; - - boolean setIcon(Bitmap Icon) { return true; } -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java deleted file mode 100644 index d4702bbaf5e4..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/Item.java +++ /dev/null @@ -1,71 +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.cat; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Represents an Item COMPREHENSION-TLV object. - * - * {@hide} - */ -public class Item implements Parcelable { - /** Identifier of the item. */ - public int id; - /** Text string of the item. */ - public String text; - /** Icon of the item */ - public Bitmap icon; - - public Item(int id, String text) { - this.id = id; - this.text = text; - this.icon = null; - } - - public Item(Parcel in) { - id = in.readInt(); - text = in.readString(); - icon = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(id); - dest.writeString(text); - dest.writeParcelable(icon, flags); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Item createFromParcel(Parcel in) { - return new Item(in); - } - - public Item[] newArray(int size) { - return new Item[size]; - } - }; - - public String toString() { - return text; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java deleted file mode 100644 index af043d154456..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java +++ /dev/null @@ -1,35 +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.cat; - - -/** - * Browser launch mode for LAUNCH BROWSER proactive command. - * - * {@hide} - */ -public enum LaunchBrowserMode { - /** Launch browser if not already launched. */ - LAUNCH_IF_NOT_ALREADY_LAUNCHED, - /** - * Use the existing browser (the browser shall not use the active existing - * secured session). - */ - USE_EXISTING_BROWSER, - /** Close the existing browser session and launch new browser session. */ - LAUNCH_NEW_BROWSER; -} diff --git a/telephony/java/com/android/internal/telephony/cat/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java deleted file mode 100644 index 7bbae013d2c9..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/Menu.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.cat; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; - -/** - * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters. - * - */ -public class Menu implements Parcelable { - public List items; - public List titleAttrs; - public PresentationType presentationType; - public String title; - public Bitmap titleIcon; - public int defaultItem; - public boolean softKeyPreferred; - public boolean helpAvailable; - public boolean titleIconSelfExplanatory; - public boolean itemsIconSelfExplanatory; - - public Menu() { - // Create an empty list. - items = new ArrayList(); - title = null; - titleAttrs = null; - defaultItem = 0; - softKeyPreferred = false; - helpAvailable = false; - titleIconSelfExplanatory = false; - itemsIconSelfExplanatory = false; - titleIcon = null; - // set default style to be navigation menu. - presentationType = PresentationType.NAVIGATION_OPTIONS; - } - - private Menu(Parcel in) { - title = in.readString(); - titleIcon = in.readParcelable(null); - // rebuild items list. - items = new ArrayList(); - int size = in.readInt(); - for (int i=0; i CREATOR = new Parcelable.Creator

() { - public Menu createFromParcel(Parcel in) { - return new Menu(in); - } - - public Menu[] newArray(int size) { - return new Menu[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/cat/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java deleted file mode 100644 index 7c8cd8c14206..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/PresentationType.java +++ /dev/null @@ -1,32 +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.cat; - - -/** - * Presentation types for SELECT TYPE proactive command. - * - * {@hide} - */ -public enum PresentationType { - /** Presentation type is not specified */ - NOT_SPECIFIED, - /** Presentation as a choice of data values */ - DATA_VALUES, - /** Presentation as a choice of navigation options */ - NAVIGATION_OPTIONS; -} diff --git a/telephony/java/com/android/internal/telephony/cat/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java deleted file mode 100644 index 1157c1ae3a01..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ResponseData.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.internal.telephony.cat; - -import com.android.internal.telephony.EncodeException; -import com.android.internal.telephony.GsmAlphabet; -import java.util.Calendar; -import java.util.TimeZone; -import android.os.SystemProperties; -import android.text.TextUtils; - -import com.android.internal.telephony.cat.AppInterface.CommandType; - -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -abstract class ResponseData { - /** - * Format the data appropriate for TERMINAL RESPONSE and write it into - * the ByteArrayOutputStream object. - */ - public abstract void format(ByteArrayOutputStream buf); - - public static void writeLength(ByteArrayOutputStream buf, int length) { - // As per ETSI 102.220 Sec7.1.2, if the total length is greater - // than 0x7F, it should be coded in two bytes and the first byte - // should be 0x81. - if (length > 0x7F) { - buf.write(0x81); - } - buf.write(length); - } -} - -class SelectItemResponseData extends ResponseData { - // members - private int id; - - public SelectItemResponseData(int id) { - super(); - this.id = id; - } - - @Override - public void format(ByteArrayOutputStream buf) { - // Item identifier object - int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); // tag - buf.write(1); // length - buf.write(id); // identifier of item chosen - } -} - -class GetInkeyInputResponseData extends ResponseData { - // members - private boolean mIsUcs2; - private boolean mIsPacked; - private boolean mIsYesNo; - private boolean mYesNoResponse; - public String mInData; - - // GetInKey Yes/No response characters constants. - protected static final byte GET_INKEY_YES = 0x01; - protected static final byte GET_INKEY_NO = 0x00; - - public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) { - super(); - this.mIsUcs2 = ucs2; - this.mIsPacked = packed; - this.mInData = inData; - this.mIsYesNo = false; - } - - public GetInkeyInputResponseData(boolean yesNoResponse) { - super(); - this.mIsUcs2 = false; - this.mIsPacked = false; - this.mInData = ""; - this.mIsYesNo = true; - this.mYesNoResponse = yesNoResponse; - } - - @Override - public void format(ByteArrayOutputStream buf) { - if (buf == null) { - return; - } - - // Text string object - int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value(); - buf.write(tag); // tag - - byte[] data; - - if (mIsYesNo) { - data = new byte[1]; - data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO; - } else if (mInData != null && mInData.length() > 0) { - try { - if (mIsUcs2) { - data = mInData.getBytes("UTF-16"); - } else if (mIsPacked) { - int size = mInData.length(); - - byte[] tempData = GsmAlphabet - .stringToGsm7BitPacked(mInData, 0, 0); - data = new byte[size]; - // Since stringToGsm7BitPacked() set byte 0 in the - // returned byte array to the count of septets used... - // copy to a new array without byte 0. - System.arraycopy(tempData, 1, data, 0, size); - } else { - data = GsmAlphabet.stringToGsm8BitPacked(mInData); - } - } catch (UnsupportedEncodingException e) { - data = new byte[0]; - } catch (EncodeException e) { - data = new byte[0]; - } - } else { - data = new byte[0]; - } - - // length - one more for data coding scheme. - writeLength(buf, data.length + 1); - - // data coding scheme - if (mIsUcs2) { - buf.write(0x08); // UCS2 - } else if (mIsPacked) { - buf.write(0x00); // 7 bit packed - } else { - buf.write(0x04); // 8 bit unpacked - } - - for (byte b : data) { - buf.write(b); - } - } -} - -// For "PROVIDE LOCAL INFORMATION" command. -// See TS 31.111 section 6.4.15/ETSI TS 102 223 -// TS 31.124 section 27.22.4.15 for test spec -class LanguageResponseData extends ResponseData { - private String lang; - - public LanguageResponseData(String lang) { - super(); - this.lang = lang; - } - - @Override - public void format(ByteArrayOutputStream buf) { - if (buf == null) { - return; - } - - // Text string object - int tag = 0x80 | ComprehensionTlvTag.LANGUAGE.value(); - buf.write(tag); // tag - - byte[] data; - - if (lang != null && lang.length() > 0) { - data = GsmAlphabet.stringToGsm8BitPacked(lang); - } - else { - data = new byte[0]; - } - - buf.write(data.length); - - for (byte b : data) { - buf.write(b); - } - } -} - -// For "PROVIDE LOCAL INFORMATION" command. -// See TS 31.111 section 6.4.15/ETSI TS 102 223 -// TS 31.124 section 27.22.4.15 for test spec -class DTTZResponseData extends ResponseData { - private Calendar calendar; - - public DTTZResponseData(Calendar cal) { - super(); - calendar = cal; - } - - @Override - public void format(ByteArrayOutputStream buf) { - if (buf == null) { - return; - } - - // DTTZ object - int tag = 0x80 | CommandType.PROVIDE_LOCAL_INFORMATION.value(); - buf.write(tag); // tag - - byte[] data = new byte[8]; - - data[0] = 0x07; // Write length of DTTZ data - - if (calendar == null) { - calendar = Calendar.getInstance(); - } - // Fill year byte - data[1] = byteToBCD(calendar.get(java.util.Calendar.YEAR) % 100); - - // Fill month byte - data[2] = byteToBCD(calendar.get(java.util.Calendar.MONTH) + 1); - - // Fill day byte - data[3] = byteToBCD(calendar.get(java.util.Calendar.DATE)); - - // Fill hour byte - data[4] = byteToBCD(calendar.get(java.util.Calendar.HOUR_OF_DAY)); - - // Fill minute byte - data[5] = byteToBCD(calendar.get(java.util.Calendar.MINUTE)); - - // Fill second byte - data[6] = byteToBCD(calendar.get(java.util.Calendar.SECOND)); - - String tz = SystemProperties.get("persist.sys.timezone", ""); - if (TextUtils.isEmpty(tz)) { - data[7] = (byte) 0xFF; // set FF in terminal response - } else { - TimeZone zone = TimeZone.getTimeZone(tz); - int zoneOffset = zone.getRawOffset() + zone.getDSTSavings(); - data[7] = getTZOffSetByte(zoneOffset); - } - - for (byte b : data) { - buf.write(b); - } - } - - private byte byteToBCD(int value) { - if (value < 0 && value > 99) { - CatLog.d(this, "Err: byteToBCD conversion Value is " + value + - " Value has to be between 0 and 99"); - return 0; - } - - return (byte) ((value / 10) | ((value % 10) << 4)); - } - - private byte getTZOffSetByte(long offSetVal) { - boolean isNegative = (offSetVal < 0); - - /* - * The 'offSetVal' is in milliseconds. Convert it to hours and compute - * offset While sending T.R to UICC, offset is expressed is 'quarters of - * hours' - */ - - long tzOffset = offSetVal / (15 * 60 * 1000); - tzOffset = (isNegative ? -1 : 1) * tzOffset; - byte bcdVal = byteToBCD((int) tzOffset); - // For negative offsets, put '1' in the msb - return isNegative ? (bcdVal |= 0x08) : bcdVal; - } - -} - diff --git a/telephony/java/com/android/internal/telephony/cat/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java deleted file mode 100644 index 85441751c9e4..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ResultCode.java +++ /dev/null @@ -1,186 +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.cat; - - -/** - * Enumeration for the return code in TERMINAL RESPONSE. - * To get the actual return code for each enum value, call {@link #code() code} - * method. - * - * {@hide} - */ -public enum ResultCode { - - /* - * Results '0X' and '1X' indicate that the command has been performed. - */ - - /** Command performed successfully */ - OK(0x00), - - /** Command performed with partial comprehension */ - PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01), - - /** Command performed, with missing information */ - PRFRMD_WITH_MISSING_INFO(0x02), - - /** REFRESH performed with additional EFs read */ - PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03), - - /** - * Command performed successfully, but requested icon could not be - * displayed - */ - PRFRMD_ICON_NOT_DISPLAYED(0x04), - - /** Command performed, but modified by call control by NAA */ - PRFRMD_MODIFIED_BY_NAA(0x05), - - /** Command performed successfully, limited service */ - PRFRMD_LIMITED_SERVICE(0x06), - - /** Command performed with modification */ - PRFRMD_WITH_MODIFICATION(0x07), - - /** REFRESH performed but indicated NAA was not active */ - PRFRMD_NAA_NOT_ACTIVE(0x08), - - /** Command performed successfully, tone not played */ - PRFRMD_TONE_NOT_PLAYED(0x09), - - /** Proactive UICC session terminated by the user */ - UICC_SESSION_TERM_BY_USER(0x10), - - /** Backward move in the proactive UICC session requested by the user */ - BACKWARD_MOVE_BY_USER(0x11), - - /** No response from user */ - NO_RESPONSE_FROM_USER(0x12), - - /** Help information required by the user */ - HELP_INFO_REQUIRED(0x13), - - /** USSD or SS transaction terminated by the user */ - USSD_SS_SESSION_TERM_BY_USER(0x14), - - - /* - * Results '2X' indicate to the UICC that it may be worth re-trying the - * command at a later opportunity. - */ - - /** Terminal currently unable to process command */ - TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20), - - /** Network currently unable to process command */ - NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21), - - /** User did not accept the proactive command */ - USER_NOT_ACCEPT(0x22), - - /** User cleared down call before connection or network release */ - USER_CLEAR_DOWN_CALL(0x23), - - /** Action in contradiction with the current timer state */ - CONTRADICTION_WITH_TIMER(0x24), - - /** Interaction with call control by NAA, temporary problem */ - NAA_CALL_CONTROL_TEMPORARY(0x25), - - /** Launch browser generic error code */ - LAUNCH_BROWSER_ERROR(0x26), - - /** MMS temporary problem. */ - MMS_TEMPORARY(0x27), - - - /* - * Results '3X' indicate that it is not worth the UICC re-trying with an - * identical command, as it will only get the same response. However, the - * decision to retry lies with the application. - */ - - /** Command beyond terminal's capabilities */ - BEYOND_TERMINAL_CAPABILITY(0x30), - - /** Command type not understood by terminal */ - CMD_TYPE_NOT_UNDERSTOOD(0x31), - - /** Command data not understood by terminal */ - CMD_DATA_NOT_UNDERSTOOD(0x32), - - /** Command number not known by terminal */ - CMD_NUM_NOT_KNOWN(0x33), - - /** SS Return Error */ - SS_RETURN_ERROR(0x34), - - /** SMS RP-ERROR */ - SMS_RP_ERROR(0x35), - - /** Error, required values are missing */ - REQUIRED_VALUES_MISSING(0x36), - - /** USSD Return Error */ - USSD_RETURN_ERROR(0x37), - - /** MultipleCard commands error */ - MULTI_CARDS_CMD_ERROR(0x38), - - /** - * Interaction with call control by USIM or MO short message control by - * USIM, permanent problem - */ - USIM_CALL_CONTROL_PERMANENT(0x39), - - /** Bearer Independent Protocol error */ - BIP_ERROR(0x3a), - - /** Access Technology unable to process command */ - ACCESS_TECH_UNABLE_TO_PROCESS(0x3b), - - /** Frames error */ - FRAMES_ERROR(0x3c), - - /** MMS Error */ - MMS_ERROR(0x3d); - - - private int mCode; - - ResultCode(int code) { - mCode = code; - } - - /** - * Retrieves the actual result code that this object represents. - * @return Actual result code - */ - public int value() { - return mCode; - } - - public static ResultCode fromInt(int value) { - for (ResultCode r : ResultCode.values()) { - if (r.mCode == value) { - return r; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java deleted file mode 100644 index 84879c22ea6d..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ResultException.java +++ /dev/null @@ -1,97 +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.cat; - - -/** - * Class for errors in the Result object. - * - * {@hide} - */ -public class ResultException extends CatException { - private ResultCode mResult; - private int mAdditionalInfo; - private String mExplanation; - - public ResultException(ResultCode result) { - super(); - - // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26', - // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal - // to provide a specific cause value as additional information. - switch (result) { - case TERMINAL_CRNTLY_UNABLE_TO_PROCESS: // 0x20 - case NETWORK_CRNTLY_UNABLE_TO_PROCESS: // 0x21 - case LAUNCH_BROWSER_ERROR: // 0x26 - case MULTI_CARDS_CMD_ERROR: // 0x38 - case USIM_CALL_CONTROL_PERMANENT: // 0x39 - case BIP_ERROR: // 0x3a - case FRAMES_ERROR: // 0x3c - case MMS_ERROR: // 0x3d - throw new AssertionError( - "For result code, " + result + - ", additional information must be given!"); - } - - mResult = result; - mAdditionalInfo = -1; - mExplanation = ""; - } - - public ResultException(ResultCode result, String explanation) { - this(result); - mExplanation = explanation; - } - - public ResultException(ResultCode result, int additionalInfo) { - this(result); - - if (additionalInfo < 0) { - throw new AssertionError( - "Additional info must be greater than zero!"); - } - - mAdditionalInfo = additionalInfo; - } - - public ResultException(ResultCode result, int additionalInfo, String explanation) { - this(result, additionalInfo); - mExplanation = explanation; - } - - public ResultCode result() { - return mResult; - } - - public boolean hasAdditionalInfo() { - return mAdditionalInfo >= 0; - } - - public int additionalInfo() { - return mAdditionalInfo; - } - - public String explanation() { - return mExplanation; - } - - @Override - public String toString() { - return "result=" + mResult + " additionalInfo=" + mAdditionalInfo + - " explantion=" + mExplanation; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java deleted file mode 100644 index fb33a8ec5b92..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.cat; - -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccUtils; - -import android.os.Handler; -import com.android.internal.util.State; -import com.android.internal.util.StateMachine; -import android.os.Message; - -/** - * Class used for queuing raw ril messages, decoding them into CommanParams - * objects and sending the result back to the CAT Service. - */ -class RilMessageDecoder extends StateMachine { - - // constants - private static final int CMD_START = 1; - private static final int CMD_PARAMS_READY = 2; - - // members - private static RilMessageDecoder sInstance = null; - private CommandParamsFactory mCmdParamsFactory = null; - private RilMessage mCurrentRilMessage = null; - private Handler mCaller = null; - - // States - private StateStart mStateStart = new StateStart(); - private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady(); - - /** - * Get the singleton instance, constructing if necessary. - * - * @param caller - * @param fh - * @return RilMesssageDecoder - */ - public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) { - if (sInstance == null) { - sInstance = new RilMessageDecoder(caller, fh); - sInstance.start(); - } - return sInstance; - } - - /** - * Start decoding the message parameters, - * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller. - * - * @param rilMsg - */ - public void sendStartDecodingMessageParams(RilMessage rilMsg) { - Message msg = obtainMessage(CMD_START); - msg.obj = rilMsg; - sendMessage(msg); - } - - /** - * The command parameters have been decoded. - * - * @param resCode - * @param cmdParams - */ - public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) { - Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY); - msg.arg1 = resCode.value(); - msg.obj = cmdParams; - sendMessage(msg); - } - - private void sendCmdForExecution(RilMessage rilMsg) { - Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED, - new RilMessage(rilMsg)); - msg.sendToTarget(); - } - - private RilMessageDecoder(Handler caller, IccFileHandler fh) { - super("RilMessageDecoder"); - - addState(mStateStart); - addState(mStateCmdParamsReady); - setInitialState(mStateStart); - - mCaller = caller; - mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh); - } - - private class StateStart extends State { - @Override - public boolean processMessage(Message msg) { - if (msg.what == CMD_START) { - if (decodeMessageParams((RilMessage)msg.obj)) { - transitionTo(mStateCmdParamsReady); - } - } else { - CatLog.d(this, "StateStart unexpected expecting START=" + - CMD_START + " got " + msg.what); - } - return true; - } - } - - private class StateCmdParamsReady extends State { - @Override - public boolean processMessage(Message msg) { - if (msg.what == CMD_PARAMS_READY) { - mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1); - mCurrentRilMessage.mData = msg.obj; - sendCmdForExecution(mCurrentRilMessage); - transitionTo(mStateStart); - } else { - CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY=" - + CMD_PARAMS_READY + " got " + msg.what); - deferMessage(msg); - } - return true; - } - } - - private boolean decodeMessageParams(RilMessage rilMsg) { - boolean decodingStarted; - - mCurrentRilMessage = rilMsg; - switch(rilMsg.mId) { - case CatService.MSG_ID_SESSION_END: - case CatService.MSG_ID_CALL_SETUP: - mCurrentRilMessage.mResCode = ResultCode.OK; - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - break; - case CatService.MSG_ID_PROACTIVE_COMMAND: - case CatService.MSG_ID_EVENT_NOTIFY: - case CatService.MSG_ID_REFRESH: - byte[] rawData = null; - try { - rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); - } catch (Exception e) { - // zombie messages are dropped - CatLog.d(this, "decodeMessageParams dropping zombie messages"); - decodingStarted = false; - break; - } - try { - // Start asynch parsing of the command parameters. - mCmdParamsFactory.make(BerTlv.decode(rawData)); - decodingStarted = true; - } catch (ResultException e) { - // send to Service for proper RIL communication. - CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e); - mCurrentRilMessage.mResCode = e.result(); - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - } - break; - default: - decodingStarted = false; - break; - } - return decodingStarted; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java deleted file mode 100644 index 7fb58a5d4696..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java +++ /dev/null @@ -1,52 +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.cat; - - -/** - * Enumeration for representing text alignment. - * - * {@hide} - */ -public enum TextAlignment { - LEFT(0x0), - CENTER(0x1), - RIGHT(0x2), - /** Language dependent (default) */ - DEFAULT(0x3); - - private int mValue; - - TextAlignment(int value) { - mValue = value; - } - - /** - * Create a TextAlignment object. - * @param value Integer value to be converted to a TextAlignment object. - * @return TextAlignment object whose value is {@code value}. If no - * TextAlignment object has that value, null is returned. - */ - public static TextAlignment fromInt(int value) { - for (TextAlignment e : TextAlignment.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java deleted file mode 100644 index 0dea6407fc73..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java +++ /dev/null @@ -1,49 +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.cat; - - -/** - * Class for representing text attributes for SIM Toolkit. - * - * {@hide} - */ -public class TextAttribute { - public int start; - public int length; - public TextAlignment align; - public FontSize size; - public boolean bold; - public boolean italic; - public boolean underlined; - public boolean strikeThrough; - public TextColor color; - - public TextAttribute(int start, int length, TextAlignment align, - FontSize size, boolean bold, boolean italic, boolean underlined, - boolean strikeThrough, TextColor color) { - this.start = start; - this.length = length; - this.align = align; - this.size = size; - this.bold = bold; - this.italic = italic; - this.underlined = underlined; - this.strikeThrough = strikeThrough; - this.color = color; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java deleted file mode 100644 index 6447e740de9d..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/TextColor.java +++ /dev/null @@ -1,63 +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.cat; - - -/** - * Enumeration for representing text color. - * - * {@hide} - */ -public enum TextColor { - BLACK(0x0), - DARK_GRAY(0x1), - DARK_RED(0x2), - DARK_YELLOW(0x3), - DARK_GREEN(0x4), - DARK_CYAN(0x5), - DARK_BLUE(0x6), - DARK_MAGENTA(0x7), - GRAY(0x8), - WHITE(0x9), - BRIGHT_RED(0xa), - BRIGHT_YELLOW(0xb), - BRIGHT_GREEN(0xc), - BRIGHT_CYAN(0xd), - BRIGHT_BLUE(0xe), - BRIGHT_MAGENTA(0xf); - - private int mValue; - - TextColor(int value) { - mValue = value; - } - - /** - * Create a TextColor object. - * @param value Integer value to be converted to a TextColor object. - * @return TextColor object whose value is {@code value}. If no TextColor - * object has that value, null is returned. - */ - public static TextColor fromInt(int value) { - for (TextColor e : TextColor.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java deleted file mode 100644 index 5ffd07635da7..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/TextMessage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.cat; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -public class TextMessage implements Parcelable { - public String title = ""; - public String text = null; - public Bitmap icon = null; - public boolean iconSelfExplanatory = false; - public boolean isHighPriority = false; - public boolean responseNeeded = true; - public boolean userClear = false; - public Duration duration = null; - - TextMessage() { - } - - private TextMessage(Parcel in) { - title = in.readString(); - text = in.readString(); - icon = in.readParcelable(null); - iconSelfExplanatory = in.readInt() == 1 ? true : false; - isHighPriority = in.readInt() == 1 ? true : false; - responseNeeded = in.readInt() == 1 ? true : false; - userClear = in.readInt() == 1 ? true : false; - duration = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(title); - dest.writeString(text); - dest.writeParcelable(icon, 0); - dest.writeInt(iconSelfExplanatory ? 1 : 0); - dest.writeInt(isHighPriority ? 1 : 0); - dest.writeInt(responseNeeded ? 1 : 0); - dest.writeInt(userClear ? 1 : 0); - dest.writeParcelable(duration, 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public TextMessage createFromParcel(Parcel in) { - return new TextMessage(in); - } - - public TextMessage[] newArray(int size) { - return new TextMessage[size]; - } - }; -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java deleted file mode 100644 index 27b4489fe515..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/Tone.java +++ /dev/null @@ -1,190 +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.cat; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Enumeration for representing the tone values for use with PLAY TONE - * proactive commands. - * - * {@hide} - */ -public enum Tone implements Parcelable { - // Standard supervisory tones - - /** - * Dial tone. - */ - DIAL(0x01), - - /** - * Called subscriber busy. - */ - BUSY(0x02), - - /** - * Congestion. - */ - CONGESTION(0x03), - - /** - * Radio path acknowledge. - */ - RADIO_PATH_ACK(0x04), - - /** - * Radio path not available / Call dropped. - */ - RADIO_PATH_NOT_AVAILABLE(0x05), - - /** - * Error/Special information. - */ - ERROR_SPECIAL_INFO(0x06), - - /** - * Call waiting tone. - */ - CALL_WAITING(0x07), - - /** - * Ringing tone. - */ - RINGING(0x08), - - // Terminal proprietary tones - - /** - * General beep. - */ - GENERAL_BEEP(0x10), - - /** - * Positive acknowledgement tone. - */ - POSITIVE_ACK(0x11), - - /** - * Negative acknowledgement tone. - */ - NEGATIVE_ACK(0x12), - - /** - * Ringing tone as selected by the user for incoming speech call. - */ - INCOMING_SPEECH_CALL(0x13), - - /** - * Alert tone as selected by the user for incoming SMS. - */ - INCOMING_SMS(0x14), - - /** - * Critical alert. - * This tone is to be used in critical situations. The terminal shall make - * every effort to alert the user when this tone is indicated independent - * from the volume setting in the terminal. - */ - CRITICAL_ALERT(0x15), - - /** - * Vibrate only, if available. - */ - VIBRATE_ONLY(0x20), - - // Themed tones - - /** - * Happy tone. - */ - HAPPY(0x30), - - /** - * Sad tone. - */ - SAD(0x31), - - /** - * Urgent action tone. - */ - URGENT(0x32), - - /** - * Question tone. - */ - QUESTION(0x33), - - /** - * Message received tone. - */ - MESSAGE_RECEIVED(0x34), - - // Melody tones - MELODY_1(0x40), - MELODY_2(0x41), - MELODY_3(0x42), - MELODY_4(0x43), - MELODY_5(0x44), - MELODY_6(0x45), - MELODY_7(0x46), - MELODY_8(0x47); - - private int mValue; - - Tone(int value) { - mValue = value; - } - - /** - * Create a Tone object. - * @param value Integer value to be converted to a Tone object. - * @return Tone object whose value is {@code value}. If no Tone object has - * that value, null is returned. - */ - public static Tone fromInt(int value) { - for (Tone e : Tone.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - - Tone(Parcel in) { - mValue = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Tone createFromParcel(Parcel in) { - return Tone.values()[in.readInt()]; - } - - public Tone[] newArray(int size) { - return new Tone[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java deleted file mode 100644 index 6375afb6adbf..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.cat; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for PlayTone commands parameters. - * - */ -public class ToneSettings implements Parcelable { - public Duration duration; - public Tone tone; - public boolean vibrate; - - public ToneSettings(Duration duration, Tone tone, boolean vibrate) { - this.duration = duration; - this.tone = tone; - this.vibrate = vibrate; - } - - private ToneSettings(Parcel in) { - duration = in.readParcelable(null); - tone = in.readParcelable(null); - vibrate = in.readInt() == 1; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(duration, 0); - dest.writeParcelable(tone, 0); - dest.writeInt(vibrate ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public ToneSettings createFromParcel(Parcel in) { - return new ToneSettings(in); - } - - public ToneSettings[] newArray(int size) { - return new ToneSettings[size]; - } - }; -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java deleted file mode 100644 index 584d96cb522f..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/ValueParser.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.internal.telephony.cat; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.cat.Duration.TimeUnit; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -abstract class ValueParser { - - /** - * Search for a Command Details object from a list. - * - * @param ctlvs List of ComprehensionTlv objects used for search - * @return An CtlvCommandDetails object found from the objects. If no - * Command Details object is found, ResultException is thrown. - * @throws ResultException - */ - static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv) - throws ResultException { - - CommandDetails cmdDet = new CommandDetails(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - cmdDet.compRequired = ctlv.isComprehensionRequired(); - cmdDet.commandNumber = rawValue[valueIndex] & 0xff; - cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff; - cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff; - return cmdDet; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - /** - * 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. - * @throws ResultException - */ - static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv) - throws ResultException { - - DeviceIdentities devIds = new DeviceIdentities(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - devIds.sourceId = rawValue[valueIndex] & 0xff; - devIds.destinationId = rawValue[valueIndex + 1] & 0xff; - return devIds; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - } - - /** - * Retrieves Duration information from the Duration COMPREHENSION-TLV - * object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return A Duration object - * @throws ResultException - */ - static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException { - int timeInterval = 0; - TimeUnit timeUnit = TimeUnit.SECOND; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)]; - timeInterval = rawValue[valueIndex + 1] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return new Duration(timeInterval, timeUnit); - } - - /** - * Retrieves Item information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item - * @throws ResultException - */ - static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException { - Item item = null; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - int textLen = length - 1; - - try { - int id = rawValue[valueIndex] & 0xff; - String text = IccUtils.adnStringFieldToString(rawValue, - valueIndex + 1, textLen); - item = new Item(id, text); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - return item; - } - - /** - * Retrieves Item id information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item id - * @throws ResultException - */ - static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException { - int id = 0; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - id = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object - * - * @param ctlv An Icon Identifier COMPREHENSION-TLV object - * @return IconId instance - * @throws ResultException - */ - static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException { - IconId id = new IconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - id.recordNumber = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV - * object - * - * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object - * @return ItemsIconId instance - * @throws ResultException - */ - static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv) - throws ResultException { - CatLog.d("ValueParser", "retrieveItemsIconId:"); - ItemsIconId id = new ItemsIconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int numOfItems = ctlv.getLength() - 1; - id.recordNumbers = new int[numOfItems]; - - try { - // get icon self-explanatory - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - - for (int index = 0; index < numOfItems;) { - id.recordNumbers[index++] = rawValue[valueIndex++]; - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return id; - } - - /** - * 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 - */ - static List retrieveTextAttribute(ComprehensionTlv ctlv) - throws ResultException { - ArrayList lst = new ArrayList(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - // Each attribute is consisted of four bytes - int itemCount = length / 4; - - try { - for (int i = 0; i < itemCount; i++, valueIndex += 4) { - int start = rawValue[valueIndex] & 0xff; - int textLength = rawValue[valueIndex + 1] & 0xff; - int format = rawValue[valueIndex + 2] & 0xff; - int colorValue = rawValue[valueIndex + 3] & 0xff; - - int alignValue = format & 0x03; - TextAlignment align = TextAlignment.fromInt(alignValue); - - int sizeValue = (format >> 2) & 0x03; - FontSize size = FontSize.fromInt(sizeValue); - if (size == null) { - // Font size value is not defined. Use default. - size = FontSize.NORMAL; - } - - boolean bold = (format & 0x10) != 0; - boolean italic = (format & 0x20) != 0; - boolean underlined = (format & 0x40) != 0; - boolean strikeThrough = (format & 0x80) != 0; - - TextColor color = TextColor.fromInt(colorValue); - - TextAttribute attr = new TextAttribute(start, textLength, - align, size, bold, italic, underlined, - strikeThrough, color); - lst.add(attr); - } - - return lst; - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - return null; - } - - - /** - * 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 - */ - static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException { - - if (ctlv != null) { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - if (length != 0) { - try { - return IccUtils.adnStringFieldToString(rawValue, valueIndex, - length); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - return CatService.STK_DEFAULT; - } - } else { - return CatService.STK_DEFAULT; - } - } - - /** - * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it - * into a Java String. - * - * @param ctlv A Text COMPREHENSION-TLV object - * @return A Java String object decoded from the Text object - * @throws ResultException - */ - static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - byte codingScheme = 0x00; - String text = null; - int textLen = ctlv.getLength(); - - // In case the text length is 0, return a null string. - if (textLen == 0) { - return text; - } else { - // one byte is coding scheme - textLen -= 1; - } - - try { - codingScheme = (byte) (rawValue[valueIndex] & 0x0c); - - if (codingScheme == 0x00) { // GSM 7-bit packed - text = GsmAlphabet.gsm7BitPackedToString(rawValue, - valueIndex + 1, (textLen * 8) / 7); - } else if (codingScheme == 0x04) { // GSM 8-bit unpacked - text = GsmAlphabet.gsm8BitUnpackedToString(rawValue, - valueIndex + 1, textLen); - } else if (codingScheme == 0x08) { // UCS2 - text = new String(rawValue, valueIndex + 1, textLen, "UTF-16"); - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return text; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } catch (UnsupportedEncodingException e) { - // This should never happen. - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html deleted file mode 100644 index 5b6bfc656f0e..000000000000 --- a/telephony/java/com/android/internal/telephony/cat/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Provides classes for ICC Toolkit Service (CAT). - - diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java deleted file mode 100644 index d99a62595f5a..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2011 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.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Message; -import android.preference.PreferenceManager; -import android.provider.Telephony; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.OperatorInfo; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneNotifier; -import com.android.internal.telephony.PhoneProxy; -import com.android.internal.telephony.SMSDispatcher; -import com.android.internal.telephony.gsm.GsmSMSDispatcher; -import com.android.internal.telephony.gsm.SmsMessage; -import com.android.internal.telephony.ims.IsimRecords; -import com.android.internal.telephony.uicc.UiccController; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -public class CDMALTEPhone extends CDMAPhone { - static final String LOG_TAG = "CDMA"; - - private static final boolean DBG = true; - - /** Secondary SMSDispatcher for 3GPP format messages. */ - SMSDispatcher m3gppSMS; - - /** - * Small container class used to hold information relevant to - * the carrier selection process. operatorNumeric can be "" - * if we are looking for automatic selection. operatorAlphaLong is the - * corresponding operator name. - */ - private static class NetworkSelectMessage { - public Message message; - public String operatorNumeric; - public String operatorAlphaLong; - } - - // Constructors - public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) { - super(context, ci, notifier, false); - m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); - mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null); - } - - @Override - public void handleMessage (Message msg) { - AsyncResult ar; - switch (msg.what) { - // handle the select network completion callbacks. - case EVENT_SET_NETWORK_MANUAL_COMPLETE: - handleSetSelectNetwork((AsyncResult) msg.obj); - break; - case EVENT_NEW_ICC_SMS: - ar = (AsyncResult)msg.obj; - m3gppSMS.dispatchMessage((SmsMessage)ar.result); - break; - default: - super.handleMessage(msg); - } - } - - @Override - protected void initSstIcc() { - mIccCard.set(UiccController.getInstance(this).getIccCard()); - mIccRecords = mIccCard.get().getIccRecords(); - // CdmaLteServiceStateTracker registers with IccCard to know - // when the card is ready. So create mIccCard before the ServiceStateTracker - mSST = new CdmaLteServiceStateTracker(this); - } - - @Override - public void dispose() { - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - super.dispose(); - m3gppSMS.dispose(); - mIccRecords.unregisterForNewSms(this); - } - } - - @Override - public void removeReferences() { - super.removeReferences(); - m3gppSMS = null; - } - - @Override - public DataState getDataConnectionState(String apnType) { - DataState ret = DataState.DISCONNECTED; - - if (mSST == null) { - // Radio Technology Change is ongoing, dispose() and - // removeReferences() have already been called - - ret = DataState.DISCONNECTED; - } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false) { - ret = DataState.DISCONNECTED; - } else { - switch (mDataConnectionTracker.getState(apnType)) { - case FAILED: - case IDLE: - ret = DataState.DISCONNECTED; - break; - - case CONNECTED: - case DISCONNECTING: - if (mCT.state != Phone.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed()) { - ret = DataState.SUSPENDED; - } else { - ret = DataState.CONNECTED; - } - break; - - case INITING: - case CONNECTING: - case SCANNING: - ret = DataState.CONNECTING; - break; - } - } - - log("getDataConnectionState apnType=" + apnType + " ret=" + ret); - return ret; - } - - @Override - public void - selectNetworkManually(OperatorInfo network, - 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.getOperatorNumeric(); - nsm.operatorAlphaLong = network.getOperatorAlphaLong(); - - // get the message - Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); - - mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); - } - - /** - * 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. - if (!(ar.userObj instanceof NetworkSelectMessage)) { - Log.e(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. - if (nsm.message != null) { - if (DBG) log("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); - editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); - - // commit and log the result. - if (! editor.commit()) { - Log.e(LOG_TAG, "failed to commit network selection preference"); - } - - } - - @Override - public boolean updateCurrentCarrierInProvider() { - if (mIccRecords != null) { - try { - Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); - ContentValues map = new ContentValues(); - String operatorNumeric = mIccRecords.getOperatorNumeric(); - map.put(Telephony.Carriers.NUMERIC, operatorNumeric); - if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" + - operatorNumeric); - mContext.getContentResolver().insert(uri, map); - return true; - } catch (SQLException e) { - Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator ret false", e); - } - } else { - if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false"); - } - return false; - } - - // return IMSI from USIM as subscriber ID. - @Override - public String getSubscriberId() { - return mIccRecords.getIMSI(); - } - - @Override - public String getImei() { - return mImei; - } - - @Override - public String getDeviceSvn() { - return mImeiSv; - } - - @Override - public IsimRecords getIsimRecords() { - return mIccRecords.getIsimRecords(); - } - - @Override - public String getMsisdn() { - return mIccRecords.getMsisdnNumber(); - } - - @Override - public void getAvailableNetworks(Message response) { - mCM.getAvailableNetworks(response); - } - - @Override - public void requestIsimAuthentication(String nonce, Message result) { - mCM.requestIsimAuthentication(nonce, result); - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[CDMALTEPhone] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CDMALTEPhone extends:"); - super.dump(fd, pw, args); - pw.println(" m3gppSMS=" + m3gppSMS); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java deleted file mode 100755 index 9f6ec712385e..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ /dev/null @@ -1,1507 +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.cdma; - -import android.app.ActivityManagerNative; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Telephony; -import android.telephony.CellLocation; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.CallTracker; -import com.android.internal.telephony.CommandException; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccException; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccPhoneBookInterfaceManager; -import com.android.internal.telephony.IccSmsInterfaceManager; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.MmiCode; -import com.android.internal.telephony.OperatorInfo; -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.ServiceStateTracker; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.UUSInfo; -import com.android.internal.telephony.cat.CatService; -import com.android.internal.telephony.uicc.UiccController; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; - -/** - * {@hide} - */ -public class CDMAPhone extends PhoneBase { - static final String LOG_TAG = "CDMA"; - private static final boolean DBG = true; - private static final boolean VDBG = false; /* STOP SHIP if true */ - - // Default Emergency Callback Mode exit timer - private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000; - - static final String VM_COUNT_CDMA = "vm_count_key_cdma"; - private static final String VM_NUMBER_CDMA = "vm_number_key_cdma"; - private String mVmNumber = null; - - static final int RESTART_ECM_TIMER = 0; // restart Ecm timer - static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer - - // Instance Variables - CdmaCallTracker mCT; - CdmaServiceStateTracker mSST; - CdmaSubscriptionSourceManager mCdmaSSM; - ArrayList mPendingMmis = new ArrayList(); - RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager; - RuimSmsInterfaceManager mRuimSmsInterfaceManager; - int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN; - PhoneSubInfo mSubInfo; - EriManager mEriManager; - WakeLock mWakeLock; - - // mEriFileLoadedRegistrants are informed after the ERI text has been loaded - private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList(); - - // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started - private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList(); - - // mEcmExitRespRegistrant is informed after the phone has been exited - //the emergency callback mode - //keep track of if phone is in emergency callback mode - private boolean mIsPhoneInEcmState; - private Registrant mEcmExitRespRegistrant; - protected String mImei; - protected String mImeiSv; - private String mEsn; - private String mMeid; - // string to define how the carrier specifies its own ota sp number - private String mCarrierOtaSpNumSchema; - - // A runnable which is used to automatically exit from Ecm after a period of time. - private Runnable mExitEcmRunnable = new Runnable() { - @Override - public void run() { - exitEmergencyCallbackMode(); - } - }; - - Registrant mPostDialHandler; - - static String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = "ro.cdma.home.operator.numeric"; - - // Constructors - public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) { - super(notifier, context, ci, false); - initSstIcc(); - init(context, notifier); - } - - public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, - boolean unitTestMode) { - super(notifier, context, ci, unitTestMode); - initSstIcc(); - init(context, notifier); - } - - protected void initSstIcc() { - mIccCard.set(UiccController.getInstance(this).getIccCard()); - mIccRecords = mIccCard.get().getIccRecords(); - // CdmaServiceStateTracker registers with IccCard to know - // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker - mSST = new CdmaServiceStateTracker(this); - } - - protected void init(Context context, PhoneNotifier notifier) { - mCM.setPhoneType(Phone.PHONE_TYPE_CDMA); - mCT = new CdmaCallTracker(this); - mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context, mCM, this, - EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); - mSMS = new CdmaSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); - mDataConnectionTracker = new CdmaDataConnectionTracker (this); - mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this); - mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS); - mSubInfo = new PhoneSubInfo(this); - mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML); - - mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); - registerForRuimRecordEvents(); - mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - mCM.registerForOn(this, EVENT_RADIO_ON, null); - mCM.setOnSuppServiceNotification(this, EVENT_SSN, null); - mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); - mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null); - - PowerManager pm - = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,LOG_TAG); - - //Change the system setting - SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, - Integer.toString(Phone.PHONE_TYPE_CDMA)); - - // This is needed to handle phone process crashes - String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - mIsPhoneInEcmState = inEcm.equals("true"); - if (mIsPhoneInEcmState) { - // Send a message which will invoke handleExitEmergencyCallbackMode - mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE)); - } - - // get the string that specifies the carrier OTA Sp number - mCarrierOtaSpNumSchema = SystemProperties.get( - TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA,""); - - // Sets operator alpha property by retrieving from build-time system property - String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha"); - setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, operatorAlpha); - - // Sets operator numeric property by retrieving from build-time system property - String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC); - log("CDMAPhone: init set 'gsm.sim.operator.numeric' to operator='" + - operatorNumeric + "'"); - setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operatorNumeric); - - // Sets iso country property by retrieving from build-time system property - setIsoCountryProperty(operatorNumeric); - - // Sets current entry in the telephony carrier table - updateCurrentCarrierInProvider(operatorNumeric); - - // Notify voicemails. - notifier.notifyMessageWaitingChanged(this); - } - - @Override - public void dispose() { - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - super.dispose(); - log("dispose"); - - //Unregister from all former registered events - unregisterForRuimRecordEvents(); - mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE - mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE - mCM.unregisterForOn(this); //EVENT_RADIO_ON - mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK - mCM.unSetOnSuppServiceNotification(this); - removeCallbacks(mExitEcmRunnable); - - mPendingMmis.clear(); - - //Force all referenced classes to unregister their former registered events - mCT.dispose(); - mDataConnectionTracker.dispose(); - mSST.dispose(); - mCdmaSSM.dispose(this); - mSMS.dispose(); - mRuimPhoneBookInterfaceManager.dispose(); - mRuimSmsInterfaceManager.dispose(); - mSubInfo.dispose(); - mEriManager.dispose(); - } - } - - @Override - public void removeReferences() { - log("removeReferences"); - mRuimPhoneBookInterfaceManager = null; - mRuimSmsInterfaceManager = null; - mSubInfo = null; - mCT = null; - mSST = null; - mEriManager = null; - mExitEcmRunnable = null; - super.removeReferences(); - } - - @Override - protected void finalize() { - if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized"); - if (mWakeLock.isHeld()) { - Log.e(LOG_TAG, "UNEXPECTED; mWakeLock is held when finalizing."); - mWakeLock.release(); - } - } - - public ServiceState getServiceState() { - return mSST.ss; - } - - public CallTracker getCallTracker() { - return mCT; - } - - public Phone.State getState() { - return mCT.state; - } - - public ServiceStateTracker getServiceStateTracker() { - return mSST; - } - - public String getPhoneName() { - return "CDMA"; - } - - public int getPhoneType() { - return Phone.PHONE_TYPE_CDMA; - } - - public boolean canTransfer() { - Log.e(LOG_TAG, "canTransfer: not possible in CDMA"); - return false; - } - - 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 { - // 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); - } - - public void clearDisconnected() { - mCT.clearDisconnected(); - } - - public DataActivityState getDataActivityState() { - DataActivityState ret = DataActivityState.NONE; - - if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) { - - switch (mDataConnectionTracker.getActivity()) { - case DATAIN: - ret = DataActivityState.DATAIN; - break; - - case DATAOUT: - ret = DataActivityState.DATAOUT; - break; - - case DATAINANDOUT: - ret = DataActivityState.DATAINANDOUT; - break; - - case DORMANT: - ret = DataActivityState.DORMANT; - break; - } - } - return ret; - } - - /*package*/ void - notifySignalStrength() { - mNotifier.notifySignalStrength(this); - } - - public Connection - dial (String dialString) throws CallStateException { - // Need to make sure dialString gets parsed properly - String newDialString = PhoneNumberUtils.stripSeparators(dialString); - return mCT.dial(newDialString); - } - - public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { - throw new CallStateException("Sending UUS information NOT supported in CDMA!"); - } - - public SignalStrength getSignalStrength() { - return mSST.mSignalStrength; - } - - public boolean - getMessageWaitingIndicator() { - return (getVoiceMessageCount() > 0); - } - - public List - getPendingMmiCodes() { - return mPendingMmis; - } - - public void registerForSuppServiceNotification( - Handler h, int what, Object obj) { - Log.e(LOG_TAG, "method registerForSuppServiceNotification is NOT supported in CDMA!"); - } - - public CdmaCall getBackgroundCall() { - return mCT.backgroundCall; - } - - public boolean handleInCallMmiCommands(String dialString) { - Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!"); - return false; - } - - boolean isInCall() { - CdmaCall.State foregroundCallState = getForegroundCall().getState(); - CdmaCall.State backgroundCallState = getBackgroundCall().getState(); - CdmaCall.State ringingCallState = getRingingCall().getState(); - - return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState - .isAlive()); - } - - public void - setNetworkSelectionModeAutomatic(Message response) { - Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!"); - } - - public void unregisterForSuppServiceNotification(Handler h) { - Log.e(LOG_TAG, "method unregisterForSuppServiceNotification is NOT supported in CDMA!"); - } - - public void - acceptCall() throws CallStateException { - mCT.acceptCall(); - } - - public void - rejectCall() throws CallStateException { - mCT.rejectCall(); - } - - public void - switchHoldingAndActive() throws CallStateException { - mCT.switchWaitingOrHoldingAndActive(); - } - - public String getLine1Number() { - return mSST.getMdnNumber(); - } - - public String getCdmaPrlVersion(){ - return mSST.getPrlVersion(); - } - - public String getCdmaMin() { - return mSST.getCdmaMin(); - } - - public boolean isMinInfoReady() { - return mSST.isMinInfoReady(); - } - - 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 or ESN in CDMA - public String getDeviceId() { - String id = getMeid(); - if ((id == null) || id.matches("^0*$")) { - Log.d(LOG_TAG, "getDeviceId(): MEID is not initialized use ESN"); - id = getEsn(); - } - return id; - } - - public String getDeviceSvn() { - Log.d(LOG_TAG, "getDeviceSvn(): return 0"); - return "0"; - } - - public String getSubscriberId() { - return mSST.getImsi(); - } - - public String getImei() { - Log.e(LOG_TAG, "IMEI is not available in CDMA"); - return null; - } - - public boolean canConference() { - Log.e(LOG_TAG, "canConference: not possible in CDMA"); - return false; - } - - public CellLocation getCellLocation() { - return mSST.cellLoc; - } - - public CdmaCall getForegroundCall() { - return mCT.foregroundCall; - } - - public void - selectNetworkManually(OperatorInfo network, - Message response) { - Log.e(LOG_TAG, "selectNetworkManually: not possible in CDMA"); - } - - public void setOnPostDialCharacter(Handler h, int what, Object obj) { - mPostDialHandler = new Registrant(h, what, obj); - } - - public boolean handlePinMmi(String dialString) { - CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this); - - if (mmi == null) { - Log.e(LOG_TAG, "Mmi is NULL!"); - return false; - } else if (mmi.isPukCommand()) { - mPendingMmis.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.processCode(); - return true; - } - Log.e(LOG_TAG, "Unrecognized mmi!"); - return false; - } - - /** - * Removes the given MMI from the pending list and notifies registrants that - * it is complete. - * - * @param mmi MMI that is done - */ - void onMMIDone(CdmaMmiCode mmi) { - /* - * Only notify complete if it's on the pending list. Otherwise, it's - * already been handled (eg, previously canceled). - */ - if (mPendingMmis.remove(mmi)) { - mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - } - } - - public void setLine1Number(String alphaTag, String number, Message onComplete) { - Log.e(LOG_TAG, "setLine1Number: not possible in CDMA"); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!"); - } - - public void updateServiceLocation() { - mSST.enableSingleLocationUpdate(); - } - - public void setDataRoamingEnabled(boolean enable) { - mDataConnectionTracker.setDataOnRoamingEnabled(enable); - } - - public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { - mCM.registerForCdmaOtaProvision(h, what, obj); - } - - public void unregisterForCdmaOtaStatusChange(Handler h) { - mCM.unregisterForCdmaOtaProvision(h); - } - - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { - mSST.registerForSubscriptionInfoReady(h, what, obj); - } - - public void unregisterForSubscriptionInfoReady(Handler h) { - mSST.unregisterForSubscriptionInfoReady(h); - } - - public void setOnEcbModeExitResponse(Handler h, int what, Object obj) { - mEcmExitRespRegistrant = new Registrant (h, what, obj); - } - - public void unsetOnEcbModeExitResponse(Handler h) { - mEcmExitRespRegistrant.clear(); - } - - public void registerForCallWaiting(Handler h, int what, Object obj) { - mCT.registerForCallWaiting(h, what, obj); - } - - public void unregisterForCallWaiting(Handler h) { - mCT.unregisterForCallWaiting(h); - } - - public void - getNeighboringCids(Message response) { - /* - * This is currently not implemented. At least as of June - * 2009, there is no neighbor cell information available for - * CDMA because some party is resisting making this - * information readily available. Consequently, calling this - * function can have no useful effect. This situation may - * (and hopefully will) change in the future. - */ - if (response != null) { - CommandException ce = new CommandException( - CommandException.Error.REQUEST_NOT_SUPPORTED); - AsyncResult.forMessage(response).exception = ce; - response.sendToTarget(); - } - } - - public DataState getDataConnectionState(String apnType) { - DataState ret = DataState.DISCONNECTED; - - if (mSST == null) { - // Radio Technology Change is ongoning, dispose() and removeReferences() have - // already been called - - ret = DataState.DISCONNECTED; - } else if (mSST.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) { - // If we're out of service, open TCP sockets may still work - // but no data will flow - ret = DataState.DISCONNECTED; - } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false || - mDataConnectionTracker.isApnTypeActive(apnType) == false) { - ret = DataState.DISCONNECTED; - } else { - switch (mDataConnectionTracker.getState(apnType)) { - case FAILED: - case IDLE: - ret = DataState.DISCONNECTED; - break; - - case CONNECTED: - case DISCONNECTING: - if ( mCT.state != Phone.State.IDLE - && !mSST.isConcurrentVoiceAndDataAllowed()) { - ret = DataState.SUSPENDED; - } else { - ret = DataState.CONNECTED; - } - break; - - case INITING: - case CONNECTING: - case SCANNING: - ret = DataState.CONNECTING; - break; - } - } - - log("getDataConnectionState apnType=" + apnType + " ret=" + ret); - return ret; - } - - public void sendUssdResponse(String ussdMessge) { - Log.e(LOG_TAG, "sendUssdResponse: not possible in CDMA"); - } - - public void sendDtmf(char c) { - 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) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "startDtmf called with invalid character '" + c + "'"); - } else { - mCM.startDtmf(c, null); - } - } - - public void stopDtmf() { - mCM.stopDtmf(null); - } - - public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { - boolean check = true; - for (int itr = 0;itr < dtmfString.length(); itr++) { - if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) { - Log.e(LOG_TAG, - "sendDtmf called with invalid character '" + dtmfString.charAt(itr)+ "'"); - check = false; - break; - } - } - if ((mCT.state == Phone.State.OFFHOOK)&&(check)) { - mCM.sendBurstDtmf(dtmfString, on, off, onComplete); - } - } - - public void getAvailableNetworks(Message response) { - Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA"); - } - - public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) { - Log.e(LOG_TAG, "setOutgoingCallerIdDisplay: not possible in CDMA"); - } - - public void enableLocationUpdates() { - mSST.enableLocationUpdates(); - } - - public void disableLocationUpdates() { - mSST.disableLocationUpdates(); - } - - public void getDataCallList(Message response) { - mCM.getDataCallList(response); - } - - public boolean getDataRoamingEnabled() { - return mDataConnectionTracker.getDataOnRoamingEnabled(); - } - - public void setVoiceMailNumber(String alphaTag, - String voiceMailNumber, - Message onComplete) { - Message resp; - mVmNumber = voiceMailNumber; - resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete); - mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp); - } - - public String getVoiceMailNumber() { - String number = null; - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - // TODO: The default value of voicemail number should be read from a system property - - // Read platform settings for dynamic voicemail number - if (getContext().getResources().getBoolean(com.android.internal - .R.bool.config_telephony_use_own_number_for_voicemail)) { - number = sp.getString(VM_NUMBER_CDMA, getLine1Number()); - } else { - number = sp.getString(VM_NUMBER_CDMA, "*86"); - } - return number; - } - - /* Returns Number of Voicemails - * @hide - */ - public int getVoiceMessageCount() { - int voicemailCount = mIccRecords.getVoiceMessageCount(); - // If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility - // that phone was power cycled and would have lost the voicemail count. - // So get the count from preferences. - if (voicemailCount == 0) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - voicemailCount = sp.getInt(VM_COUNT_CDMA, 0); - } - return voicemailCount; - } - - public String getVoiceMailAlphaTag() { - // 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. - - //ret = mSIMRecords.getVoiceMailAlphaTag(); - - if (ret == null || ret.length() == 0) { - return mContext.getText( - com.android.internal.R.string.defaultVoiceMailAlphaTag).toString(); - } - - return ret; - } - - public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { - Log.e(LOG_TAG, "getCallForwardingOption: not possible in CDMA"); - } - - public void setCallForwardingOption(int commandInterfaceCFAction, - int commandInterfaceCFReason, - String dialingNumber, - int timerSeconds, - Message onComplete) { - Log.e(LOG_TAG, "setCallForwardingOption: not possible in CDMA"); - } - - public void - getOutgoingCallerIdDisplay(Message onComplete) { - Log.e(LOG_TAG, "getOutgoingCallerIdDisplay: not possible in CDMA"); - } - - public boolean - getCallForwardingIndicator() { - Log.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA"); - return false; - } - - public void explicitCallTransfer() { - Log.e(LOG_TAG, "explicitCallTransfer: not possible in CDMA"); - } - - public String getLine1AlphaTag() { - Log.e(LOG_TAG, "getLine1AlphaTag: not possible in CDMA"); - return null; - } - - /** - * Notify any interested party of a Phone state change {@link Phone.State} - */ - /*package*/ void notifyPhoneStateChanged() { - mNotifier.notifyPhoneState(this); - } - - /** - * Notify registrants of a change in the call state. This notifies changes in {@link Call.State} - * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged. - */ - /*package*/ void notifyPreciseCallStateChanged() { - /* we'd love it if this was package-scoped*/ - super.notifyPreciseCallStateChangedP(); - } - - void notifyServiceStateChanged(ServiceState ss) { - super.notifyServiceStateChangedP(ss); - } - - void notifyLocationChanged() { - mNotifier.notifyCellLocation(this); - } - - /*package*/ void notifyNewRingingConnection(Connection c) { - /* we'd love it if this was package-scoped*/ - super.notifyNewRingingConnectionP(c); - } - - /*package*/ void notifyDisconnect(Connection cn) { - mDisconnectRegistrants.notifyResult(cn); - } - - void notifyUnknownConnection() { - mUnknownConnectionRegistrants.notifyResult(this); - } - - public boolean isInEmergencyCall() { - return mCT.isInEmergencyCall(); - } - - public boolean isInEcm() { - return mIsPhoneInEcmState; - } - - void sendEmergencyCallbackModeChange(){ - //Send an Intent - Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); - intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInEcmState); - ActivityManagerNative.broadcastStickyIntent(intent,null); - if (DBG) Log.d(LOG_TAG, "sendEmergencyCallbackModeChange"); - } - - @Override - public void exitEmergencyCallbackMode() { - if (mWakeLock.isHeld()) { - mWakeLock.release(); - } - // Send a message which will invoke handleExitEmergencyCallbackMode - mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE)); - } - - private void handleEnterEmergencyCallbackMode(Message msg) { - if (DBG) { - Log.d(LOG_TAG, "handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= " - + mIsPhoneInEcmState); - } - // if phone is not in Ecm mode, and it's changed to Ecm mode - if (mIsPhoneInEcmState == false) { - mIsPhoneInEcmState = true; - // notify change - sendEmergencyCallbackModeChange(); - setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true"); - - // Post this runnable so we will automatically exit - // if no one invokes exitEmergencyCallbackMode() directly. - long delayInMillis = SystemProperties.getLong( - TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); - postDelayed(mExitEcmRunnable, delayInMillis); - // We don't want to go to sleep while in Ecm - mWakeLock.acquire(); - } - } - - private void handleExitEmergencyCallbackMode(Message msg) { - AsyncResult ar = (AsyncResult)msg.obj; - if (DBG) { - Log.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , mIsPhoneInEcmState " - + ar.exception + mIsPhoneInEcmState); - } - // Remove pending exit Ecm runnable, if any - removeCallbacks(mExitEcmRunnable); - - if (mEcmExitRespRegistrant != null) { - mEcmExitRespRegistrant.notifyRegistrant(ar); - } - // if exiting ecm success - if (ar.exception == null) { - if (mIsPhoneInEcmState) { - mIsPhoneInEcmState = false; - setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - } - // send an Intent - sendEmergencyCallbackModeChange(); - // Re-initiate data connection - mDataConnectionTracker.setInternalDataEnabled(true); - } - } - - /** - * Handle to cancel or restart Ecm timer in emergency call back mode - * if action is CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled; - * otherwise, restart Ecm timer and notify apps the timer is restarted. - */ - void handleTimerInEmergencyCallbackMode(int action) { - switch(action) { - case CANCEL_ECM_TIMER: - removeCallbacks(mExitEcmRunnable); - mEcmTimerResetRegistrants.notifyResult(Boolean.TRUE); - break; - case RESTART_ECM_TIMER: - long delayInMillis = SystemProperties.getLong( - TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); - postDelayed(mExitEcmRunnable, delayInMillis); - mEcmTimerResetRegistrants.notifyResult(Boolean.FALSE); - break; - default: - Log.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action); - } - } - - /** - * Registration point for Ecm timer reset - * @param h handler to notify - * @param what User-defined message code - * @param obj placed in Message.obj - */ - public void registerForEcmTimerReset(Handler h, int what, Object obj) { - mEcmTimerResetRegistrants.addUnique(h, what, obj); - } - - public void unregisterForEcmTimerReset(Handler h) { - mEcmTimerResetRegistrants.remove(h); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - Message onComplete; - - switch(msg.what) { - case EVENT_RADIO_AVAILABLE: { - mCM.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE)); - - mCM.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE)); - } - break; - - case EVENT_GET_BASEBAND_VERSION_DONE:{ - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - if (DBG) Log.d(LOG_TAG, "Baseband version: " + ar.result); - setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result); - } - break; - - case EVENT_GET_DEVICE_IDENTITY_DONE:{ - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - String[] respId = (String[])ar.result; - mImei = respId[0]; - mImeiSv = respId[1]; - mEsn = respId[2]; - mMeid = respId[3]; - } - break; - - case EVENT_EMERGENCY_CALLBACK_MODE_ENTER:{ - handleEnterEmergencyCallbackMode(msg); - } - break; - - case EVENT_ICC_RECORD_EVENTS: - ar = (AsyncResult)msg.obj; - processIccRecordEvents((Integer)ar.result); - break; - - case EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE:{ - handleExitEmergencyCallbackMode(msg); - } - break; - - case EVENT_RUIM_RECORDS_LOADED:{ - Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received"); - updateCurrentCarrierInProvider(); - } - break; - - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:{ - 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"); - handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); - } - break; - - case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:{ - Log.d(LOG_TAG, "EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED"); - handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); - } - break; - - case EVENT_SSN:{ - Log.d(LOG_TAG, "Event EVENT_SSN Received"); - } - break; - - case EVENT_REGISTERED_TO_NETWORK:{ - Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received"); - } - break; - - case EVENT_NV_READY:{ - Log.d(LOG_TAG, "Event EVENT_NV_READY Received"); - prepareEri(); - } - break; - - case EVENT_SET_VM_NUMBER_DONE:{ - ar = (AsyncResult)msg.obj; - if (IccException.class.isInstance(ar.exception)) { - storeVoiceMailNumber(mVmNumber); - ar.exception = null; - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - } - break; - - default:{ - super.handleMessage(msg); - } - } - } - - private void processIccRecordEvents(int eventCode) { - switch (eventCode) { - case RuimRecords.EVENT_MWI: - notifyMessageWaitingIndicator(); - break; - - default: - Log.e(LOG_TAG,"Unknown icc records event code " + eventCode); - break; - } - } - - /** - * Handles the call to get the subscription source - * - * @param newSubscriptionSource holds the new CDMA subscription source value - */ - private void handleCdmaSubscriptionSource(int newSubscriptionSource) { - if (newSubscriptionSource != mCdmaSubscriptionSource) { - mCdmaSubscriptionSource = newSubscriptionSource; - if (newSubscriptionSource == CDMA_SUBSCRIPTION_NV) { - // NV is ready when subscription source is NV - sendMessage(obtainMessage(EVENT_NV_READY)); - } - } - } - - /** - * Retrieves the PhoneSubInfo of the CDMAPhone - */ - public PhoneSubInfo getPhoneSubInfo() { - return mSubInfo; - } - - /** - * Retrieves the IccSmsInterfaceManager of the CDMAPhone - */ - public IccSmsInterfaceManager getIccSmsInterfaceManager() { - return mRuimSmsInterfaceManager; - } - - /** - * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone - */ - public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager() { - return mRuimPhoneBookInterfaceManager; - } - - public void registerForEriFileLoaded(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mEriFileLoadedRegistrants.add(r); - } - - public void unregisterForEriFileLoaded(Handler h) { - mEriFileLoadedRegistrants.remove(h); - } - - // override for allowing access from other classes of this package - /** - * {@inheritDoc} - */ - public final void setSystemProperty(String property, String value) { - super.setSystemProperty(property, value); - } - - /** - * 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) { - Log.e(LOG_TAG, "[CDMAPhone] activateCellBroadcastSms() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - /** - * Query the current configuration of cdma cell broadcast SMS. - * - * @param response Callback message is empty on completion - */ - public void getCellBroadcastSmsConfig(Message response) { - Log.e(LOG_TAG, "[CDMAPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - /** - * Configure cdma cell broadcast SMS. - * - * @param response Callback message is empty on completion - */ - public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) { - Log.e(LOG_TAG, "[CDMAPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - /** - * Returns true if OTA Service Provisioning needs to be performed. - */ - @Override - public boolean needsOtaServiceProvisioning() { - return mSST.getOtasp() != ServiceStateTracker.OTASP_NOT_NEEDED; - } - - private static final String IS683A_FEATURE_CODE = "*228"; - private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4; - private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2; - private static final int IS683A_SYS_SEL_CODE_OFFSET = 4; - - private static final int IS683_CONST_800MHZ_A_BAND = 0; - private static final int IS683_CONST_800MHZ_B_BAND = 1; - private static final int IS683_CONST_1900MHZ_A_BLOCK = 2; - private static final int IS683_CONST_1900MHZ_B_BLOCK = 3; - private static final int IS683_CONST_1900MHZ_C_BLOCK = 4; - private static final int IS683_CONST_1900MHZ_D_BLOCK = 5; - private static final int IS683_CONST_1900MHZ_E_BLOCK = 6; - private static final int IS683_CONST_1900MHZ_F_BLOCK = 7; - private static final int INVALID_SYSTEM_SELECTION_CODE = -1; - - private static boolean isIs683OtaSpDialStr(String dialStr) { - int sysSelCodeInt; - boolean isOtaspDialString = false; - int dialStrLen = dialStr.length(); - - if (dialStrLen == IS683A_FEATURE_CODE_NUM_DIGITS) { - if (dialStr.equals(IS683A_FEATURE_CODE)) { - isOtaspDialString = true; - } - } else { - sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr); - switch (sysSelCodeInt) { - case IS683_CONST_800MHZ_A_BAND: - case IS683_CONST_800MHZ_B_BAND: - case IS683_CONST_1900MHZ_A_BLOCK: - case IS683_CONST_1900MHZ_B_BLOCK: - case IS683_CONST_1900MHZ_C_BLOCK: - case IS683_CONST_1900MHZ_D_BLOCK: - case IS683_CONST_1900MHZ_E_BLOCK: - case IS683_CONST_1900MHZ_F_BLOCK: - isOtaspDialString = true; - break; - default: - break; - } - } - return isOtaspDialString; - } - /** - * This function extracts the system selection code from the dial string. - */ - private static int extractSelCodeFromOtaSpNum(String dialStr) { - int dialStrLen = dialStr.length(); - int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE; - - if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE, - 0, IS683A_FEATURE_CODE_NUM_DIGITS)) && - (dialStrLen >= (IS683A_FEATURE_CODE_NUM_DIGITS + - IS683A_SYS_SEL_CODE_NUM_DIGITS))) { - // Since we checked the condition above, the system selection code - // extracted from dialStr will not cause any exception - sysSelCodeInt = Integer.parseInt ( - dialStr.substring (IS683A_FEATURE_CODE_NUM_DIGITS, - IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS)); - } - if (DBG) Log.d(LOG_TAG, "extractSelCodeFromOtaSpNum " + sysSelCodeInt); - return sysSelCodeInt; - } - - /** - * This function checks if the system selection code extracted from - * the dial string "sysSelCodeInt' is the system selection code specified - * in the carrier ota sp number schema "sch". - */ - private static boolean - checkOtaSpNumBasedOnSysSelCode (int sysSelCodeInt, String sch[]) { - boolean isOtaSpNum = false; - try { - // Get how many number of system selection code ranges - int selRc = Integer.parseInt((String)sch[1]); - for (int i = 0; i < selRc; i++) { - if (!TextUtils.isEmpty(sch[i+2]) && !TextUtils.isEmpty(sch[i+3])) { - int selMin = Integer.parseInt((String)sch[i+2]); - int selMax = Integer.parseInt((String)sch[i+3]); - // Check if the selection code extracted from the dial string falls - // within any of the range pairs specified in the schema. - if ((sysSelCodeInt >= selMin) && (sysSelCodeInt <= selMax)) { - isOtaSpNum = true; - break; - } - } - } - } catch (NumberFormatException ex) { - // If the carrier ota sp number schema is not correct, we still allow dial - // and only log the error: - Log.e(LOG_TAG, "checkOtaSpNumBasedOnSysSelCode, error", ex); - } - return isOtaSpNum; - } - - // Define the pattern/format for carrier specified OTASP number schema. - // It separates by comma and/or whitespace. - private static Pattern pOtaSpNumSchema = Pattern.compile("[,\\s]+"); - - /** - * The following function checks if a dial string is a carrier specified - * OTASP number or not by checking against the OTASP number schema stored - * in PROPERTY_OTASP_NUM_SCHEMA. - * - * Currently, there are 2 schemas for carriers to specify the OTASP number: - * 1) Use system selection code: - * The schema is: - * SELC,the # of code pairs,min1,max1,min2,max2,... - * e.g "SELC,3,10,20,30,40,60,70" indicates that there are 3 pairs of - * selection codes, and they are {10,20}, {30,40} and {60,70} respectively. - * - * 2) Use feature code: - * The schema is: - * "FC,length of feature code,feature code". - * e.g "FC,2,*2" indicates that the length of the feature code is 2, - * and the code itself is "*2". - */ - private boolean isCarrierOtaSpNum(String dialStr) { - boolean isOtaSpNum = false; - int sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr); - if (sysSelCodeInt == INVALID_SYSTEM_SELECTION_CODE) { - return isOtaSpNum; - } - // mCarrierOtaSpNumSchema is retrieved from PROPERTY_OTASP_NUM_SCHEMA: - if (!TextUtils.isEmpty(mCarrierOtaSpNumSchema)) { - Matcher m = pOtaSpNumSchema.matcher(mCarrierOtaSpNumSchema); - if (DBG) { - Log.d(LOG_TAG, "isCarrierOtaSpNum,schema" + mCarrierOtaSpNumSchema); - } - - if (m.find()) { - String sch[] = pOtaSpNumSchema.split(mCarrierOtaSpNumSchema); - // If carrier uses system selection code mechanism - if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("SELC")) { - if (sysSelCodeInt!=INVALID_SYSTEM_SELECTION_CODE) { - isOtaSpNum=checkOtaSpNumBasedOnSysSelCode(sysSelCodeInt,sch); - } else { - if (DBG) { - Log.d(LOG_TAG, "isCarrierOtaSpNum,sysSelCodeInt is invalid"); - } - } - } else if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("FC")) { - int fcLen = Integer.parseInt((String)sch[1]); - String fc = (String)sch[2]; - if (dialStr.regionMatches(0,fc,0,fcLen)) { - isOtaSpNum = true; - } else { - if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,not otasp number"); - } - } else { - if (DBG) { - Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema not supported" + sch[0]); - } - } - } else { - if (DBG) { - Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern not right" + - mCarrierOtaSpNumSchema); - } - } - } else { - if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern empty"); - } - return isOtaSpNum; - } - - /** - * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier - * OTASP dial string. - * - * @param dialStr the number to look up. - * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string - */ - @Override - public boolean isOtaSpNumber(String dialStr){ - boolean isOtaSpNum = false; - String dialableStr = PhoneNumberUtils.extractNetworkPortionAlt(dialStr); - if (dialableStr != null) { - isOtaSpNum = isIs683OtaSpDialStr(dialableStr); - if (isOtaSpNum == false) { - isOtaSpNum = isCarrierOtaSpNum(dialableStr); - } - } - if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum); - return isOtaSpNum; - } - - @Override - public int getCdmaEriIconIndex() { - return getServiceState().getCdmaEriIconIndex(); - } - - /** - * Returns the CDMA ERI icon mode, - * 0 - ON - * 1 - FLASHING - */ - @Override - public int getCdmaEriIconMode() { - return getServiceState().getCdmaEriIconMode(); - } - - /** - * Returns the CDMA ERI text, - */ - @Override - public String getCdmaEriText() { - int roamInd = getServiceState().getCdmaRoamingIndicator(); - int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator(); - return mEriManager.getCdmaEriText(roamInd, defRoamInd); - } - - /** - * Store the voicemail number in preferences - */ - private void storeVoiceMailNumber(String number) { - // Update the preference value of voicemail number - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_NUMBER_CDMA, number); - editor.apply(); - } - - /** - * Sets PROPERTY_ICC_OPERATOR_ISO_COUNTRY property - * - */ - private void setIsoCountryProperty(String operatorNumeric) { - if (TextUtils.isEmpty(operatorNumeric)) { - setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, ""); - } else { - String iso = ""; - try { - iso = MccTable.countryCodeForMcc(Integer.parseInt( - operatorNumeric.substring(0,3))); - } catch (NumberFormatException ex) { - Log.w(LOG_TAG, "countryCodeForMcc error" + ex); - } catch (StringIndexOutOfBoundsException ex) { - Log.w(LOG_TAG, "countryCodeForMcc error" + ex); - } - - setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso); - } - } - - /** - * Sets the "current" field in the telephony provider according to the - * build-time operator numeric property - * - * @return true for success; false otherwise. - */ - boolean updateCurrentCarrierInProvider(String operatorNumeric) { - if (!TextUtils.isEmpty(operatorNumeric)) { - try { - Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); - ContentValues map = new ContentValues(); - map.put(Telephony.Carriers.NUMERIC, operatorNumeric); - log("updateCurrentCarrierInProvider from system: numeric=" + operatorNumeric); - getContext().getContentResolver().insert(uri, map); - - // Updates MCC MNC device configuration information - MccTable.updateMccMncConfiguration(mContext, operatorNumeric); - - return true; - } catch (SQLException e) { - Log.e(LOG_TAG, "Can't store current operator", e); - } - } - return false; - } - - /** - * Sets the "current" field in the telephony provider according to the SIM's operator. - * Implemented in {@link CDMALTEPhone} for CDMA/LTE devices. - * - * @return true for success; false otherwise. - */ - boolean updateCurrentCarrierInProvider() { - return true; - } - - public void prepareEri() { - mEriManager.loadEriFile(); - if(mEriManager.isEriFileLoaded()) { - // when the ERI file is loaded - log("ERI read, notify registrants"); - mEriFileLoadedRegistrants.notifyRegistrants(); - } - } - - public boolean isEriFileLoaded() { - return mEriManager.isEriFileLoaded(); - } - - private void registerForRuimRecordEvents() { - mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null); - mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null); - } - - private void unregisterForRuimRecordEvents() { - mIccRecords.unregisterForRecordsEvents(this); - mIccRecords.unregisterForRecordsLoaded(this); - } - - protected void log(String s) { - if (DBG) - Log.d(LOG_TAG, "[CDMAPhone] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CDMAPhone extends:"); - super.dump(fd, pw, args); - pw.println(" mVmNumber=" + mVmNumber); - pw.println(" mCT=" + mCT); - pw.println(" mSST=" + mSST); - pw.println(" mCdmaSSM=" + mCdmaSSM); - pw.println(" mPendingMmis=" + mPendingMmis); - pw.println(" mRuimPhoneBookInterfaceManager=" + mRuimPhoneBookInterfaceManager); - pw.println(" mRuimSmsInterfaceManager=" + mRuimSmsInterfaceManager); - pw.println(" mCdmaSubscriptionSource=" + mCdmaSubscriptionSource); - pw.println(" mSubInfo=" + mSubInfo); - pw.println(" mEriManager=" + mEriManager); - pw.println(" mWakeLock=" + mWakeLock); - pw.println(" mIsPhoneInEcmState=" + mIsPhoneInEcmState); - if (VDBG) pw.println(" mImei=" + mImei); - if (VDBG) pw.println(" mImeiSv=" + mImeiSv); - if (VDBG) pw.println(" mEsn=" + mEsn); - if (VDBG) pw.println(" mMeid=" + mMeid); - pw.println(" mCarrierOtaSpNumSchema=" + mCarrierOtaSpNumSchema); - pw.println(" getCdmaEriIconIndex()=" + getCdmaEriIconIndex()); - pw.println(" getCdmaEriIconMode()=" + getCdmaEriIconMode()); - pw.println(" getCdmaEriText()=" + getCdmaEriText()); - pw.println(" isMinInfoReady()=" + isMinInfoReady()); - pw.println(" isCspPlmnEnabled()=" + isCspPlmnEnabled()); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java deleted file mode 100644 index ad6c23c74ae6..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java +++ /dev/null @@ -1,59 +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.cdma; - -/** - * CDMA Call fail causes covering all the possible failures that are - * needed to be distinguished by the UI. CDMA call failure reasons - * are derived from the possible call failure scenarios described - * in "CDMA IS2000 - Release A (C.S0005-A v6.0)" standard. - * - * {@hide} - * - */ -public interface CallFailCause { - static final int NORMAL_CLEARING = 16; - // Busy Tone - static final int USER_BUSY = 17; - - static final int NORMAL_UNSPECIFIED = 31; - - // Congestion Tone - static final int NO_CIRCUIT_AVAIL = 34; - - // others - static final int ACM_LIMIT_EXCEEDED = 68; - static final int CALL_BARRED = 240; - static final int FDN_BLOCKED = 241; - - static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; - static final int CDMA_DROP = 1001; - static final int CDMA_INTERCEPT = 1002; - static final int CDMA_REORDER = 1003; - static final int CDMA_SO_REJECT = 1004; - static final int CDMA_RETRY_ORDER = 1005; - static final int CDMA_ACCESS_FAILURE = 1006; - static final int CDMA_PREEMPTED = 1007; - - // For non-emergency number dialed while in emergency callback mode. - static final int CDMA_NOT_EMERGENCY = 1008; - - // Access Blocked by CDMA Network. - static final int CDMA_ACCESS_BLOCKED = 1009; - - static final int ERROR_UNSPECIFIED = 0xffff; -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java deleted file mode 100644 index 4ad61bb083b6..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java +++ /dev/null @@ -1,208 +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.cdma; - -import java.util.ArrayList; -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.DriverCall; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.Call.State; - -/** - * {@hide} - */ -public final class CdmaCall extends Call { - /*************************** Instance Variables **************************/ - - /*package*/ ArrayList connections = new ArrayList(); - /*package*/ State state = State.IDLE; - /*package*/ CdmaCallTracker owner; - - /***************************** Class Methods *****************************/ - - static State - stateFromDCState (DriverCall.State dcState) { - switch (dcState) { - case ACTIVE: return State.ACTIVE; - case HOLDING: return State.HOLDING; - case DIALING: return State.DIALING; - case ALERTING: return State.ALERTING; - case INCOMING: return State.INCOMING; - case WAITING: return State.WAITING; - default: throw new RuntimeException ("illegal call state:" + dcState); - } - } - - - /****************************** Constructors *****************************/ - /*package*/ - CdmaCall (CdmaCallTracker owner) { - this.owner = owner; - } - - public void dispose() { - } - - /************************** Overridden from Call *************************/ - public List - getConnections() { - // FIXME should return Collections.unmodifiableList(); - return connections; - } - - public State - getState() { - return state; - } - - public Phone - getPhone() { - return owner.phone; - } - - public boolean isMultiparty() { - return connections.size() > 1; - } - - /** Please note: if this is the foreground call and a - * background call exists, the background call will be resumed - * because an AT+CHLD=1 will be sent - */ - public void - hangup() throws CallStateException { - owner.hangup(this); - } - - public String - toString() { - return state.toString(); - } - - //***** Called from CdmaConnection - - /*package*/ void - attach(Connection conn, DriverCall dc) { - connections.add(conn); - - state = stateFromDCState (dc.state); - } - - /*package*/ void - attachFake(Connection conn, State state) { - connections.add(conn); - - this.state = state; - } - - /** - * Called by CdmaConnection when it has disconnected - */ - void - connectionDisconnected(CdmaConnection conn) { - if (state != State.DISCONNECTED) { - /* 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() - != State.DISCONNECTED - ) { - hasOnlyDisconnectedConnections = false; - break; - } - } - - if (hasOnlyDisconnectedConnections) { - state = State.DISCONNECTED; - } - } - } - - - /*package*/ void - detach(CdmaConnection conn) { - connections.remove(conn); - - if (connections.size() == 0) { - state = State.IDLE; - } - } - - /*package*/ boolean - update (CdmaConnection conn, DriverCall dc) { - State newState; - boolean changed = false; - - newState = stateFromDCState(dc.state); - - if (newState != state) { - state = newState; - changed = true; - } - - return changed; - } - - /** - * @return true if there's no space in this call for additional - * connections to be added via "conference" - */ - /*package*/ boolean - isFull() { - return connections.size() == CdmaCallTracker.MAX_CONNECTIONS_PER_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 - */ - void - onHangupLocal() { - for (int i = 0, s = connections.size(); i < s; i++) { - CdmaConnection cn = (CdmaConnection)connections.get(i); - - cn.onHangupLocal(); - } - state = State.DISCONNECTING; - } - - /** - * 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 deleted file mode 100644 index af92b08bf236..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ /dev/null @@ -1,1162 +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.cdma; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.util.Log; -import android.os.SystemProperties; - -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.CallTracker; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.DriverCall; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.TelephonyProperties; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - - -/** - * {@hide} - */ -public final class CdmaCallTracker extends CallTracker { - 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 = 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(); - RegistrantList callWaitingRegistrants = new RegistrantList(); - - - // connections dropped during last poll - ArrayList droppedDuringPoll - = new ArrayList(MAX_CONNECTIONS); - - 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; - boolean pendingCallInEcm=false; - boolean mIsInEmergencyCall = false; - CDMAPhone phone; - - boolean desiredMute = false; // false = mute off - - int pendingCallClirMode; - Phone.State state = Phone.State.IDLE; - - private boolean mIsEcmTimerCanceled = false; - -// boolean needsPoll; - - - - //***** Events - - //***** Constructors - CdmaCallTracker(CDMAPhone phone) { - this.phone = phone; - cm = phone.mCM; - cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); - cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null); - cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null); - cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null); - foregroundCall.setGeneric(false); - } - - public void dispose() { - cm.unregisterForCallStateChanged(this); - cm.unregisterForOn(this); - cm.unregisterForNotAvailable(this); - cm.unregisterForCallWaitingInfo(this); - for(CdmaConnection c : connections) { - try { - if(c != null) hangup(c); - } 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(); - - } - - @Override - protected void finalize() { - Log.d(LOG_TAG, "CdmaCallTracker finalized"); - } - - //***** Instance Methods - - //***** Public Methods - public void registerForVoiceCallStarted(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - voiceCallStartedRegistrants.add(r); - // Notify if in call when registering - if (state != Phone.State.IDLE) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - 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); - } - - public void registerForCallWaiting(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - callWaitingRegistrants.add(r); - } - - public void unregisterForCallWaiting(Handler h) { - callWaitingRegistrants.remove(h); - } - - private void - fakeHoldForegroundBeforeDial() { - List connCopy; - - // We need to make a copy here, since fakeHoldBeforeDial() - // modifies the lists, and we don't want to reverse the order - connCopy = (List) foregroundCall.connections.clone(); - - for (int i = 0, s = connCopy.size() ; i < s ; i++) { - CdmaConnection conn = (CdmaConnection)connCopy.get(i); - - conn.fakeHoldBeforeDial(); - } - } - - /** - * clirMode is one of the CLIR_ constants - */ - Connection - dial (String dialString, int clirMode) throws CallStateException { - // note that this triggers call state changed notif - clearDisconnected(); - - if (!canDial()) { - throw new CallStateException("cannot dial in current state"); - } - - String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - boolean isPhoneInEcmMode = inEcm.equals("true"); - boolean isEmergencyCall = - PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext()); - - // Cancel Ecm timer if a second emergency call is originating in Ecm mode - if (isPhoneInEcmMode && isEmergencyCall) { - handleEcmTimer(phone.CANCEL_ECM_TIMER); - } - - // We are initiating a call therefore even if we previously - // didn't know the state (i.e. Generic was true) we now know - // and therefore can set Generic to false. - foregroundCall.setGeneric(false); - - // The new call must be assigned to the foreground call. - // That call must be idle, so place anything that's - // there on hold - if (foregroundCall.getState() == CdmaCall.State.ACTIVE) { - return dialThreeWay(dialString); - } - - pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), - this, foregroundCall); - hangupPendingMO = false; - - if (pendingMO.address == null || pendingMO.address.length() == 0 - || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) { - // Phone number is invalid - pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER; - - // handlePollCalls() will notice this call not present - // and will mark it as dropped. - pollCallsWhenSafe(); - } else { - // Always unmute when initiating a new call - setMute(false); - - // Check data call - disableDataCallInEmergencyCall(dialString); - - // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit. - if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) { - cm.dial(pendingMO.address, clirMode, obtainCompleteMessage()); - } else { - phone.exitEmergencyCallbackMode(); - phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null); - pendingCallClirMode=clirMode; - pendingCallInEcm=true; - } - } - - updatePhoneState(); - phone.notifyPreciseCallStateChanged(); - - return pendingMO; - } - - - Connection - dial (String dialString) throws CallStateException { - return dial(dialString, CommandsInterface.CLIR_DEFAULT); - } - - private Connection - dialThreeWay (String dialString) { - if (!foregroundCall.isIdle()) { - // Check data call - disableDataCallInEmergencyCall(dialString); - - // Attach the new connection to foregroundCall - pendingMO = new CdmaConnection(phone.getContext(), - checkForTestEmergencyNumber(dialString), this, foregroundCall); - cm.sendCDMAFeatureCode(pendingMO.address, - obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA)); - return pendingMO; - } - return null; - } - - void - acceptCall() throws CallStateException { - if (ringingCall.getState() == CdmaCall.State.INCOMING) { - Log.i("phone", "acceptCall: incoming..."); - // Always unmute when answering a new call - setMute(false); - cm.acceptCall(obtainCompleteMessage()); - } else if (ringingCall.getState() == CdmaCall.State.WAITING) { - CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection()); - - // Since there is no network response for supplimentary - // service for CDMA, we assume call waiting is answered. - // ringing Call state change to idle is in CdmaCall.detach - // triggered by updateParent. - cwConn.updateParent(ringingCall, foregroundCall); - cwConn.onConnectedInOrOut(); - updatePhoneState(); - switchWaitingOrHoldingAndActive(); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - rejectCall () throws CallStateException { - // AT+CHLD=0 means "release held or UDUB" - // so if the phone isn't ringing, this could hang up held - if (ringingCall.getState().isRinging()) { - cm.rejectCall(obtainCompleteMessage()); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - switchWaitingOrHoldingAndActive() throws CallStateException { - // Should we bother with this check? - if (ringingCall.getState() == CdmaCall.State.INCOMING) { - throw new CallStateException("cannot be in the incoming state"); - } else if (foregroundCall.getConnections().size() > 1) { - flashAndSetGenericTrue(); - } else { - // Send a flash command to CDMA network for putting the other party on hold. - // For CDMA networks which do not support this the user would just hear a beep - // from the network. For CDMA networks which do support it will put the other - // party on hold. - cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT)); - } - } - - void - conference() throws CallStateException { - // Should we be checking state? - flashAndSetGenericTrue(); - } - - void - explicitCallTransfer() throws CallStateException { - cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); - } - - void - clearDisconnected() { - internalClearDisconnected(); - - updatePhoneState(); - phone.notifyPreciseCallStateChanged(); - } - - boolean - canConference() { - return foregroundCall.getState() == CdmaCall.State.ACTIVE - && backgroundCall.getState() == CdmaCall.State.HOLDING - && !backgroundCall.isFull() - && !foregroundCall.isFull(); - } - - boolean - canDial() { - boolean ret; - int serviceState = phone.getServiceState().getState(); - String disableCall = SystemProperties.get( - TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); - - ret = (serviceState != ServiceState.STATE_POWER_OFF) - && pendingMO == null - && !ringingCall.isRinging() - && !disableCall.equals("true") - && (!foregroundCall.getState().isAlive() - || (foregroundCall.getState() == CdmaCall.State.ACTIVE) - || !backgroundCall.getState().isAlive()); - - if (!ret) { - log(String.format("canDial is false\n" + - "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" + - "&& pendingMO == null::=%s\n" + - "&& !ringingCall.isRinging()::=%s\n" + - "&& !disableCall.equals(\"true\")::=%s\n" + - "&& (!foregroundCall.getState().isAlive()::=%s\n" + - " || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" + - " ||!backgroundCall.getState().isAlive())::=%s)", - serviceState, - serviceState != ServiceState.STATE_POWER_OFF, - pendingMO == null, - !ringingCall.isRinging(), - !disableCall.equals("true"), - !foregroundCall.getState().isAlive(), - foregroundCall.getState() == CdmaCall.State.ACTIVE, - !backgroundCall.getState().isAlive())); - } - return ret; - } - - boolean - canTransfer() { - Log.e(LOG_TAG, "canTransfer: not possible in CDMA"); - return false; - } - - //***** Private Instance Methods - - private void - internalClearDisconnected() { - ringingCall.clearDisconnected(); - foregroundCall.clearDisconnected(); - backgroundCall.clearDisconnected(); - } - - /** - * Obtain a message to use for signalling "invoke getCurrentCalls() when - * this operation and all other pending operations are complete - */ - private Message - 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 - */ - private Message - obtainCompleteMessage(int what) { - pendingOperations++; - lastRelevantPoll = null; - needsPoll = true; - - if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + - pendingOperations + ", needsPoll=" + needsPoll); - - return obtainMessage(what); - } - - 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); - } 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 || - !(foregroundCall.isIdle() && backgroundCall.isIdle())) { - state = Phone.State.OFFHOOK; - } else { - state = Phone.State.IDLE; - } - - if (state == Phone.State.IDLE && oldState != state) { - voiceCallEndedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - } else if (oldState == Phone.State.IDLE && oldState != state) { - voiceCallStartedRegistrants.notifyRegistrants ( - new AsyncResult(null, null, null)); - } - if (Phone.DEBUG_PHONE) { - log("update phone state, old=" + oldState + " new="+ state); - } - if (state != oldState) { - 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)) { - // just a dummy empty ArrayList to cause the loop - // to hang up all the calls - polledCalls = new ArrayList(); - } else { - // Radio probably wasn't ready--try again in a bit - // But don't keep polling if the channel is closed - pollCallsAfterDelay(); - return; - } - - Connection newRinging = null; //or waiting - boolean hasNonHangupStateChanged = false; // Any change besides - // a dropped connection - boolean needsPollDelay = false; - boolean unknownConnectionAppeared = false; - - for (int i = 0, curDC = 0, dcSize = polledCalls.size() - ; i < connections.length; i++) { - CdmaConnection conn = connections[i]; - DriverCall dc = null; - - // polledCall list is sparse - if (curDC < dcSize) { - dc = (DriverCall) polledCalls.get(curDC); - - if (dc.index == i+1) { - curDC++; - } else { - dc = null; - } - } - - if (DBG_POLL) log("poll: conn[i=" + i + "]=" + - conn+", dc=" + dc); - - if (conn == null && dc != null) { - // Connection appeared in CLCC response that we don't know about - if (pendingMO != null && pendingMO.compareTo(dc)) { - - if (DBG_POLL) log("poll: pendingMO=" + pendingMO); - - // It's our pending mobile originating call - connections[i] = pendingMO; - pendingMO.index = i; - pendingMO.update(dc); - pendingMO = null; - - // Someone has already asked to hangup this call - if (hangupPendingMO) { - hangupPendingMO = false; - // Re-start Ecm timer when an uncompleted emergency call ends - if (mIsEcmTimerCanceled) { - handleEcmTimer(phone.RESTART_ECM_TIMER); - } - - try { - if (Phone.DEBUG_PHONE) log( - "poll: hangupPendingMO, hangup conn " + i); - hangup(connections[i]); - } catch (CallStateException ex) { - Log.e(LOG_TAG, "unexpected error on hangup"); - } - - // Do not continue processing this poll - // Wait for hangup and repoll - return; - } - } else { - if (Phone.DEBUG_PHONE) { - log("pendingMo=" + pendingMO + ", dc=" + dc); - } - // find if the MT call is a new ring or unknown connection - newRinging = checkMtFindNewRinging(dc,i); - if (newRinging == null) { - unknownConnectionAppeared = true; - } - checkAndEnableDataCallAfterEmergencyCallDropped(); - } - hasNonHangupStateChanged = true; - } else if (conn != null && dc == null) { - // This case means the RIL has no more active call anymore and - // we need to clean up the foregroundCall and ringingCall. - // Loop through foreground call connections as - // it contains the known logical connections. - int count = foregroundCall.connections.size(); - for (int n = 0; n < count; n++) { - if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll"); - CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n); - droppedDuringPoll.add(cn); - } - count = ringingCall.connections.size(); - // Loop through ringing call connections as - // it may contain the known logical connections. - for (int n = 0; n < count; n++) { - if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll"); - CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n); - droppedDuringPoll.add(cn); - } - foregroundCall.setGeneric(false); - ringingCall.setGeneric(false); - - // Re-start Ecm timer when the connected emergency call ends - if (mIsEcmTimerCanceled) { - handleEcmTimer(phone.RESTART_ECM_TIMER); - } - // If emergency call is not going through while dialing - checkAndEnableDataCallAfterEmergencyCallDropped(); - - // Dropped connections are removed from the CallTracker - // list but kept in the Call list - connections[i] = null; - } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */ - // Call collision case - if (conn.isIncoming != dc.isMT) { - if (dc.isMT == true){ - // Mt call takes precedence than Mo,drops Mo - droppedDuringPoll.add(conn); - // find if the MT call is a new ring or unknown connection - newRinging = checkMtFindNewRinging(dc,i); - if (newRinging == null) { - unknownConnectionAppeared = true; - } - checkAndEnableDataCallAfterEmergencyCallDropped(); - } else { - // Call info stored in conn is not consistent with the call info from dc. - // We should follow the rule of MT calls taking precedence over MO calls - // when there is conflict, so here we drop the call info from dc and - // continue to use the call info from conn, and only take a log. - Log.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc); - } - } else { - boolean changed; - changed = conn.update(dc); - hasNonHangupStateChanged = hasNonHangupStateChanged || changed; - } - } - - if (REPEAT_POLLING) { - if (dc != null) { - // FIXME with RIL, we should not need this anymore - if ((dc.state == DriverCall.State.DIALING - /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/) - || (dc.state == DriverCall.State.ALERTING - /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/) - || (dc.state == DriverCall.State.INCOMING - /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/) - || (dc.state == DriverCall.State.WAITING - /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/) - ) { - // Sometimes there's no unsolicited notification - // for state transitions - needsPollDelay = true; - } - } - } - } - - // 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:" - + foregroundCall.getState()); - - droppedDuringPoll.add(pendingMO); - pendingMO = null; - hangupPendingMO = false; - if( pendingCallInEcm) { - pendingCallInEcm = false; - } - } - - if (newRinging != null) { - phone.notifyNewRingingConnection(newRinging); - } - - // clear the "local hangup" and "missed/rejected call" - // cases from the "dropped during poll" list - // These cases need no "last call fail" reason - for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) { - CdmaConnection conn = droppedDuringPoll.get(i); - - if (conn.isIncoming() && conn.getConnectTime() == 0) { - // Missed or rejected call - Connection.DisconnectCause cause; - if (conn.cause == Connection.DisconnectCause.LOCAL) { - cause = Connection.DisconnectCause.INCOMING_REJECTED; - } else { - cause = Connection.DisconnectCause.INCOMING_MISSED; - } - - if (Phone.DEBUG_PHONE) { - log("missed/rejected call, conn.cause=" + conn.cause); - log("setting cause to " + cause); - } - droppedDuringPoll.remove(i); - conn.onDisconnect(cause); - } else if (conn.cause == Connection.DisconnectCause.LOCAL) { - // Local hangup - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.LOCAL); - } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) { - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); - } - } - - // Any non-local disconnects: determine cause - if (droppedDuringPoll.size() > 0) { - cm.getLastCallFailCause( - obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE)); - } - - if (needsPollDelay) { - pollCallsAfterDelay(); - } - - // Cases when we can no longer keep disconnected Connection's - // with their previous calls - // 1) the phone has started to ring - // 2) A Call/Connection object has changed state... - // we may have switched or held or answered (but not hung up) - if (newRinging != null || hasNonHangupStateChanged) { - internalClearDisconnected(); - } - - updatePhoneState(); - - if (unknownConnectionAppeared) { - phone.notifyUnknownConnection(); - } - - if (hasNonHangupStateChanged || newRinging != null) { - phone.notifyPreciseCallStateChanged(); - } - - //dumpState(); - } - - //***** Called from CdmaConnection - /*package*/ void - hangup (CdmaConnection conn) throws CallStateException { - if (conn.owner != this) { - throw new CallStateException ("CdmaConnection " + conn - + "does not belong to CdmaCallTracker " + this); - } - - if (conn == pendingMO) { - // We're hanging up an outgoing call that doesn't have it's - // GSM index assigned yet - - if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); - hangupPendingMO = true; - } else if ((conn.getCall() == ringingCall) - && (ringingCall.getState() == CdmaCall.State.WAITING)) { - // Handle call waiting hang up case. - // - // The ringingCall state will change to IDLE in CdmaCall.detach - // if the ringing call connection size is 0. We don't specifically - // set the ringing call state to IDLE here to avoid a race condition - // where a new call waiting could get a hang up from an old call - // waiting ringingCall. - // - // PhoneApp does the call log itself since only PhoneApp knows - // the hangup reason is user ignoring or timing out. So conn.onDisconnect() - // is not called here. Instead, conn.onLocalDisconnect() is called. - conn.onLocalDisconnect(); - updatePhoneState(); - phone.notifyPreciseCallStateChanged(); - return; - } else { - 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 " - + conn); - } - } - - conn.onHangupLocal(); - } - - /*package*/ void - separate (CdmaConnection conn) throws CallStateException { - if (conn.owner != this) { - throw new CallStateException ("CdmaConnection " + conn - + "does not belong to CdmaCallTracker " + this); - } - try { - 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 " - + conn); - } - } - - //***** Called from CDMAPhone - - /*package*/ void - setMute(boolean mute) { - desiredMute = mute; - cm.setMute(desiredMute, null); - } - - /*package*/ boolean - getMute() { - return desiredMute; - } - - - //***** Called from CdmaCall - - /* package */ void - hangup (CdmaCall call) throws CallStateException { - if (call.getConnections().size() == 0) { - throw new CallStateException("no connections in call"); - } - - if (call == ringingCall) { - if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } else if (call == foregroundCall) { - if (call.isDialingOrAlerting()) { - if (Phone.DEBUG_PHONE) { - log("(foregnd) hangup dialing or alerting..."); - } - hangup((CdmaConnection)(call.getConnections().get(0))); - } else { - hangupForegroundResumeBackground(); - } - } else if (call == backgroundCall) { - if (ringingCall.isRinging()) { - if (Phone.DEBUG_PHONE) { - log("hangup all conns in background call"); - } - hangupAllConnections(call); - } else { - hangupWaitingOrBackground(); - } - } else { - throw new RuntimeException ("CdmaCall " + call + - "does not belong to CdmaCallTracker " + this); - } - - call.onHangupLocal(); - phone.notifyPreciseCallStateChanged(); - } - - /* package */ - void hangupWaitingOrBackground() { - if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } - - /* package */ - void hangupForegroundResumeBackground() { - if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground"); - cm.hangupForegroundResumeBackground(obtainCompleteMessage()); - } - - void hangupConnectionByIndex(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.getCDMAIndex() == index) { - cm.hangupConnection(index, obtainCompleteMessage()); - return; - } - } - - throw new CallStateException("no gsm index found"); - } - - void hangupAllConnections(CdmaCall call) throws CallStateException{ - try { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - CdmaConnection cn = (CdmaConnection)call.connections.get(i); - 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.getCDMAIndex() == index) { - return cn; - } - } - - return null; - } - - private void flashAndSetGenericTrue() throws CallStateException { - cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT)); - - // Set generic to true because in CDMA it is not known what - // the status of the call is after a call waiting is answered, - // 3 way call merged or a switch between calls. - foregroundCall.setGeneric(true); - phone.notifyPreciseCallStateChanged(); - } - - private Phone.SuppService getFailedService(int what) { - switch (what) { - case EVENT_SWITCH_RESULT: - return Phone.SuppService.SWITCH; - case EVENT_CONFERENCE_RESULT: - return Phone.SuppService.CONFERENCE; - case EVENT_SEPARATE_RESULT: - return Phone.SuppService.SEPARATE; - case EVENT_ECT_RESULT: - return Phone.SuppService.TRANSFER; - } - return Phone.SuppService.UNKNOWN; - } - - private void handleRadioNotAvailable() { - // handlePollCalls will clear out its - // call list when it gets the CommandException - // error result from this - pollCallsWhenSafe(); - } - - private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) { - if (callWaitingRegistrants != null) { - callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null)); - } - } - - private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) { - // Check how many connections in foregroundCall. - // If the connection in foregroundCall is more - // than one, then the connection information is - // not reliable anymore since it means either - // call waiting is connected or 3 way call is - // dialed before, so set generic. - if (foregroundCall.connections.size() > 1 ) { - foregroundCall.setGeneric(true); - } - - // Create a new CdmaConnection which attaches itself to ringingCall. - ringingCall.setGeneric(false); - new CdmaConnection(phone.getContext(), cw, this, ringingCall); - updatePhoneState(); - - // Finally notify application - notifyCallWaitingInfo(cw); - } - //****** Overridden from Handler - - public void - handleMessage (Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_POLL_CALLS_RESULT:{ - Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); - ar = (AsyncResult)msg.obj; - - if(msg == lastRelevantPoll) { - if(DBG_POLL) log( - "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); - needsPoll = false; - lastRelevantPoll = null; - handlePollCalls((AsyncResult)msg.obj); - } - } - break; - - case EVENT_OPERATION_COMPLETE: - operationComplete(); - break; - - case EVENT_SWITCH_RESULT: - // In GSM call operationComplete() here which gets the - // current call list. But in CDMA there is no list so - // there is nothing to do. - break; - - case EVENT_GET_LAST_CALL_FAIL_CAUSE: - int causeCode; - ar = (AsyncResult)msg.obj; - - operationComplete(); - - if (ar.exception != null) { - // An exception occurred...just treat the disconnect - // cause as "normal" - causeCode = CallFailCause.NORMAL_CLEARING; - Log.i(LOG_TAG, - "Exception during getLastCallFailCause, assuming normal disconnect"); - } else { - causeCode = ((int[])ar.result)[0]; - } - - for (int i = 0, s = droppedDuringPoll.size() - ; i < s ; i++ - ) { - CdmaConnection conn = droppedDuringPoll.get(i); - - conn.onRemoteDisconnect(causeCode); - } - - updatePhoneState(); - - phone.notifyPreciseCallStateChanged(); - droppedDuringPoll.clear(); - break; - - case EVENT_REPOLL_AFTER_DELAY: - case EVENT_CALL_STATE_CHANGE: - pollCallsWhenSafe(); - break; - - case EVENT_RADIO_AVAILABLE: - handleRadioAvailable(); - break; - - case EVENT_RADIO_NOT_AVAILABLE: - handleRadioNotAvailable(); - break; - - case EVENT_EXIT_ECM_RESPONSE_CDMA: - //no matter the result, we still do the same here - if (pendingCallInEcm) { - cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage()); - pendingCallInEcm = false; - } - phone.unsetOnEcbModeExitResponse(this); - break; - - case EVENT_CALL_WAITING_INFO_CDMA: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result); - Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received"); - } - break; - - case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - // Assume 3 way call is connected - pendingMO.onConnectedInOrOut(); - pendingMO = null; - } - break; - - default:{ - throw new RuntimeException("unexpected event not handled"); - } - } - } - - /** - * Handle Ecm timer to be canceled or re-started - */ - private void handleEcmTimer(int action) { - phone.handleTimerInEmergencyCallbackMode(action); - switch(action) { - case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break; - case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break; - default: - Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action); - } - } - - /** - * Disable data call when emergency call is connected - */ - private void disableDataCallInEmergencyCall(String dialString) { - if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) { - if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall"); - mIsInEmergencyCall = true; - phone.mDataConnectionTracker.setInternalDataEnabled(false); - } - } - - /** - * Check and enable data call after an emergency call is dropped if it's - * not in ECM - */ - private void checkAndEnableDataCallAfterEmergencyCallDropped() { - if (mIsInEmergencyCall) { - mIsInEmergencyCall = false; - String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - if (Phone.DEBUG_PHONE) { - log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm); - } - if (inEcm.compareTo("false") == 0) { - // Re-initiate data connection - phone.mDataConnectionTracker.setInternalDataEnabled(true); - } - } - } - - /** - * Check the MT call to see if it's a new ring or - * a unknown connection. - */ - private Connection checkMtFindNewRinging(DriverCall dc, int i) { - - Connection newRinging = null; - - connections[i] = new CdmaConnection(phone.getContext(), dc, this, i); - // it's a ringing call - if (connections[i].getCall() == ringingCall) { - newRinging = connections[i]; - if (Phone.DEBUG_PHONE) log("Notify new ring " + dc); - } else { - // Something strange happened: a call which is neither - // a ringing call nor the one we created. It could be the - // call collision result from RIL - Log.e(LOG_TAG,"Phantom call appeared " + dc); - // If it's a connected call, set the connect time so that - // it's non-zero. It may not be accurate, but at least - // it won't appear as a Missed Call. - if (dc.state != DriverCall.State.ALERTING - && dc.state != DriverCall.State.DIALING) { - connections[i].connectTime = System.currentTimeMillis(); - } - } - return newRinging; - } - - /** - * Check if current call is in emergency call - * - * @return true if it is in emergency call - * false if it is not in emergency call - */ - boolean isInEmergencyCall() { - return mIsInEmergencyCall; - } - - protected void log(String msg) { - Log.d(LOG_TAG, "[CdmaCallTracker] " + msg); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("GsmCallTracker extends:"); - super.dump(fd, pw, args); - pw.println("droppedDuringPoll: length=" + connections.length); - for(int i=0; i < connections.length; i++) { - pw.printf(" connections[%d]=%s\n", i, connections[i]); - } - pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants); - pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants); - pw.println(" callWaitingRegistrants=" + callWaitingRegistrants); - pw.println("droppedDuringPoll: size=" + droppedDuringPoll.size()); - for(int i = 0; i < droppedDuringPoll.size(); i++) { - pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i)); - } - pw.println(" ringingCall=" + ringingCall); - pw.println(" foregroundCall=" + foregroundCall); - pw.println(" backgroundCall=" + backgroundCall); - pw.println(" pendingMO=" + pendingMO); - pw.println(" hangupPendingMO=" + hangupPendingMO); - pw.println(" pendingCallInEcm=" + pendingCallInEcm); - pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall); - pw.println(" phone=" + phone); - pw.println(" desiredMute=" + desiredMute); - pw.println(" pendingCallClirMode=" + pendingCallClirMode); - pw.println(" state=" + state); - pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java deleted file mode 100644 index 81ff0425dc69..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; - -import android.util.Log; -import com.android.internal.telephony.Connection; - -/** - * Represents a Supplementary Service Notification received from the network. - * - * {@hide} - */ -public class CdmaCallWaitingNotification { - static final String LOG_TAG = "CDMA"; - public String number = null; - public int numberPresentation = 0; - public String name = null; - public int namePresentation = 0; - public int numberType = 0; - public int numberPlan = 0; - public int isPresent = 0; - public int signalType = 0; - public int alertPitch = 0; - public int signal = 0; - - public String toString() - { - return super.toString() + "Call Waiting Notification " - + " number: " + number - + " numberPresentation: " + numberPresentation - + " name: " + name - + " namePresentation: " + namePresentation - + " numberType: " + numberType - + " numberPlan: " + numberPlan - + " isPresent: " + isPresent - + " signalType: " + signalType - + " alertPitch: " + alertPitch - + " signal: " + signal ; - } - - public static int - presentationFromCLIP(int cli) - { - switch(cli) { - case 0: return Connection.PRESENTATION_ALLOWED; - case 1: return Connection.PRESENTATION_RESTRICTED; - case 2: return Connection.PRESENTATION_UNKNOWN; - default: - // This shouldn't happen, just log an error and treat as Unknown - Log.d(LOG_TAG, "Unexpected presentation " + cli); - return Connection.PRESENTATION_UNKNOWN; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java deleted file mode 100755 index 6985979c9b02..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java +++ /dev/null @@ -1,945 +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.cdma; - -import com.android.internal.telephony.*; -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.util.Log; -import android.text.TextUtils; - -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.RILConstants; - -/** - * {@hide} - */ -public class CdmaConnection extends Connection { - static final String LOG_TAG = "CDMA"; - - //***** Instance Variables - - CdmaCallTracker owner; - CdmaCall parent; - - - String address; // MAY BE NULL!!! - String dialString; // outgoing calls only - String postDialString; // outgoing calls only - boolean isIncoming; - boolean disconnected; - int index; // index in CdmaCallTracker.connections[], -1 if unassigned - - /* - * These time/timespan values are based on System.currentTimeMillis(), - * i.e., "wall clock" time. - */ - long createTime; - long connectTime; - long disconnectTime; - - /* - * These time/timespan values are based on SystemClock.elapsedRealTime(), - * i.e., time since boot. They are appropriate for comparison and - * calculating deltas. - */ - long connectTimeReal; - long duration; - 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; - int numberPresentation = Connection.PRESENTATION_ALLOWED; - - - Handler h; - - private PowerManager.WakeLock mPartialWakeLock; - - //***** Event Constants - static final int EVENT_DTMF_DONE = 1; - static final int EVENT_PAUSE_DONE = 2; - static final int EVENT_NEXT_POST_DIAL = 3; - static final int EVENT_WAKE_LOCK_TIMEOUT = 4; - - //***** Constants - static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000; - static final int PAUSE_DELAY_MILLIS = 2 * 1000; - - //***** Inner Classes - - class MyHandler extends Handler { - MyHandler(Looper l) {super(l);} - - public void - handleMessage(Message msg) { - - switch (msg.what) { - case EVENT_NEXT_POST_DIAL: - case EVENT_DTMF_DONE: - case EVENT_PAUSE_DONE: - processNextPostDialChar(); - break; - case EVENT_WAKE_LOCK_TIMEOUT: - releaseWakeLock(); - break; - } - } - } - - //***** Constructors - - /** This is probably an MT call that we first saw in a CLCC response */ - /*package*/ - CdmaConnection (Context context, DriverCall dc, CdmaCallTracker ct, int index) { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - address = dc.number; - - isIncoming = dc.isMT; - createTime = System.currentTimeMillis(); - cnapName = dc.name; - cnapNamePresentation = dc.namePresentation; - numberPresentation = dc.numberPresentation; - - this.index = index; - - parent = parentFromDCState (dc.state); - parent.attach(this, dc); - } - - /** This is an MO call/three way call, created when dialing */ - /*package*/ - CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - this.dialString = dialString; - Log.d(LOG_TAG, "[CDMAConn] CdmaConnection: dialString=" + dialString); - dialString = formatDialString(dialString); - Log.d(LOG_TAG, "[CDMAConn] CdmaConnection:formated dialString=" + dialString); - - this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString); - this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString); - - index = -1; - - isIncoming = false; - cnapName = null; - cnapNamePresentation = Connection.PRESENTATION_ALLOWED; - numberPresentation = Connection.PRESENTATION_ALLOWED; - createTime = System.currentTimeMillis(); - - if (parent != null) { - this.parent = parent; - - //for the three way call case, not change parent state - if (parent.state == CdmaCall.State.ACTIVE) { - parent.attachFake(this, CdmaCall.State.ACTIVE); - } else { - parent.attachFake(this, CdmaCall.State.DIALING); - } - } - } - - /** This is a Call waiting call*/ - CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct, - CdmaCall parent) { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - address = cw.number; - numberPresentation = cw.numberPresentation; - cnapName = cw.name; - cnapNamePresentation = cw.namePresentation; - index = -1; - isIncoming = true; - createTime = System.currentTimeMillis(); - connectTime = 0; - this.parent = parent; - parent.attachFake(this, CdmaCall.State.WAITING); - } - - public void dispose() { - } - - static boolean - equalsHandlesNulls (Object a, Object b) { - return (a == null) ? (b == null) : a.equals (b); - } - - /*package*/ boolean - compareTo(DriverCall c) { - // On mobile originated (MO) calls, the phone number may have changed - // due to a SIM Toolkit call control modification. - // - // We assume we know when MO calls are created (since we created them) - // and therefore don't need to compare the phone number anyway. - if (! (isIncoming || c.isMT)) return true; - - // ... but we can compare phone numbers on MT calls, and we have - // 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); - } - - - public String getOrigDialString(){ - return dialString; - } - - public String getAddress() { - return address; - } - - public CdmaCall getCall() { - return parent; - } - - public long getCreateTime() { - return createTime; - } - - public long getConnectTime() { - return connectTime; - } - - public long getDisconnectTime() { - return disconnectTime; - } - - public long getDurationMillis() { - if (connectTimeReal == 0) { - return 0; - } else if (duration == 0) { - return SystemClock.elapsedRealtime() - connectTimeReal; - } else { - return duration; - } - } - - public long getHoldDurationMillis() { - if (getState() != CdmaCall.State.HOLDING) { - // If not holding, return 0 - return 0; - } else { - return SystemClock.elapsedRealtime() - holdingStartTime; - } - } - - public DisconnectCause getDisconnectCause() { - return cause; - } - - public boolean isIncoming() { - return isIncoming; - } - - public CdmaCall.State getState() { - if (disconnected) { - return CdmaCall.State.DISCONNECTED; - } else { - return super.getState(); - } - } - - public void hangup() throws CallStateException { - if (!disconnected) { - owner.hangup(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public void separate() throws CallStateException { - if (!disconnected) { - owner.separate(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public PostDialState getPostDialState() { - return postDialState; - } - - public void proceedAfterWaitChar() { - if (postDialState != PostDialState.WAIT) { - Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WAIT but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - processNextPostDialChar(); - } - - public void proceedAfterWildChar(String str) { - if (postDialState != PostDialState.WILD) { - Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WILD but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - if (false) { - boolean playedTone = false; - int len = (str != null ? str.length() : 0); - - for (int i=0; i 0 && (wIndex < pIndex || pIndex <= 0)) { - subStr = subStr.substring(0, wIndex); - } else if (pIndex > 0) { - subStr = subStr.substring(0, pIndex); - } - } - return subStr; - } - - public void updateParent(CdmaCall oldParent, CdmaCall newParent){ - if (newParent != oldParent) { - if (oldParent != null) { - oldParent.detach(this); - } - newParent.attachFake(this, CdmaCall.State.ACTIVE); - parent = newParent; - } - } - - @Override - protected void finalize() - { - /** - * It is understood that This finializer is not guaranteed - * to be called and the release lock call is here just in - * case there is some path that doesn't call onDisconnect - * and or onConnectedInOrOut. - */ - if (mPartialWakeLock.isHeld()) { - Log.e(LOG_TAG, "[CdmaConn] UNEXPECTED; mPartialWakeLock is held when finalizing."); - } - releaseWakeLock(); - } - - void processNextPostDialChar() { - char c = 0; - Registrant postDialHandler; - - if (postDialState == PostDialState.CANCELLED) { - releaseWakeLock(); - //Log.v("CDMA", "##### processNextPostDialChar: postDialState == CANCELLED, bail"); - return; - } - - if (postDialString == null || - postDialString.length() <= nextPostDialChar) { - setPostDialState(PostDialState.COMPLETE); - - // We were holding a wake lock until pause-dial was complete, so give it up now - releaseWakeLock(); - - // notifyMessage.arg1 is 0 on complete - c = 0; - } else { - boolean isValid; - - setPostDialState(PostDialState.STARTED); - - c = postDialString.charAt(nextPostDialChar++); - - isValid = processPostDialChar(c); - - if (!isValid) { - // Will call processNextPostDialChar - h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget(); - // Don't notify application - Log.e("CDMA", "processNextPostDialChar: c=" + c + " isn't valid!"); - return; - } - } - - postDialHandler = owner.phone.mPostDialHandler; - - Message notifyMessage; - - if (postDialHandler != null && - (notifyMessage = postDialHandler.messageForRegistrant()) != null) { - // The AsyncResult.result is the Connection object - PostDialState state = postDialState; - AsyncResult ar = AsyncResult.forMessage(notifyMessage); - ar.result = this; - ar.userObj = state; - - // arg1 is the character that was/is being processed - notifyMessage.arg1 = c; - - notifyMessage.sendToTarget(); - } - } - - - /** "connecting" means "has never been ACTIVE" for both incoming - * and outgoing calls - */ - private boolean - isConnectingInOrOut() { - return parent == null || parent == owner.ringingCall - || parent.state == CdmaCall.State.DIALING - || parent.state == CdmaCall.State.ALERTING; - } - - private CdmaCall - parentFromDCState (DriverCall.State state) { - switch (state) { - case ACTIVE: - case DIALING: - case ALERTING: - return owner.foregroundCall; - //break; - - case HOLDING: - return owner.backgroundCall; - //break; - - case INCOMING: - case WAITING: - return owner.ringingCall; - //break; - - default: - throw new RuntimeException("illegal call state: " + state); - } - } - - /** - * Set post dial state and acquire wake lock while switching to "started" or "wait" - * state, the wake lock will be released if state switches out of "started" or "wait" - * state or after WAKE_LOCK_TIMEOUT_MILLIS. - * @param s new PostDialState - */ - private void setPostDialState(PostDialState s) { - if (s == PostDialState.STARTED || - s == PostDialState.PAUSE) { - synchronized (mPartialWakeLock) { - if (mPartialWakeLock.isHeld()) { - h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - } else { - acquireWakeLock(); - } - Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); - h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS); - } - } else { - h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - releaseWakeLock(); - } - postDialState = s; - } - - private void createWakeLock(Context context) { - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); - } - - private void acquireWakeLock() { - log("acquireWakeLock"); - mPartialWakeLock.acquire(); - } - - private void releaseWakeLock() { - synchronized (mPartialWakeLock) { - if (mPartialWakeLock.isHeld()) { - log("releaseWakeLock"); - mPartialWakeLock.release(); - } - } - } - - private static boolean isPause(char c) { - return c == PhoneNumberUtils.PAUSE; - } - - private static boolean isWait(char c) { - return c == PhoneNumberUtils.WAIT; - } - - // This function is to find the next PAUSE character index if - // multiple pauses in a row. Otherwise it finds the next non PAUSE or - // non WAIT character index. - private static int - findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) { - boolean wMatched = isWait(phoneNumber.charAt(currIndex)); - int index = currIndex + 1; - int length = phoneNumber.length(); - while (index < length) { - char cNext = phoneNumber.charAt(index); - // if there is any W inside P/W sequence,mark it - if (isWait(cNext)) { - wMatched = true; - } - // if any characters other than P/W chars after P/W sequence - // we break out the loop and append the correct - if (!isWait(cNext) && !isPause(cNext)) { - break; - } - index++; - } - - // It means the PAUSE character(s) is in the middle of dial string - // and it needs to be handled one by one. - if ((index < length) && (index > (currIndex + 1)) && - ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) { - return (currIndex + 1); - } - return index; - } - - // This function returns either PAUSE or WAIT character to append. - // It is based on the next non PAUSE/WAIT character in the phoneNumber and the - // index for the current PAUSE/WAIT character - private static char - findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) { - char c = phoneNumber.charAt(currPwIndex); - char ret; - - // Append the PW char - ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT; - - // If the nextNonPwCharIndex is greater than currPwIndex + 1, - // it means the PW sequence contains not only P characters. - // Since for the sequence that only contains P character, - // the P character is handled one by one, the nextNonPwCharIndex - // equals to currPwIndex + 1. - // In this case, skip P, append W. - if (nextNonPwCharIndex > (currPwIndex + 1)) { - ret = PhoneNumberUtils.WAIT; - } - return ret; - } - - /** - * format original dial string - * 1) convert international dialing prefix "+" to - * string specified per region - * - * 2) handle corner cases for PAUSE/WAIT dialing: - * - * If PAUSE/WAIT sequence at the end, ignore them. - * - * If consecutive PAUSE/WAIT sequence in the middle of the string, - * and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT. - */ - public static String formatDialString(String phoneNumber) { - /** - * TODO(cleanup): This function should move to PhoneNumberUtils, and - * tests should be added. - */ - - if (phoneNumber == null) { - return null; - } - int length = phoneNumber.length(); - StringBuilder ret = new StringBuilder(); - char c; - int currIndex = 0; - - while (currIndex < length) { - c = phoneNumber.charAt(currIndex); - if (isPause(c) || isWait(c)) { - if (currIndex < length - 1) { - // if PW not at the end - int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex); - // If there is non PW char following PW sequence - if (nextIndex < length) { - char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex); - ret.append(pC); - // If PW char sequence has more than 2 PW characters, - // skip to the last PW character since the sequence already be - // converted to WAIT character - if (nextIndex > (currIndex + 1)) { - currIndex = nextIndex - 1; - } - } else if (nextIndex == length) { - // It means PW characters at the end, ignore - currIndex = length - 1; - } - } - } else { - ret.append(c); - } - currIndex++; - } - return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString()); - } - - private void log(String msg) { - Log.d(LOG_TAG, "[CDMAConn] " + msg); - } - - @Override - public int getNumberPresentation() { - return numberPresentation; - } - - @Override - public UUSInfo getUUSInfo() { - // UUS information not supported in CDMA - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java deleted file mode 100644 index 141736c74b3f..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java +++ /dev/null @@ -1,123 +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.cdma; - -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.DataConnection; -import com.android.internal.telephony.DataConnectionTracker; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.RetryManager; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -/** - * {@hide} - */ -public class CdmaDataConnection extends DataConnection { - - private static final String LOG_TAG = "CDMA"; - - // ***** Constructor - private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm, - DataConnectionTracker dct) { - super(phone, name, id, rm, dct); - } - - /** - * Create the connection object - * - * @param phone the Phone - * @param id the connection id - * @param rm the RetryManager - * @return CdmaDataConnection that was created. - */ - static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm, - DataConnectionTracker dct) { - CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, - "CdmaDC-" + mCount.incrementAndGet(), id, rm, dct); - cdmaDc.start(); - if (DBG) cdmaDc.log("Made " + cdmaDc.getName()); - return cdmaDc; - } - - /** - * Begin setting up a data connection, calls setupDataCall - * and the ConnectionParams will be returned with the - * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj. - * - * @param cp is the connection parameters - */ - @Override - protected void onConnect(ConnectionParams cp) { - if (DBG) log("CdmaDataConnection Connecting..."); - - mApn = cp.apn; - createTime = -1; - lastFailTime = -1; - lastFailCause = FailCause.NONE; - int dataProfile; - if ((cp.apn != null) && (cp.apn.types.length > 0) && (cp.apn.types[0] != null) && - (cp.apn.types[0].equals(Phone.APN_TYPE_DUN))) { - if (DBG) log("CdmaDataConnection using DUN"); - dataProfile = RILConstants.DATA_PROFILE_TETHERED; - } else { - dataProfile = RILConstants.DATA_PROFILE_DEFAULT; - } - - // msg.obj will be returned in AsyncResult.userObj; - Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); - msg.obj = cp; - phone.mCM.setupDataCall( - Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)), - Integer.toString(dataProfile), - null, null, null, - Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP), - RILConstants.SETUP_DATA_PROTOCOL_IP, msg); - } - - @Override - public String toString() { - return "State=" + getCurrentState().getName() + " create=" + createTime + " lastFail=" - + lastFailTime + " lastFasilCause=" + lastFailCause; - } - - @Override - protected boolean isDnsOk(String[] domainNameServers) { - if (NULL_IP.equals(domainNameServers[0]) - && NULL_IP.equals(domainNameServers[1]) - && !phone.isDnsCheckDisabled()) { - return false; - } else { - return true; - } - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[" + getName() + "] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CdmaDataConnection extends:"); - super.dump(fd, pw, args); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java deleted file mode 100644 index a691eaec22a5..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ /dev/null @@ -1,1040 +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.cdma; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.TrafficStats; -import android.os.AsyncResult; -import android.os.Message; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.telephony.cdma.CdmaCellLocation; -import android.text.TextUtils; -import android.util.EventLog; -import android.util.Log; - -import com.android.internal.telephony.ApnSetting; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.DataCallState; -import com.android.internal.telephony.DataConnection.FailCause; -import com.android.internal.telephony.DataConnection; -import com.android.internal.telephony.DataConnectionAc; -import com.android.internal.telephony.DataConnectionTracker; -import com.android.internal.telephony.EventLogTags; -import com.android.internal.telephony.RetryManager; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.Phone; -import com.android.internal.util.AsyncChannel; -import com.android.internal.telephony.RILConstants; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; - -/** - * {@hide} - */ -public final class CdmaDataConnectionTracker extends DataConnectionTracker { - protected final String LOG_TAG = "CDMA"; - - private CDMAPhone mCdmaPhone; - private CdmaSubscriptionSourceManager mCdmaSSM; - - /** The DataConnection being setup */ - private CdmaDataConnection mPendingDataConnection; - - private boolean mPendingRestartRadio = false; - private static final int TIME_DELAYED_TO_RESTART_RADIO = - SystemProperties.getInt("ro.cdma.timetoradiorestart", 60000); - - /** - * Pool size of CdmaDataConnection objects. - */ - private static final int DATA_CONNECTION_POOL_SIZE = 1; - - private static final String INTENT_RECONNECT_ALARM = - "com.android.internal.telephony.cdma-reconnect"; - - private static final String INTENT_DATA_STALL_ALARM = - "com.android.internal.telephony.cdma-data-stall"; - - - /** - * Constants for the data connection activity: - * physical link down/up - */ - private static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0; - private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1; - private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2; - - private static final String[] mSupportedApnTypes = { - Phone.APN_TYPE_DEFAULT, - Phone.APN_TYPE_MMS, - Phone.APN_TYPE_DUN, - Phone.APN_TYPE_HIPRI }; - - private static final String[] mDefaultApnTypes = { - Phone.APN_TYPE_DEFAULT, - Phone.APN_TYPE_MMS, - Phone.APN_TYPE_HIPRI }; - - private String[] mDunApnTypes = { - Phone.APN_TYPE_DUN }; - - private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID; - - /* Constructor */ - - CdmaDataConnectionTracker(CDMAPhone p) { - super(p); - mCdmaPhone = p; - - p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null); - p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null); - p.mCM.registerForDataNetworkStateChanged (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.registerForDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null); - p.mSST.registerForDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null); - p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null); - p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null); - p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null); - mCdmaSSM = CdmaSubscriptionSourceManager.getInstance (p.getContext(), p.mCM, this, - EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); - - mDataConnectionTracker = this; - - createAllDataConnectionList(); - broadcastMessenger(); - - Context c = mCdmaPhone.getContext(); - String[] t = c.getResources().getStringArray( - com.android.internal.R.array.config_cdma_dun_supported_types); - if (t != null && t.length > 0) { - ArrayList temp = new ArrayList(); - for(int i=0; i< t.length; i++) { - if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) { - temp.add(t[i]); - } - } - temp.add(0, Phone.APN_TYPE_DUN); - mDunApnTypes = temp.toArray(t); - } - - } - - @Override - public void dispose() { - cleanUpConnection(false, null, false); - - super.dispose(); - - // Unregister from all events - mPhone.mCM.unregisterForAvailable(this); - mPhone.mCM.unregisterForOffOrNotAvailable(this); - mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this); - mPhone.mCM.unregisterForDataNetworkStateChanged(this); - mCdmaPhone.mCT.unregisterForVoiceCallEnded(this); - mCdmaPhone.mCT.unregisterForVoiceCallStarted(this); - mCdmaPhone.mSST.unregisterForDataConnectionAttached(this); - mCdmaPhone.mSST.unregisterForDataConnectionDetached(this); - mCdmaPhone.mSST.unregisterForRoamingOn(this); - mCdmaPhone.mSST.unregisterForRoamingOff(this); - mCdmaSSM.dispose(this); - mPhone.mCM.unregisterForCdmaOtaProvision(this); - - destroyAllDataConnectionList(); - } - - @Override - protected void finalize() { - if(DBG) log("CdmaDataConnectionTracker finalized"); - } - - @Override - protected String getActionIntentReconnectAlarm() { - return INTENT_RECONNECT_ALARM; - } - - @Override - protected String getActionIntentDataStallAlarm() { - return INTENT_DATA_STALL_ALARM; - } - - @Override - protected void restartDataStallAlarm() {} - - @Override - protected void setState(State s) { - if (DBG) log ("setState: " + s); - if (mState != s) { - EventLog.writeEvent(EventLogTags.CDMA_DATA_STATE_CHANGE, - mState.toString(), s.toString()); - mState = s; - } - } - - @Override - public synchronized State getState(String apnType) { - return mState; - } - - @Override - protected boolean isApnTypeAvailable(String type) { - for (String s : mSupportedApnTypes) { - if (TextUtils.equals(type, s)) { - return true; - } - } - return false; - } - - @Override - protected boolean isDataAllowed() { - final boolean internalDataEnabled; - synchronized (mDataEnabledLock) { - internalDataEnabled = mInternalDataEnabled; - } - - int psState = mCdmaPhone.mSST.getCurrentDataConnectionState(); - boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()); - boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState(); - boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource() - == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV); - - boolean allowed = - (psState == ServiceState.STATE_IN_SERVICE || - mAutoAttachOnCreation) && - (subscriptionFromNv || - mCdmaPhone.mIccRecords.getRecordsLoaded()) && - (mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() || - mPhone.getState() == Phone.State.IDLE) && - !roaming && - internalDataEnabled && - desiredPowerState && - !mPendingRestartRadio && - ((mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) || - !mCdmaPhone.needsOtaServiceProvisioning()); - if (!allowed && DBG) { - String reason = ""; - if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) { - reason += " - psState= " + psState; - } - if (!subscriptionFromNv && - !mCdmaPhone.mIccRecords.getRecordsLoaded()) { - reason += " - RUIM not loaded"; - } - if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() || - mPhone.getState() == Phone.State.IDLE)) { - reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState(); - } - if (roaming) reason += " - Roaming"; - if (!internalDataEnabled) reason += " - mInternalDataEnabled= false"; - if (!desiredPowerState) reason += " - desiredPowerState= false"; - if (mPendingRestartRadio) reason += " - mPendingRestartRadio= true"; - if (mCdmaPhone.needsOtaServiceProvisioning()) reason += " - needs Provisioning"; - log("Data not allowed due to" + reason); - } - return allowed; - } - - @Override - protected boolean isDataPossible(String apnType) { - boolean possible = isDataAllowed() && !(getAnyDataEnabled() && - (mState == State.FAILED || mState == State.IDLE)); - if (!possible && DBG && isDataAllowed()) { - log("Data not possible. No coverage: dataState = " + mState); - } - return possible; - } - - private boolean trySetupData(String reason) { - if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason)); - - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - setState(State.CONNECTED); - notifyDataConnection(reason); - notifyOffApnsOfAvailability(reason); - - log("(fix?) We're on the simulator; assuming data is connected"); - return true; - } - - int psState = mCdmaPhone.mSST.getCurrentDataConnectionState(); - boolean roaming = mPhone.getServiceState().getRoaming(); - boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState(); - - if ((mState == State.IDLE || mState == State.SCANNING) && - isDataAllowed() && getAnyDataEnabled() && !isEmergency()) { - boolean retValue = setupData(reason); - notifyOffApnsOfAvailability(reason); - return retValue; - } else { - notifyOffApnsOfAvailability(reason); - return false; - } - } - - /** - * Cleanup the CDMA data connection (only one is supported) - * - * @param tearDown true if the underlying DataConnection should be disconnected. - * @param reason for the clean up. - */ - private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) { - if (DBG) log("cleanUpConnection: reason: " + reason); - - // Clear the reconnect alarm, if set. - if (mReconnectIntent != null) { - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - am.cancel(mReconnectIntent); - mReconnectIntent = null; - } - - setState(State.DISCONNECTING); - notifyOffApnsOfAvailability(reason); - - boolean notificationDeferred = false; - for (DataConnection conn : mDataConnections.values()) { - if(conn != null) { - DataConnectionAc dcac = - mDataConnectionAsyncChannels.get(conn.getDataConnectionId()); - if (tearDown) { - if (doAll) { - if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll"); - conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE, - conn.getDataConnectionId(), 0, reason)); - } else { - if (DBG) log("cleanUpConnection: teardown, conn.tearDown"); - conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE, - conn.getDataConnectionId(), 0, reason)); - } - notificationDeferred = true; - } else { - if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously"); - if (dcac != null) { - dcac.resetSync(); - } - notificationDeferred = false; - } - } - } - - stopNetStatPoll(); - - if (!notificationDeferred) { - if (DBG) log("cleanupConnection: !notificationDeferred"); - gotoIdleAndNotifyDataConnection(reason); - } - } - - private CdmaDataConnection findFreeDataConnection() { - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - if (dcac.isInactiveSync()) { - log("found free GsmDataConnection"); - return (CdmaDataConnection) dcac.dataConnection; - } - } - log("NO free CdmaDataConnection"); - return null; - } - - private boolean setupData(String reason) { - CdmaDataConnection conn = findFreeDataConnection(); - - if (conn == null) { - if (DBG) log("setupData: No free CdmaDataConnection found!"); - return false; - } - - /** TODO: We probably want the connection being setup to a parameter passed around */ - mPendingDataConnection = conn; - String[] types; - int apnId; - if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) { - types = mDunApnTypes; - apnId = DataConnectionTracker.APN_DUN_ID; - } else { - types = mDefaultApnTypes; - apnId = mDefaultApnId; - } - mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "", - "", 0, types, "IP", "IP", true, 0); - if (DBG) log("call conn.bringUp mActiveApn=" + mActiveApn); - - Message msg = obtainMessage(); - msg.what = EVENT_DATA_SETUP_COMPLETE; - msg.obj = reason; - conn.bringUp(msg, mActiveApn); - - setState(State.INITING); - notifyDataConnection(reason); - return true; - } - - private void notifyDefaultData(String reason) { - setState(State.CONNECTED); - notifyDataConnection(reason); - startNetStatPoll(); - mDataConnections.get(0).resetRetryCount(); - } - - private void resetPollStats() { - mTxPkts = -1; - mRxPkts = -1; - mSentSinceLastRecv = 0; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - mNoRecvPollCount = 0; - } - - @Override - protected void startNetStatPoll() { - if (mState == State.CONNECTED && mNetStatPollEnabled == false) { - log("[DataConnection] Start poll NetStat"); - resetPollStats(); - mNetStatPollEnabled = true; - mPollNetStat.run(); - } - } - - @Override - protected void stopNetStatPoll() { - mNetStatPollEnabled = false; - removeCallbacks(mPollNetStat); - log("[DataConnection] Stop poll NetStat"); - } - - @Override - protected void restartRadio() { - if (DBG) log("Cleanup connection and wait " + - (TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio"); - cleanUpAllConnections(null); - sendEmptyMessageDelayed(EVENT_RESTART_RADIO, TIME_DELAYED_TO_RESTART_RADIO); - mPendingRestartRadio = true; - } - - private Runnable mPollNetStat = new Runnable() { - - public void run() { - long sent, received; - long preTxPkts = -1, preRxPkts = -1; - - Activity newActivity; - - preTxPkts = mTxPkts; - preRxPkts = mRxPkts; - - mTxPkts = TrafficStats.getMobileTxPackets(); - mRxPkts = TrafficStats.getMobileRxPackets(); - - //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts)); - - if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) { - sent = mTxPkts - preTxPkts; - received = mRxPkts - preRxPkts; - - if ( sent > 0 && received > 0 ) { - mSentSinceLastRecv = 0; - newActivity = Activity.DATAINANDOUT; - } else if (sent > 0 && received == 0) { - if (mPhone.getState() == Phone.State.IDLE) { - mSentSinceLastRecv += sent; - } else { - mSentSinceLastRecv = 0; - } - newActivity = Activity.DATAOUT; - } else if (sent == 0 && received > 0) { - mSentSinceLastRecv = 0; - newActivity = Activity.DATAIN; - } else if (sent == 0 && received == 0) { - newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE; - } else { - mSentSinceLastRecv = 0; - newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE; - } - - if (mActivity != newActivity && mIsScreenOn) { - mActivity = newActivity; - mPhone.notifyDataActivity(); - } - } - - if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) { - // Packets sent without ack exceeded threshold. - - if (mNoRecvPollCount == 0) { - EventLog.writeEvent( - EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED, - mSentSinceLastRecv); - } - - if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) { - mNoRecvPollCount++; - // Slow down the poll interval to let things happen - mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS; - } else { - if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) + - " pkts since last received"); - // We've exceeded the threshold. Restart the radio. - mNetStatPollEnabled = false; - stopNetStatPoll(); - restartRadio(); - EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT); - } - } else { - mNoRecvPollCount = 0; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - } - - if (mNetStatPollEnabled) { - mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod); - } - } - }; - - /** - * 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); - } - - /** - * Return true if data connection need to be setup after disconnected due to - * reason. - * - * @param reason the reason why data is disconnected - * @return true if try setup data connection is need for this reason - */ - private boolean retryAfterDisconnected(String reason) { - boolean retry = true; - - if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) { - retry = false; - } - return retry; - } - - private void reconnectAfterFail(FailCause lastFailCauseCode, String reason, int retryOverride) { - if (mState == State.FAILED) { - /** - * For now With CDMA we never try to reconnect on - * error and instead just continue to retry - * at the last time until the state is changed. - * TODO: Make this configurable? - */ - int nextReconnectDelay = retryOverride; - if (nextReconnectDelay < 0) { - nextReconnectDelay = mDataConnections.get(0).getRetryTimer(); - mDataConnections.get(0).increaseRetryCount(); - } - startAlarmForReconnect(nextReconnectDelay, reason); - - if (!shouldPostNotification(lastFailCauseCode)) { - log("NOT Posting Data Connection Unavailable notification " - + "-- likely transient error"); - } else { - notifyNoData(lastFailCauseCode); - } - } - } - - private void startAlarmForReconnect(int delay, String reason) { - - log("Data Connection activate failed. Scheduling next attempt for " - + (delay / 1000) + "s"); - - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(INTENT_RECONNECT_ALARM); - intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason); - mReconnectIntent = PendingIntent.getBroadcast( - mPhone.getContext(), 0, intent, 0); - am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delay, mReconnectIntent); - - } - - private void notifyNoData(FailCause lastFailCauseCode) { - setState(State.FAILED); - notifyOffApnsOfAvailability(null); - } - - protected void gotoIdleAndNotifyDataConnection(String reason) { - if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason); - setState(State.IDLE); - notifyDataConnection(reason); - mActiveApn = null; - } - - protected void onRecordsLoaded() { - if (mState == State.FAILED) { - cleanUpAllConnections(null); - } - sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED)); - } - - protected void onNVReady() { - if (mState == State.FAILED) { - cleanUpAllConnections(null); - } - sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA)); - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onEnableNewApn() { - // No mRequestedApnType check; only one connection is supported - cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false); - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected boolean onTrySetupData(String reason) { - return trySetupData(reason); - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onRoamingOff() { - if (mUserDataEnabled == false) return; - - if (getDataOnRoamingEnabled() == false) { - notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF); - trySetupData(Phone.REASON_ROAMING_OFF); - } else { - notifyDataConnection(Phone.REASON_ROAMING_OFF); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onRoamingOn() { - if (mUserDataEnabled == false) return; - - if (getDataOnRoamingEnabled()) { - trySetupData(Phone.REASON_ROAMING_ON); - notifyDataConnection(Phone.REASON_ROAMING_ON); - } else { - if (DBG) log("Tear down data connection on roaming."); - cleanUpAllConnections(null); - notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onRadioAvailable() { - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - setState(State.CONNECTED); - notifyDataConnection(null); - - log("We're on the simulator; assuming data is connected"); - } - - notifyOffApnsOfAvailability(null); - - if (mState != State.IDLE) { - cleanUpAllConnections(null); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onRadioOffOrNotAvailable() { - mDataConnections.get(0).resetRetryCount(); - - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - log("We're on the simulator; assuming radio off is meaningless"); - } else { - if (DBG) log("Radio is off and clean up all connection"); - cleanUpAllConnections(null); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onDataSetupComplete(AsyncResult ar) { - String reason = null; - if (ar.userObj instanceof String) { - reason = (String) ar.userObj; - } - - if (isDataSetupCompleteOk(ar)) { - // Everything is setup - notifyDefaultData(reason); - } else { - FailCause cause = (FailCause) (ar.result); - if(DBG) log("Data Connection setup failed " + cause); - - // No try for permanent failure - if (cause.isPermanentFail()) { - notifyNoData(cause); - return; - } - - int retryOverride = -1; - if (ar.exception instanceof DataConnection.CallSetupException) { - retryOverride = - ((DataConnection.CallSetupException)ar.exception).getRetryOverride(); - } - if (retryOverride == RILConstants.MAX_INT) { - if (DBG) log("No retry is suggested."); - } else { - startDelayedRetry(cause, reason, retryOverride); - } - } - } - - /** - * Called when EVENT_DISCONNECT_DONE is received. - */ - @Override - protected void onDisconnectDone(int connId, AsyncResult ar) { - if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId); - String reason = null; - if (ar.userObj instanceof String) { - reason = (String) ar.userObj; - } - setState(State.IDLE); - - // Since the pending request to turn off or restart radio will be processed here, - // remove the pending event to restart radio from the message queue. - if (mPendingRestartRadio) removeMessages(EVENT_RESTART_RADIO); - - // Process the pending request to turn off radio in ServiceStateTracker first. - // If radio is turned off in ServiceStateTracker, ignore the pending event to restart radio. - CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST; - if (ssTracker.processPendingRadioPowerOffAfterDataOff()) { - mPendingRestartRadio = false; - } else { - onRestartRadio(); - } - - notifyDataConnection(reason); - mActiveApn = null; - if (retryAfterDisconnected(reason)) { - // Wait a bit before trying, so we're not tying up RIL command channel. - startAlarmForReconnect(APN_DELAY_MILLIS, reason); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onVoiceCallStarted() { - if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) { - stopNetStatPoll(); - notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); - notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_STARTED); - } - } - - /** - * @override com.android.internal.telephony.DataConnectionTracker - */ - @Override - protected void onVoiceCallEnded() { - if (mState == State.CONNECTED) { - if (!mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) { - startNetStatPoll(); - notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); - } else { - // clean slate after call end. - resetPollStats(); - } - notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_ENDED); - } else { - mDataConnections.get(0).resetRetryCount(); - // in case data setup was attempted when we were on a voice call - trySetupData(Phone.REASON_VOICE_CALL_ENDED); - } - } - - @Override - protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) { - // No apnId check; only one connection is supported - cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID)); - } - - @Override - protected void onCleanUpAllConnections(String cause) { - // Only one CDMA connection is supported - cleanUpConnection(true, cause, false); - } - - private void createAllDataConnectionList() { - CdmaDataConnection dataConn; - - String retryConfig = SystemProperties.get("ro.cdma.data_retry_config"); - for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) { - RetryManager rm = new RetryManager(); - if (!rm.configure(retryConfig)) { - if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) { - // Should never happen, log an error and default to a simple linear sequence. - log("Could not configure using DEFAULT_DATA_RETRY_CONFIG=" - + DEFAULT_DATA_RETRY_CONFIG); - rm.configure(20, 2000, 1000); - } - } - - int id = mUniqueIdGenerator.getAndIncrement(); - dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this); - mDataConnections.put(id, dataConn); - DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG); - int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler()); - if (status == AsyncChannel.STATUS_SUCCESSFUL) { - log("Fully connected"); - mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac); - } else { - log("Could not connect to dcac.dataConnection=" + dcac.dataConnection + - " status=" + status); - } - - } - } - - private void destroyAllDataConnectionList() { - if(mDataConnections != null) { - mDataConnections.clear(); - } - } - - private void onCdmaDataDetached() { - if (mState == State.CONNECTED) { - startNetStatPoll(); - notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); - } else { - if (mState == State.FAILED) { - cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false); - mDataConnections.get(0).resetRetryCount(); - - CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation()); - EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED, - loc != null ? loc.getBaseStationId() : -1, - TelephonyManager.getDefault().getNetworkType()); - } - trySetupData(Phone.REASON_CDMA_DATA_DETACHED); - } - } - - private void onCdmaOtaProvision(AsyncResult ar) { - if (ar.exception != null) { - int [] otaPrivision = (int [])ar.result; - if ((otaPrivision != null) && (otaPrivision.length > 1)) { - switch (otaPrivision[0]) { - case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED: - case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED: - mDataConnections.get(0).resetRetryCount(); - break; - default: - break; - } - } - } - } - - private void onRestartRadio() { - if (mPendingRestartRadio) { - log("************TURN OFF RADIO**************"); - mPhone.mCM.setRadioPower(false, null); - /* Note: no need to call setRadioPower(true). Assuming the desired - * radio power state is still ON (as tracked by ServiceStateTracker), - * ServiceStateTracker will call setRadioPower when it receives the - * 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. - */ - mPendingRestartRadio = false; - } - } - - private void writeEventLogCdmaDataDrop() { - CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation()); - EventLog.writeEvent(EventLogTags.CDMA_DATA_DROP, - loc != null ? loc.getBaseStationId() : -1, - TelephonyManager.getDefault().getNetworkType()); - } - - protected void onDataStateChanged(AsyncResult ar) { - ArrayList dataCallStates = (ArrayList)(ar.result); - - 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; - } - - if (mState == State.CONNECTED) { - boolean isActiveOrDormantConnectionPresent = false; - int connectionState = DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE; - - // Check for an active or dormant connection element in - // the DATA_CALL_LIST array - for (int index = 0; index < dataCallStates.size(); index++) { - connectionState = dataCallStates.get(index).active; - if (connectionState != DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) { - isActiveOrDormantConnectionPresent = true; - break; - } - } - - if (!isActiveOrDormantConnectionPresent) { - // No active or dormant connection - log("onDataStateChanged: No active connection" - + "state is CONNECTED, disconnecting/cleanup"); - writeEventLogCdmaDataDrop(); - cleanUpConnection(true, null, false); - return; - } - - switch (connectionState) { - case DATA_CONNECTION_ACTIVE_PH_LINK_UP: - log("onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore"); - mActivity = Activity.NONE; - mPhone.notifyDataActivity(); - startNetStatPoll(); - break; - - case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN: - log("onDataStateChanged active=LINK_DOWN && CONNECTED, dormant"); - mActivity = Activity.DORMANT; - mPhone.notifyDataActivity(); - stopNetStatPoll(); - break; - - default: - log("onDataStateChanged: IGNORE unexpected DataCallState.active=" - + connectionState); - } - } else { - // TODO: Do we need to do anything? - log("onDataStateChanged: not connected, state=" + mState + " ignoring"); - } - } - - private void startDelayedRetry(FailCause cause, String reason, int retryOverride) { - notifyNoData(cause); - reconnectAfterFail(cause, reason, retryOverride); - } - - @Override - public void handleMessage (Message msg) { - if (DBG) log("CdmaDCT handleMessage msg=" + msg); - - if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) { - log("Ignore CDMA msgs since CDMA phone is inactive"); - return; - } - - switch (msg.what) { - case EVENT_RECORDS_LOADED: - onRecordsLoaded(); - break; - - case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: - if(mCdmaSSM.getCdmaSubscriptionSource() == - CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV) { - onNVReady(); - } - break; - - case EVENT_CDMA_DATA_DETACHED: - onCdmaDataDetached(); - break; - - case EVENT_DATA_STATE_CHANGED: - onDataStateChanged((AsyncResult) msg.obj); - break; - - case EVENT_CDMA_OTA_PROVISION: - onCdmaOtaProvision((AsyncResult) msg.obj); - break; - - case EVENT_RESTART_RADIO: - if (DBG) log("EVENT_RESTART_RADIO"); - onRestartRadio(); - break; - - default: - // handle the message in the super class DataConnectionTracker - super.handleMessage(msg); - break; - } - } - - @Override - public boolean isDisconnected() { - return ((mState == State.IDLE) || (mState == State.FAILED)); - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[CdmaDCT] " + s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[CdmaDCT] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CdmaDataConnectionTracker extends:"); - super.dump(fd, pw, args); - pw.println(" mCdmaPhone=" + mCdmaPhone); - pw.println(" mCdmaSSM=" + mCdmaSSM); - pw.println(" mPendingDataConnection=" + mPendingDataConnection); - pw.println(" mPendingRestartRadio=" + mPendingRestartRadio); - pw.println(" mSupportedApnTypes=" + mSupportedApnTypes); - pw.println(" mDefaultApnTypes=" + mDefaultApnTypes); - pw.println(" mDunApnTypes=" + mDunApnTypes); - pw.println(" mDefaultApnId=" + mDefaultApnId); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java deleted file mode 100644 index ce6530af8ce6..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; -import static com.android.internal.telephony.RILConstants.*; -import android.os.Parcel; - -public final class CdmaInformationRecords { - public Object record; - - /** - * Record type identifier - */ - public static final int RIL_CDMA_DISPLAY_INFO_REC = 0; - public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1; - public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2; - public static final int RIL_CDMA_CONNECTED_NUMBER_INFO_REC = 3; - public static final int RIL_CDMA_SIGNAL_INFO_REC = 4; - public static final int RIL_CDMA_REDIRECTING_NUMBER_INFO_REC = 5; - public static final int RIL_CDMA_LINE_CONTROL_INFO_REC = 6; - public static final int RIL_CDMA_EXTENDED_DISPLAY_INFO_REC = 7; - public static final int RIL_CDMA_T53_CLIR_INFO_REC = 8; - public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9; - public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10; - - public CdmaInformationRecords(Parcel p) { - int id = p.readInt(); - switch (id) { - case RIL_CDMA_DISPLAY_INFO_REC: - case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: - record = new CdmaDisplayInfoRec(id, p.readString()); - break; - - case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: - record = new CdmaNumberInfoRec(id, p.readString(), p.readInt(), p.readInt(), - p.readInt(), p.readInt()); - break; - - case RIL_CDMA_SIGNAL_INFO_REC: - record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt()); - break; - - case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: - record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(), - p.readInt(), p.readInt(), p.readInt()); - break; - - case RIL_CDMA_LINE_CONTROL_INFO_REC: - record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(), - p.readInt()); - break; - - case RIL_CDMA_T53_CLIR_INFO_REC: - record = new CdmaT53ClirInfoRec(p.readInt()); - break; - - case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: - record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt()); - break; - - case RIL_CDMA_T53_RELEASE_INFO_REC: - // TODO: WHAT to do, for now fall through and throw exception - default: - throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got " - + CdmaInformationRecords.idToString(id) + " "); - - } - } - - public static String idToString(int id) { - switch(id) { - case RIL_CDMA_DISPLAY_INFO_REC: return "RIL_CDMA_DISPLAY_INFO_REC"; - case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC"; - case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC"; - case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: return "RIL_CDMA_CONNECTED_NUMBER_INFO_REC"; - case RIL_CDMA_SIGNAL_INFO_REC: return "RIL_CDMA_SIGNAL_INFO_REC"; - case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: return "RIL_CDMA_REDIRECTING_NUMBER_INFO_REC"; - case RIL_CDMA_LINE_CONTROL_INFO_REC: return "RIL_CDMA_LINE_CONTROL_INFO_REC"; - case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: return "RIL_CDMA_EXTENDED_DISPLAY_INFO_REC"; - case RIL_CDMA_T53_CLIR_INFO_REC: return "RIL_CDMA_T53_CLIR_INFO_REC"; - case RIL_CDMA_T53_RELEASE_INFO_REC: return "RIL_CDMA_T53_RELEASE_INFO_REC"; - case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: return "RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC"; - default: return ""; - } - } - - /** - * Signal Information record from 3GPP2 C.S005 3.7.5.5 - */ - public static class CdmaSignalInfoRec { - public boolean isPresent; /* non-zero if signal information record is present */ - public int signalType; - public int alertPitch; - public int signal; - - public CdmaSignalInfoRec() {} - - public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) { - this.isPresent = isPresent != 0; - this.signalType = signalType; - this.alertPitch = alertPitch; - this.signal = signal; - } - - @Override - public String toString() { - return "CdmaSignalInfo: {" + - " isPresent: " + isPresent + - ", signalType: " + signalType + - ", alertPitch: " + alertPitch + - ", signal: " + signal + - " }"; - } - } - - public static class CdmaDisplayInfoRec { - public int id; - public String alpha; - - public CdmaDisplayInfoRec(int id, String alpha) { - this.id = id; - this.alpha = alpha; - } - - @Override - public String toString() { - return "CdmaDisplayInfoRec: {" + - " id: " + CdmaInformationRecords.idToString(id) + - ", alpha: " + alpha + - " }"; - } - } - - public static class CdmaNumberInfoRec { - public int id; - public String number; - public byte numberType; - public byte numberPlan; - public byte pi; - public byte si; - - public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi, - int si) { - this.number = number; - this.numberType = (byte)numberType; - this.numberPlan = (byte)numberPlan; - this.pi = (byte)pi; - this.si = (byte)si; - } - - @Override - public String toString() { - return "CdmaNumberInfoRec: {" + - " id: " + CdmaInformationRecords.idToString(id) + - ", number: " + number + - ", numberType: " + numberType + - ", numberPlan: " + numberPlan + - ", pi: " + pi + - ", si: " + si + - " }"; - } - } - - public static class CdmaRedirectingNumberInfoRec { - public static final int REASON_UNKNOWN = 0; - public static final int REASON_CALL_FORWARDING_BUSY = 1; - public static final int REASON_CALL_FORWARDING_NO_REPLY = 2; - public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9; - public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10; - public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15; - - public CdmaNumberInfoRec numberInfoRec; - public int redirectingReason; - - public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan, - int pi, int si, int reason) { - numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, - number, numberType, numberPlan, pi, si); - redirectingReason = reason; - } - - @Override - public String toString() { - return "CdmaNumberInfoRec: {" + - " numberInfoRec: " + numberInfoRec + - ", redirectingReason: " + redirectingReason + - " }"; - } - } - - public static class CdmaLineControlInfoRec { - public byte lineCtrlPolarityIncluded; - public byte lineCtrlToggle; - public byte lineCtrlReverse; - public byte lineCtrlPowerDenial; - - public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle, - int lineCtrlReverse, int lineCtrlPowerDenial) { - this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded; - this.lineCtrlToggle = (byte)lineCtrlToggle; - this.lineCtrlReverse = (byte)lineCtrlReverse; - this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial; - } - - @Override - public String toString() { - return "CdmaLineControlInfoRec: {" + - " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded + - " lineCtrlToggle: " + lineCtrlToggle + - " lineCtrlReverse: " + lineCtrlReverse + - " lineCtrlPowerDenial: " + lineCtrlPowerDenial + - " }"; - } - } - - public static class CdmaT53ClirInfoRec { - public byte cause; - - public CdmaT53ClirInfoRec(int cause) { - this.cause = (byte)cause; - } - - @Override - public String toString() { - return "CdmaT53ClirInfoRec: {" + - " cause: " + cause + - " }"; - } - } - - public static class CdmaT53AudioControlInfoRec { - public byte uplink; - public byte downlink; - - public CdmaT53AudioControlInfoRec(int uplink, int downlink) { - this.uplink = (byte) uplink; - this.downlink = (byte) downlink; - } - - @Override - public String toString() { - return "CdmaT53AudioControlInfoRec: {" + - " uplink: " + uplink + - " downlink: " + downlink + - " }"; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java deleted file mode 100644 index 0a40c759848e..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java +++ /dev/null @@ -1,546 +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 com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.EventLogTags; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.IccCard; - -import android.content.Intent; -import android.telephony.SignalStrength; -import android.telephony.ServiceState; -import android.telephony.cdma.CdmaCellLocation; -import android.os.AsyncResult; -import android.os.Message; -import android.os.SystemProperties; -import android.provider.Telephony.Intents; - -import android.text.TextUtils; -import android.util.Log; -import android.util.EventLog; - -import com.android.internal.telephony.gsm.GsmDataConnectionTracker; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { - CDMALTEPhone mCdmaLtePhone; - - private ServiceState mLteSS; // The last LTE state from Voice Registration - - public CdmaLteServiceStateTracker(CDMALTEPhone phone) { - super(phone); - mCdmaLtePhone = phone; - - mLteSS = new ServiceState(); - if (DBG) log("CdmaLteServiceStateTracker Constructors"); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - int[] ints; - String[] strings; - switch (msg.what) { - case EVENT_POLL_STATE_GPRS: - if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS"); - ar = (AsyncResult)msg.obj; - handlePollStateResult(msg.what, ar); - break; - case EVENT_RUIM_RECORDS_LOADED: - CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords; - if ((sim != null) && sim.isProvisioned()) { - mMdn = sim.getMdn(); - mMin = sim.getMin(); - parseSidNid(sim.getSid(), sim.getNid()); - mPrlVersion = sim.getPrlVersion();; - mIsMinInfoReady = true; - updateOtaspState(); - } - // SID/NID/PRL is loaded. Poll service state - // again to update to the roaming state with - // the latest variables. - pollState(); - break; - default: - super.handleMessage(msg); - } - } - - /** - * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA - */ - @Override - protected void setCdmaTechnology(int radioTechnology) { - // Called on voice registration state response. - // Just record new CDMA radio technology - newSS.setRadioTechnology(radioTechnology); - } - - /** - * Handle the result of one of the pollState()-related requests - */ - @Override - protected void handlePollStateResultMessage(int what, AsyncResult ar) { - if (what == EVENT_POLL_STATE_GPRS) { - if (DBG) log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS"); - String states[] = (String[])ar.result; - - int type = 0; - int regState = -1; - 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]); - } - } catch (NumberFormatException ex) { - loge("handlePollStateResultMessage: error parsing GprsRegistrationState: " - + ex); - } - } - - mLteSS.setRadioTechnology(type); - mLteSS.setState(regCodeToServiceState(regState)); - } else { - super.handlePollStateResultMessage(what, ar); - } - } - - @Override - protected void setSignalStrengthDefaultValues() { - // TODO Make a constructor only has boolean gsm as parameter - mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, - -1, -1, -1, SignalStrength.INVALID_SNR, -1, false); - } - - @Override - protected void pollState() { - pollingContext = new int[1]; - pollingContext[0] = 0; - - switch (cm.getRadioState()) { - case RADIO_UNAVAILABLE: - newSS.setStateOutOfService(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - mGotCountryCode = false; - - pollStateDone(); - break; - - case RADIO_OFF: - newSS.setStateOff(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - 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 - cm.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext)); - - pollingContext[0]++; - // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA - cm.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, - pollingContext)); - - int networkMode = android.provider.Settings.Secure.getInt(phone.getContext() - .getContentResolver(), - android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, - RILConstants.PREFERRED_NETWORK_MODE); - if (DBG) log("pollState: network mode here is = " + networkMode); - if ((networkMode == RILConstants.NETWORK_MODE_GLOBAL) - || (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY)) { - pollingContext[0]++; - // RIL_REQUEST_DATA_REGISTRATION_STATE - cm.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS, - pollingContext)); - } - break; - } - } - - @Override - protected void pollStateDone() { - // determine data RadioTechnology from both LET and CDMA SS - if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) { - //in LTE service - mNewRilRadioTechnology = mLteSS.getRilRadioTechnology(); - mNewDataConnectionState = mLteSS.getState(); - newSS.setRadioTechnology(mNewRilRadioTechnology); - log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " + - mNewRilRadioTechnology); - } else { - // LTE out of service, get CDMA Service State - mNewRilRadioTechnology = newSS.getRilRadioTechnology(); - mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology); - log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " + - mNewRilRadioTechnology + " mNewDataConnectionState = " + - mNewDataConnectionState); - } - - // TODO: Add proper support for LTE Only, we should be looking at - // the preferred network mode, to know when newSS state should - // be coming from mLteSs state. This was needed to pass a VZW - // LTE Only test. - // - // If CDMA service is OOS, double check if the device is running with LTE only - // mode. If that is the case, derive the service state from LTE side. - // To set in LTE only mode, sqlite3 /data/data/com.android.providers.settings/ - // databases/settings.db "update secure set value='11' where name='preferred_network_mode'" - if (newSS.getState() == ServiceState.STATE_OUT_OF_SERVICE) { - int networkMode = android.provider.Settings.Secure.getInt(phone.getContext() - .getContentResolver(), - android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, - RILConstants.PREFERRED_NETWORK_MODE); - if (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY) { - if (DBG) log("pollState: LTE Only mode"); - newSS.setState(mLteSS.getState()); - } - } - - if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]"); - - boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE - && newSS.getState() == ServiceState.STATE_IN_SERVICE; - - boolean hasDeregistered = ss.getState() == ServiceState.STATE_IN_SERVICE - && newSS.getState() != ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionAttached = - mDataConnectionState != ServiceState.STATE_IN_SERVICE - && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionDetached = - mDataConnectionState == ServiceState.STATE_IN_SERVICE - && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionChanged = - mDataConnectionState != mNewDataConnectionState; - - boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology; - - boolean hasChanged = !newSS.equals(ss); - - boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming(); - - boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming(); - - boolean hasLocationChanged = !newCellLoc.equals(cellLoc); - - boolean has4gHandoff = - mNewDataConnectionState == ServiceState.STATE_IN_SERVICE && - (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) && - (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) || - ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) && - (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE))); - - boolean hasMultiApnSupport = - (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) || - (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) && - ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) && - (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD))); - - boolean hasLostMultiApnSupport = - ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) && - (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)); - - if (DBG) { - log("pollStateDone:" - + " hasRegistered=" + hasRegistered - + " hasDeegistered=" + hasDeregistered - + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached - + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached - + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged - + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged - + " hasChanged=" + hasChanged - + " hasRoamingOn=" + hasRoamingOn - + " hasRoamingOff=" + hasRoamingOff - + " hasLocationChanged=" + hasLocationChanged - + " has4gHandoff = " + has4gHandoff - + " hasMultiApnSupport=" + hasMultiApnSupport - + " hasLostMultiApnSupport=" + hasLostMultiApnSupport); - } - // Add an event log when connection state changes - if (ss.getState() != newSS.getState() - || mDataConnectionState != mNewDataConnectionState) { - EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(), - mDataConnectionState, newSS.getState(), mNewDataConnectionState); - } - - ServiceState tss; - tss = ss; - ss = newSS; - newSS = tss; - // clean slate for next time - newSS.setStateOutOfService(); - mLteSS.setStateOutOfService(); - - if ((hasMultiApnSupport) - && (phone.mDataConnectionTracker instanceof CdmaDataConnectionTracker)) { - if (DBG) log("GsmDataConnectionTracker Created"); - phone.mDataConnectionTracker.dispose(); - phone.mDataConnectionTracker = new GsmDataConnectionTracker(mCdmaLtePhone); - } - - if ((hasLostMultiApnSupport) - && (phone.mDataConnectionTracker instanceof GsmDataConnectionTracker)) { - if (DBG)log("GsmDataConnectionTracker disposed"); - phone.mDataConnectionTracker.dispose(); - phone.mDataConnectionTracker = new CdmaDataConnectionTracker(phone); - } - - CdmaCellLocation tcl = cellLoc; - cellLoc = newCellLoc; - newCellLoc = tcl; - - mDataConnectionState = mNewDataConnectionState; - mRilRadioTechnology = mNewRilRadioTechnology; - mNewRilRadioTechnology = 0; - - newSS.setStateOutOfService(); // clean slate for next time - - if (hasRadioTechnologyChanged) { - phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, - ServiceState.rilRadioTechnologyToString(mRilRadioTechnology)); - } - - if (hasRegistered) { - mNetworkAttachedRegistrants.notifyRegistrants(); - } - - if (hasChanged) { - if (phone.isEriFileLoaded()) { - String eriText; - // Now the CDMAPhone sees the new ServiceState so it can get the - // new ERI text - if (ss.getState() == ServiceState.STATE_IN_SERVICE) { - eriText = phone.getCdmaEriText(); - } else if (ss.getState() == ServiceState.STATE_POWER_OFF) { - eriText = phone.mIccRecords.getServiceProviderName(); - if (TextUtils.isEmpty(eriText)) { - // Sets operator alpha property by retrieving from - // build-time system property - eriText = SystemProperties.get("ro.cdma.home.operator.alpha"); - } - } else { - // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used - // for mRegistrationState 0,2,3 and 4 - eriText = phone.getContext() - .getText(com.android.internal.R.string.roamingTextSearching).toString(); - } - ss.setOperatorAlphaLong(eriText); - } - - if (phone.getIccCard().getState() == IccCard.State.READY) { - // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches - // one configfured in SIM, use operator name from CSIM record. - boolean showSpn = - ((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition(); - int iconIndex = ss.getCdmaEriIconIndex(); - - if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) && - isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) { - ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName()); - } - } - - String operatorNumeric; - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA, - ss.getOperatorAlphaLong()); - - String prevOperatorNumeric = - SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, ""); - operatorNumeric = ss.getOperatorNumeric(); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); - - if (operatorNumeric == null) { - if (DBG) log("operatorNumeric is null"); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); - mGotCountryCode = false; - } else { - String isoCountryCode = ""; - String mcc = operatorNumeric.substring(0, 3); - try { - isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric - .substring(0, 3))); - } catch (NumberFormatException ex) { - loge("countryCodeForMcc error" + ex); - } catch (StringIndexOutOfBoundsException ex) { - loge("countryCodeForMcc error" + ex); - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, - isoCountryCode); - mGotCountryCode = true; - - if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric, - mNeedFixZone)) { - fixTimeZone(isoCountryCode); - } - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, - ss.getRoaming() ? "true" : "false"); - - updateSpnDisplay(); - phone.notifyServiceStateChanged(ss); - } - - if (hasCdmaDataConnectionAttached || has4gHandoff) { - mAttachedRegistrants.notifyRegistrants(); - } - - if (hasCdmaDataConnectionDetached) { - mDetachedRegistrants.notifyRegistrants(); - } - - if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) { - phone.notifyDataConnection(null); - } - - if (hasRoamingOn) { - mRoamingOnRegistrants.notifyRegistrants(); - } - - if (hasRoamingOff) { - mRoamingOffRegistrants.notifyRegistrants(); - } - - if (hasLocationChanged) { - phone.notifyLocationChanged(); - } - } - - @Override - protected void onSignalStrengthResult(AsyncResult ar) { - SignalStrength oldSignalStrength = mSignalStrength; - - if (ar.exception != null) { - // Most likely radio is resetting/disconnected change to default - // values. - setSignalStrengthDefaultValues(); - } else { - int[] ints = (int[])ar.result; - - int lteRssi = -1; - int lteRsrp = -1; - int lteRsrq = -1; - int lteRssnr = SignalStrength.INVALID_SNR; - int lteCqi = -1; - - int offset = 2; - int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120; - int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160; - int evdoRssi = (ints[offset + 2] > 0) ? -ints[offset + 2] : -120; - int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1; - int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4] - : -1; - - if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) { - lteRssi = ints[offset+5]; - lteRsrp = ints[offset+6]; - lteRsrq = ints[offset+7]; - lteRssnr = ints[offset+8]; - lteCqi = ints[offset+9]; - } - - if (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) { - mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, - evdoSnr, false); - } else { - mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, - evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true); - } - } - - try { - phone.notifySignalStrength(); - } catch (NullPointerException ex) { - loge("onSignalStrengthResult() Phone already destroyed: " + ex - + "SignalStrength not notified"); - } - } - - @Override - public boolean isConcurrentVoiceAndDataAllowed() { - // 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 (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE); - } - - /** - * Check whether the specified SID and NID pair appears in the HOME SID/NID list - * read from NV or SIM. - * - * @return true if provided sid/nid pair belongs to operator's home network. - */ - private boolean isInHomeSidNid(int sid, int nid) { - // if SID/NID is not available, assume this is home network. - if (isSidsAllZeros()) return true; - - // length of SID/NID shold be same - if (mHomeSystemId.length != mHomeNetworkId.length) return true; - - if (sid == 0) return true; - - for (int i = 0; i < mHomeSystemId.length; i++) { - // Use SID only if NID is a reserved value. - // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2) - if ((mHomeSystemId[i] == sid) && - ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) || - (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) { - return true; - } - } - // SID/NID are not in the list. So device is not in home network - return false; - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[CdmaLteSST] " + s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[CdmaLteSST] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CdmaLteServiceStateTracker extends:"); - super.dump(fd, pw, args); - pw.println(" mCdmaLtePhone=" + mCdmaLtePhone); - pw.println(" mLteSS=" + mLteSS); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java deleted file mode 100644 index 93a6290cf759..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 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.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccConstants; -import com.android.internal.telephony.IccFileHandler; -import android.os.Message; - -/** - * {@hide} - */ -public final class CdmaLteUiccFileHandler extends IccFileHandler { - static final String LOG_TAG = "CDMA"; - - public CdmaLteUiccFileHandler(IccCard card, String aid, CommandsInterface ci) { - super(card, aid, ci); - } - - protected String getEFPath(int efid) { - switch(efid) { - case EF_CSIM_SPN: - case EF_CSIM_LI: - case EF_CSIM_MDN: - case EF_CSIM_IMSIM: - case EF_CSIM_CDMAHOME: - case EF_CSIM_EPRL: - return MF_SIM + DF_CDMA; - case EF_AD: - return MF_SIM + DF_GSM; - case EF_IMPI: - case EF_DOMAIN: - case EF_IMPU: - return MF_SIM + DF_ADFISIM; - } - return getCommonIccEFPath(efid); - } - - @Override - public void loadEFTransparent(int fileid, Message onLoaded) { - if (fileid == EF_CSIM_EPRL) { - // Entire PRL could be huge. We are only interested in - // the first 4 bytes of the record. - mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), - 0, 0, 4, null, null, mAid, - obtainMessage(EVENT_READ_BINARY_DONE, - fileid, 0, onLoaded)); - } else { - super.loadEFTransparent(fileid, onLoaded); - } - } - - - protected void logd(String msg) { - Log.d(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg); - } - - protected void loge(String msg) { - Log.e(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg); - } - -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java deleted file mode 100755 index eaa2ede622ae..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) 2011 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.AsyncResult; -import android.os.SystemProperties; -import android.util.Log; - -import com.android.internal.telephony.AdnRecordLoader; -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccCardApplication.AppType; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.telephony.gsm.SIMRecords; -import com.android.internal.telephony.ims.IsimRecords; -import com.android.internal.telephony.ims.IsimUiccRecords; - -import java.util.ArrayList; -import java.util.Locale; - -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM; - -/** - * {@hide} - */ -public final class CdmaLteUiccRecords extends SIMRecords { - // From CSIM application - private byte[] mEFpl = null; - private byte[] mEFli = null; - boolean mCsimSpnDisplayCondition = false; - private String mMdn; - private String mMin; - private String mPrlVersion; - private String mHomeSystemId; - private String mHomeNetworkId; - - private final IsimUiccRecords mIsimUiccRecords = new IsimUiccRecords(); - - public CdmaLteUiccRecords(IccCard card, Context c, CommandsInterface ci) { - super(card, c, ci); - } - - // Refer to ETSI TS 102.221 - private class EfPlLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_PL"; - } - - public void onRecordLoaded(AsyncResult ar) { - mEFpl = (byte[]) ar.result; - if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl)); - } - } - - // Refer to C.S0065 5.2.26 - private class EfCsimLiLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_LI"; - } - - public void onRecordLoaded(AsyncResult ar) { - mEFli = (byte[]) ar.result; - // convert csim efli data to iso 639 format - for (int i = 0; i < mEFli.length; i+=2) { - switch(mEFli[i+1]) { - case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break; - case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break; - case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break; - case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break; - case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break; - case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break; - case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break; - default: mEFli[i] = ' '; mEFli[i+1] = ' '; - } - } - - if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli)); - } - } - - // Refer to C.S0065 5.2.32 - private class EfCsimSpnLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_SPN"; - } - - public void onRecordLoaded(AsyncResult ar) { - byte[] data = (byte[]) ar.result; - if (DBG) log("CSIM_SPN=" + - IccUtils.bytesToHexString(data)); - - // C.S0065 for EF_SPN decoding - mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0); - - int encoding = data[1]; - int language = data[2]; - byte[] spnData = new byte[32]; - System.arraycopy(data, 3, spnData, 0, (data.length < 32) ? data.length : 32); - - int numBytes; - for (numBytes = 0; numBytes < spnData.length; numBytes++) { - if ((spnData[numBytes] & 0xFF) == 0xFF) break; - } - - if (numBytes == 0) { - spn = ""; - return; - } - try { - switch (encoding) { - case UserData.ENCODING_OCTET: - case UserData.ENCODING_LATIN: - spn = new String(spnData, 0, numBytes, "ISO-8859-1"); - break; - case UserData.ENCODING_IA5: - case UserData.ENCODING_GSM_7BIT_ALPHABET: - case UserData.ENCODING_7BIT_ASCII: - spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7); - break; - case UserData.ENCODING_UNICODE_16: - spn = new String(spnData, 0, numBytes, "utf-16"); - break; - default: - log("SPN encoding not supported"); - } - } catch(Exception e) { - log("spn decode error: " + e); - } - if (DBG) log("spn=" + spn); - if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition); - SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn); - } - } - - private class EfCsimMdnLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_MDN"; - } - - public void onRecordLoaded(AsyncResult ar) { - byte[] data = (byte[]) ar.result; - if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data)); - int mdnDigitsNum = 0x0F & data[0]; - mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum); - if (DBG) log("CSIM MDN=" + mMdn); - } - } - - private class EfCsimImsimLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_IMSIM"; - } - - public void onRecordLoaded(AsyncResult ar) { - byte[] data = (byte[]) ar.result; - if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data)); - // C.S0065 section 5.2.2 for IMSI_M encoding - // C.S0005 section 2.3.1 for MIN encoding in IMSI_M. - boolean provisioned = ((data[7] & 0x80) == 0x80); - - if (provisioned) { - int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]); - int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6; - int digit7 = 0x0F & (data[4] >> 2); - if (digit7 > 0x09) digit7 = 0; - int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]); - first3digits = adjstMinDigits(first3digits); - second3digits = adjstMinDigits(second3digits); - last3digits = adjstMinDigits(last3digits); - - StringBuilder builder = new StringBuilder(); - builder.append(String.format(Locale.US, "%03d", first3digits)); - builder.append(String.format(Locale.US, "%03d", second3digits)); - builder.append(String.format(Locale.US, "%d", digit7)); - builder.append(String.format(Locale.US, "%03d", last3digits)); - mMin = builder.toString(); - if (DBG) log("min present=" + mMin); - } else { - if (DBG) log("min not present"); - } - } - } - - private class EfCsimCdmaHomeLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_CDMAHOME"; - } - - public void onRecordLoaded(AsyncResult ar) { - // Per C.S0065 section 5.2.8 - ArrayList dataList = (ArrayList) ar.result; - if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size()); - if (dataList.isEmpty()) { - return; - } - StringBuilder sidBuf = new StringBuilder(); - StringBuilder nidBuf = new StringBuilder(); - - for (byte[] data : dataList) { - if (data.length == 5) { - int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF); - int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF); - sidBuf.append(sid).append(','); - nidBuf.append(nid).append(','); - } - } - // remove trailing "," - sidBuf.setLength(sidBuf.length()-1); - nidBuf.setLength(nidBuf.length()-1); - - mHomeSystemId = sidBuf.toString(); - mHomeNetworkId = nidBuf.toString(); - } - } - - private class EfCsimEprlLoaded implements IccRecordLoaded { - public String getEfName() { - return "EF_CSIM_EPRL"; - } - public void onRecordLoaded(AsyncResult ar) { - onGetCSimEprlDone(ar); - } - } - - @Override - protected void onRecordLoaded() { - // One record loaded successfully or failed, In either case - // we need to update the recordsToLoad count - recordsToLoad -= 1; - - if (recordsToLoad == 0 && recordsRequested == true) { - onAllRecordsLoaded(); - } else if (recordsToLoad < 0) { - Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected"); - recordsToLoad = 0; - } - } - - @Override - protected void onAllRecordsLoaded() { - setLocaleFromCsim(); - super.onAllRecordsLoaded(); // broadcasts ICC state change to "LOADED" - } - - @Override - protected void fetchSimRecords() { - recordsRequested = true; - - mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_PL, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded())); - recordsToLoad++; - - new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1, - obtainMessage(EVENT_GET_MSISDN_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_CSIM_LI, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded())); - recordsToLoad++; - - mFh.loadEFTransparent(EF_CSIM_SPN, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded())); - recordsToLoad++; - - mFh.loadEFLinearFixed(EF_CSIM_MDN, 1, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded())); - recordsToLoad++; - - mFh.loadEFTransparent(EF_CSIM_IMSIM, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded())); - recordsToLoad++; - - mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded())); - recordsToLoad++; - - mFh.loadEFTransparent(EF_CSIM_EPRL, - obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded())); - recordsToLoad++; - - // load ISIM records - recordsToLoad += mIsimUiccRecords.fetchIsimRecords(mFh, this); - } - - private int adjstMinDigits (int digits) { - // Per C.S0005 section 2.3.1. - digits += 111; - digits = (digits % 10 == 0)?(digits - 10):digits; - digits = ((digits / 10) % 10 == 0)?(digits - 100):digits; - digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits; - return digits; - } - - private void onGetCSimEprlDone(AsyncResult ar) { - // C.S0065 section 5.2.57 for EFeprl encoding - // C.S0016 section 3.5.5 for PRL format. - byte[] data = (byte[]) ar.result; - if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data)); - - // Only need the first 4 bytes of record - if (data.length > 3) { - int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF); - mPrlVersion = Integer.toString(prlId); - } - if (DBG) log("CSIM PRL version=" + mPrlVersion); - } - - private void setLocaleFromCsim() { - String prefLang = null; - // check EFli then EFpl - prefLang = findBestLanguage(mEFli); - - if (prefLang == null) { - prefLang = findBestLanguage(mEFpl); - } - - if (prefLang != null) { - // check country code from SIM - String imsi = getIMSI(); - String country = null; - if (imsi != null) { - country = MccTable.countryCodeForMcc( - Integer.parseInt(imsi.substring(0,3))); - } - log("Setting locale to " + prefLang + "_" + country); - MccTable.setSystemLocale(mContext, prefLang, country); - } else { - log ("No suitable CSIM selected locale"); - } - } - - private String findBestLanguage(byte[] languages) { - String bestMatch = null; - String[] locales = mContext.getAssets().getLocales(); - - if ((languages == null) || (locales == null)) return null; - - // Each 2-bytes consists of one language - for (int i = 0; (i + 1) < languages.length; i += 2) { - try { - String lang = new String(languages, i, 2, "ISO-8859-1"); - for (int j = 0; j < locales.length; j++) { - if (locales[j] != null && locales[j].length() >= 2 && - locales[j].substring(0, 2).equals(lang)) { - return lang; - } - } - if (bestMatch != null) break; - } catch(java.io.UnsupportedEncodingException e) { - log ("Failed to parse SIM language records"); - } - } - // no match found. return null - return null; - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[CSIM] " + s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[CSIM] " + s); - } - - public String getMdn() { - return mMdn; - } - - public String getMin() { - return mMin; - } - - public String getSid() { - return mHomeSystemId; - } - - public String getNid() { - return mHomeNetworkId; - } - - public String getPrlVersion() { - return mPrlVersion; - } - - public boolean getCsimSpnDisplayCondition() { - return mCsimSpnDisplayCondition; - } - - @Override - public IsimRecords getIsimRecords() { - return mIsimUiccRecords; - } - - @Override - public boolean isProvisioned() { - // If UICC card has CSIM app, look for MDN and MIN field - // to determine if the SIM is provisioned. Otherwise, - // consider the SIM is provisioned. (for case of ordinal - // USIM only UICC.) - // If PROPERTY_TEST_CSIM is defined, bypess provision check - // and consider the SIM is provisioned. - if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) { - return true; - } - - if (mParentCard == null) { - return false; - } - - if (mParentCard.isApplicationOnIcc(AppType.APPTYPE_CSIM) && - ((mMdn == null) || (mMin == null))) { - return false; - } - return true; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java deleted file mode 100644 index 8dd8c2e6c679..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java +++ /dev/null @@ -1,296 +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.cdma; - -import android.content.Context; - -import com.android.internal.telephony.CommandException; -import com.android.internal.telephony.MmiCode; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.util.Log; - -import java.util.regex.Pattern; -import java.util.regex.Matcher; - -/** - * This class can handle Puk code Mmi - * - * {@hide} - * - */ -public final class CdmaMmiCode extends Handler implements MmiCode { - static final String LOG_TAG = "CDMA_MMI"; - - // Constants - - // From TS 22.030 6.5.2 - static final String ACTION_REGISTER = "**"; - - // Supp Service codes from TS 22.030 Annex B - static final String SC_PUK = "05"; - - // Event Constant - - static final int EVENT_SET_COMPLETE = 1; - - // Instance Variables - - CDMAPhone phone; - Context context; - - String action; // ACTION_REGISTER - 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 - - State state = State.PENDING; - CharSequence message; - - // Class Variables - - static Pattern sPatternSuppService = Pattern.compile( - "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"); -/* 1 2 3 4 5 6 7 8 9 10 11 12 - - 1 = Full string up to and including # - 2 = action - 3 = service code - 5 = SIA - 7 = SIB - 9 = SIC - 10 = dialing number -*/ - - static final int MATCH_GROUP_POUND_STRING = 1; - static final int MATCH_GROUP_ACTION = 2; - static final int MATCH_GROUP_SERVICE_CODE = 3; - static final int MATCH_GROUP_SIA = 5; - static final int MATCH_GROUP_SIB = 7; - static final int MATCH_GROUP_SIC = 9; - static final int MATCH_GROUP_PWD_CONFIRM = 11; - static final int MATCH_GROUP_DIALING_NUMBER = 12; - - - // Public Class methods - - /** - * Check if provided string contains Mmi code in it and create corresponding - * Mmi if it does - */ - - public static CdmaMmiCode - newFromDialString(String dialString, CDMAPhone phone) { - Matcher m; - CdmaMmiCode ret = null; - - m = sPatternSuppService.matcher(dialString); - - // Is this formatted like a standard supplementary service code? - if (m.matches()) { - ret = new CdmaMmiCode(phone); - ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); - ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); - ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); - ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); - ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); - ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); - ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); - ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); - - } - - return ret; - } - - // Private Class methods - - /** make empty strings be null. - * Regexp returns empty strings for empty groups - */ - private static String - makeEmptyNull (String s) { - if (s != null && s.length() == 0) return null; - - return s; - } - - // Constructor - - CdmaMmiCode (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() { - // Complete or failed cannot be cancelled - if (state == State.COMPLETE || state == State.FAILED) { - return; - } - - state = State.CANCELLED; - phone.onMMIDone (this); - } - - public boolean isCancelable() { - return false; - } - - // Instance Methods - - /** - * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related - */ - boolean isPukCommand() { - return sc != null && sc.equals(SC_PUK); - } - - boolean isRegister() { - return action != null && action.equals(ACTION_REGISTER); - } - - public boolean isUssdRequest() { - Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode"); - return false; - } - - /** Process a MMI PUK code */ - void - processCode () { - try { - if (isPukCommand()) { - // sia = old PUK - // sib = new PIN - // sic = new PIN - String oldPinOrPuk = sia; - String newPin = sib; - int pinLen = newPin.length(); - if (isRegister()) { - if (!newPin.equals(sic)) { - // password mismatch; return error - handlePasswordError(com.android.internal.R.string.mismatchPin); - } else if (pinLen < 4 || pinLen > 8 ) { - // invalid length - handlePasswordError(com.android.internal.R.string.invalidPin); - } else { - phone.mCM.supplyIccPuk(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } catch (RuntimeException exc) { - state = State.FAILED; - message = context.getText(com.android.internal.R.string.mmiError); - phone.onMMIDone(this); - } - } - - private void handlePasswordError(int res) { - state = State.FAILED; - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - sb.append(context.getText(res)); - message = sb; - phone.onMMIDone(this); - } - - public void - handleMessage (Message msg) { - AsyncResult ar; - - if (msg.what == EVENT_SET_COMPLETE) { - ar = (AsyncResult) (msg.obj); - onSetComplete(ar); - } else { - Log.e(LOG_TAG, "Unexpected reply"); - } - } - // Private instance methods - - private CharSequence getScString() { - if (sc != null) { - if (isPukCommand()) { - return context.getText(com.android.internal.R.string.PinMmi); - } - } - - return ""; - } - - private void - onSetComplete(AsyncResult ar){ - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - if (ar.exception instanceof CommandException) { - CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); - if (err == CommandException.Error.PASSWORD_INCORRECT) { - if (isPukCommand()) { - sb.append(context.getText( - com.android.internal.R.string.badPuk)); - } else { - sb.append(context.getText( - com.android.internal.R.string.passwordIncorrect)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else if (isRegister()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceRegistered)); - } 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/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java deleted file mode 100755 index e6b45f6940e8..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ /dev/null @@ -1,428 +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.PendingIntent.CanceledException; -import android.content.ContentValues; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.SQLException; -import android.os.Message; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Telephony; -import android.provider.Telephony.Sms.Intents; -import android.telephony.SmsCbMessage; -import android.telephony.SmsManager; -import android.telephony.SmsMessage.MessageClass; -import android.telephony.cdma.CdmaSmsCbProgramData; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.SMSDispatcher; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; -import com.android.internal.telephony.SmsStorageMonitor; -import com.android.internal.telephony.SmsUsageMonitor; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.WspTypeDecoder; -import com.android.internal.telephony.cdma.sms.SmsEnvelope; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.HexDump; - -import java.io.ByteArrayOutputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import android.content.res.Resources; - - -final class CdmaSMSDispatcher extends SMSDispatcher { - private static final String TAG = "CDMA"; - - private byte[] mLastDispatchedSmsFingerprint; - private byte[] mLastAcknowledgedSmsFingerprint; - - private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( - com.android.internal.R.bool.config_duplicate_port_omadm_wappush); - - CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor, - SmsUsageMonitor usageMonitor) { - super(phone, storageMonitor, usageMonitor); - mCm.setOnNewCdmaSms(this, EVENT_NEW_SMS, null); - } - - @Override - public void dispose() { - mCm.unSetOnNewCdmaSms(this); - } - - @Override - protected String getFormat() { - return android.telephony.SmsMessage.FORMAT_3GPP2; - } - - private void handleCdmaStatusReport(SmsMessage sms) { - for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { - SmsTracker tracker = deliveryPendingList.get(i); - if (tracker.mMessageRef == sms.messageRef) { - // Found it. Remove from list and broadcast. - deliveryPendingList.remove(i); - PendingIntent intent = tracker.mDeliveryIntent; - Intent fillIn = new Intent(); - fillIn.putExtra("pdu", sms.getPdu()); - fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2); - try { - intent.send(mContext, Activity.RESULT_OK, fillIn); - } catch (CanceledException ex) {} - break; // Only expect to see one tracker matching this message. - } - } - } - - /** - * Dispatch service category program data to the CellBroadcastReceiver app, which filters - * the broadcast alerts to display. - * @param sms the SMS message containing one or more - * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects. - */ - private void handleServiceCategoryProgramData(SmsMessage sms) { - List programDataList = sms.getSmsCbProgramData(); - if (programDataList == null) { - Log.e(TAG, "handleServiceCategoryProgramData: program data list is null!"); - return; - } - - Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION); - intent.putExtra("program_data_list", (CdmaSmsCbProgramData[]) programDataList.toArray()); - dispatch(intent, RECEIVE_SMS_PERMISSION); - } - - /** {@inheritDoc} */ - @Override - public int dispatchMessage(SmsMessageBase smsb) { - - // If sms is null, means there was a parsing error. - if (smsb == null) { - Log.e(TAG, "dispatchMessage: message is null"); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - - String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - if (inEcm.equals("true")) { - return Activity.RESULT_OK; - } - - if (mSmsReceiveDisabled) { - // Device doesn't support receiving SMS, - Log.d(TAG, "Received short message on device which doesn't support " - + "receiving SMS. Ignored."); - return Intents.RESULT_SMS_HANDLED; - } - - SmsMessage sms = (SmsMessage) smsb; - - // Handle CMAS emergency broadcast messages. - if (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType()) { - Log.d(TAG, "Broadcast type message"); - SmsCbMessage message = sms.parseBroadcastSms(); - if (message != null) { - dispatchBroadcastMessage(message); - } - return Intents.RESULT_SMS_HANDLED; - } - - // See if we have a network duplicate SMS. - mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); - if (mLastAcknowledgedSmsFingerprint != null && - Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { - return Intents.RESULT_SMS_HANDLED; - } - // Decode BD stream and set sms variables. - sms.parseSms(); - int teleService = sms.getTeleService(); - boolean handled = false; - - if ((SmsEnvelope.TELESERVICE_VMN == teleService) || - (SmsEnvelope.TELESERVICE_MWI == teleService)) { - // handling Voicemail - int voicemailCount = sms.getNumOfVoicemails(); - Log.d(TAG, "Voicemail count=" + voicemailCount); - // Store the voicemail count in preferences. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( - mContext); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); - editor.apply(); - mPhone.setVoiceMessageWaiting(1, voicemailCount); - handled = true; - } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) || - (SmsEnvelope.TELESERVICE_WEMT == teleService)) && - sms.isStatusReportMessage()) { - handleCdmaStatusReport(sms); - handled = true; - } else if (SmsEnvelope.TELESERVICE_SCPT == teleService) { - handleServiceCategoryProgramData(sms); - handled = true; - } else if ((sms.getUserData() == null)) { - if (false) { - Log.d(TAG, "Received SMS without user data"); - } - handled = true; - } - - if (handled) { - return Intents.RESULT_SMS_HANDLED; - } - - if (!mStorageMonitor.isStorageAvailable() && - sms.getMessageClass() != MessageClass.CLASS_0) { - // It's a storable message and there's no storage available. Bail. - // (See C.S0015-B v2.0 for a description of "Immediate Display" - // messages, which we represent as CLASS_0.) - return Intents.RESULT_SMS_OUT_OF_MEMORY; - } - - if (SmsEnvelope.TELESERVICE_WAP == teleService) { - return processCdmaWapPdu(sms.getUserData(), sms.messageRef, - sms.getOriginatingAddress()); - } - - // Reject (NAK) any messages with teleservice ids that have - // not yet been handled and also do not correspond to the two - // kinds that are processed below. - if ((SmsEnvelope.TELESERVICE_WMT != teleService) && - (SmsEnvelope.TELESERVICE_WEMT != teleService) && - (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) { - return Intents.RESULT_SMS_UNSUPPORTED; - } - - return dispatchNormalMessage(smsb); - } - - /** - * 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 - * @return a result code from {@link Telephony.Sms.Intents}, or - * {@link Activity#RESULT_OK} if the message has been broadcast - * to applications - */ - protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { - int index = 0; - - int msgType = (0xFF & pdu[index++]); - if (msgType != 0) { - Log.w(TAG, "Received a WAP SMS which is not WDP. Discard."); - return Intents.RESULT_SMS_HANDLED; - } - int totalSegments = (0xFF & pdu[index++]); // >= 1 - int segment = (0xFF & pdu[index++]); // >= 0 - - if (segment >= totalSegments) { - Log.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1)); - return Intents.RESULT_SMS_HANDLED; - } - - // Only the first segment contains sourcePort and destination Port - int sourcePort = 0; - int destinationPort = 0; - if (segment == 0) { - //process WDP segment - sourcePort = (0xFF & pdu[index++]) << 8; - sourcePort |= 0xFF & pdu[index++]; - destinationPort = (0xFF & pdu[index++]) << 8; - destinationPort |= 0xFF & pdu[index++]; - // Some carriers incorrectly send duplicate port fields in omadm wap pushes. - // If configured, check for that here - if (mCheckForDuplicatePortsInOmadmWapPush) { - if (checkDuplicatePortOmadmWappush(pdu,index)) { - index = index + 4; // skip duplicate port fields - } - } - } - - // Lookup all other related parts - Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address - + ", src-port = " + sourcePort + ", dst-port = " + destinationPort - + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments); - - // pass the user data portion of the PDU to the shared handler in SMSDispatcher - byte[] userData = new byte[pdu.length - index]; - System.arraycopy(pdu, index, userData, 0, pdu.length - index); - - return processMessagePart(userData, address, referenceNumber, segment, totalSegments, - 0L, destinationPort, true); - } - - /** {@inheritDoc} */ - @Override - protected void sendData(String destAddr, String scAddr, int destPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( - scAddr, destAddr, destPort, data, (deliveryIntent != null)); - sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr); - } - - /** {@inheritDoc} */ - @Override - protected void sendText(String destAddr, String scAddr, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent) { - SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( - scAddr, destAddr, text, (deliveryIntent != null), null); - sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr); - } - - /** {@inheritDoc} */ - @Override - protected TextEncodingDetails calculateLength(CharSequence messageBody, - boolean use7bitOnly) { - return SmsMessage.calculateLength(messageBody, use7bitOnly); - } - - /** {@inheritDoc} */ - @Override - protected void sendNewSubmitPdu(String destinationAddress, String scAddress, - String message, SmsHeader smsHeader, int encoding, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { - UserData uData = new UserData(); - uData.payloadStr = message; - uData.userDataHeader = smsHeader; - if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) { - uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; - } else { // assume UTF-16 - uData.msgEncoding = UserData.ENCODING_UNICODE_16; - } - uData.msgEncodingSet = true; - - /* By setting the statusReportRequested bit only for the - * last message fragment, this will result in only one - * callback to the sender when that last fragment delivery - * has been acknowledged. */ - SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress, - uData, (deliveryIntent != null) && lastPart); - - sendSubmitPdu(submitPdu, sentIntent, deliveryIntent, destinationAddress); - } - - protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, - PendingIntent sentIntent, PendingIntent deliveryIntent, String destAddr) { - if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { - if (sentIntent != null) { - try { - sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); - } catch (CanceledException ex) {} - } - if (false) { - Log.d(TAG, "Block SMS in Emergency Callback mode"); - } - return; - } - sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, destAddr); - } - - /** {@inheritDoc} */ - @Override - protected void sendSms(SmsTracker tracker) { - HashMap map = tracker.mData; - - // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA - byte pdu[] = (byte[]) map.get("pdu"); - - Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); - mCm.sendCdmaSms(pdu, reply); - } - - /** {@inheritDoc} */ - @Override - protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { - String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); - if (inEcm.equals("true")) { - return; - } - - int causeCode = resultToCause(result); - mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response); - - if (causeCode == 0) { - mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; - } - mLastDispatchedSmsFingerprint = null; - } - - private static int resultToCause(int rc) { - switch (rc) { - case Activity.RESULT_OK: - case Intents.RESULT_SMS_HANDLED: - // Cause code is ignored on success. - return 0; - case Intents.RESULT_SMS_OUT_OF_MEMORY: - return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; - case Intents.RESULT_SMS_UNSUPPORTED: - return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; - case Intents.RESULT_SMS_GENERIC_ERROR: - default: - return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; - } - } - - /** - * Optional check to see if the received WapPush is an OMADM notification with erroneous - * extra port fields. - * - Some carriers make this mistake. - * ex: MSGTYPE-TotalSegments-CurrentSegment - * -SourcePortDestPort-SourcePortDestPort-OMADM PDU - * @param origPdu The WAP-WDP PDU segment - * @param index Current Index while parsing the PDU. - * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. - * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. - */ - private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { - index += 4; - byte[] omaPdu = new byte[origPdu.length - index]; - System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); - - WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); - int wspIndex = 2; - - // Process header length field - if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { - return false; - } - - wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field - - // Process content type field - if (pduDecoder.decodeContentType(wspIndex) == false) { - return false; - } - - String mimeType = pduDecoder.getValueString(); - if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { - return true; - } - return false; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java deleted file mode 100755 index 25cd1126ec19..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ /dev/null @@ -1,1751 +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 com.android.internal.telephony.CommandException; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.DataConnectionTracker; -import com.android.internal.telephony.EventLogTags; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.ServiceStateTracker; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.CommandsInterface.RadioState; - -import android.app.AlarmManager; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.database.ContentObserver; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.provider.Settings; -import android.provider.Settings.Secure; -import android.provider.Settings.SettingNotFoundException; -import android.provider.Telephony.Intents; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.cdma.CdmaCellLocation; -import android.text.TextUtils; -import android.util.EventLog; -import android.util.Log; -import android.util.TimeUtils; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -/** - * {@hide} - */ -public class CdmaServiceStateTracker extends ServiceStateTracker { - static final String LOG_TAG = "CDMA"; - - CDMAPhone phone; - CdmaCellLocation cellLoc; - CdmaCellLocation newCellLoc; - - // Min values used to by getOtasp() - private static final String UNACTIVATED_MIN2_VALUE = "000000"; - private static final String UNACTIVATED_MIN_VALUE = "1111110111"; - - // Current Otasp value - int mCurrentOtaspMode = OTASP_UNINITIALIZED; - - /** if time between NITZ updates is less than mNitzUpdateSpacing the update may be ignored. */ - private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10; - private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing", - NITZ_UPDATE_SPACING_DEFAULT); - - /** If mNitzUpdateSpacing hasn't been exceeded but update is > mNitzUpdate do the update */ - private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000; - private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff", - NITZ_UPDATE_DIFF_DEFAULT); - - private boolean mCdmaRoaming = false; - private int mRoamingIndicator; - private boolean mIsInPrl; - private int mDefaultRoamingIndicator; - - /** - * Initially assume no data connection. - */ - protected int mDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE; - protected int mNewDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE; - protected int mRegistrationState = -1; - protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = 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. - */ - protected boolean mNeedFixZone = false; - private int mZoneOffset; - private boolean mZoneDst; - private long mZoneTime; - protected 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 = false; - - /** Wake lock used while setting time of day. */ - private PowerManager.WakeLock mWakeLock; - private static final String WAKELOCK_TAG = "ServiceStateTracker"; - - /** Contains the name of the registered network in CDMA (either ONS or ERI text). */ - protected String mCurPlmn = null; - - protected String mMdn; - protected int mHomeSystemId[] = null; - protected int mHomeNetworkId[] = null; - protected String mMin; - protected String mPrlVersion; - protected boolean mIsMinInfoReady = false; - - private boolean isEriTextLoaded = false; - protected boolean isSubscriptionFromRuim = false; - private CdmaSubscriptionSourceManager mCdmaSSM; - - /* Used only for debugging purposes. */ - private String mRegistrationDeniedReason; - - private ContentResolver cr; - private String currentCarrier = null; - - private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - if (DBG) log("Auto time state changed"); - revertToNitzTime(); - } - }; - - private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - if (DBG) log("Auto time zone state changed"); - revertToNitzTimeZone(); - } - }; - - public CdmaServiceStateTracker(CDMAPhone phone) { - super(); - - this.phone = phone; - cr = phone.getContext().getContentResolver(); - cm = phone.mCM; - ss = new ServiceState(); - newSS = new ServiceState(); - cellLoc = new CdmaCellLocation(); - newCellLoc = new CdmaCellLocation(); - mSignalStrength = new SignalStrength(); - - mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(phone.getContext(), cm, this, - EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); - isSubscriptionFromRuim = (mCdmaSSM.getCdmaSubscriptionSource() == - CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM); - - PowerManager powerManager = - (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); - - cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); - - cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null); - cm.setOnNITZTime(this, EVENT_NITZ_TIME, null); - cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); - - cm.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null); - phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null); - cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null); - - // System setting property AIRPLANE_MODE_ON is set in Settings. - int airplaneMode = Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0); - mDesiredPowerState = ! (airplaneMode > 0); - - cr.registerContentObserver( - Settings.System.getUriFor(Settings.System.AUTO_TIME), true, - mAutoTimeObserver); - cr.registerContentObserver( - Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true, - mAutoTimeZoneObserver); - setSignalStrengthDefaultValues(); - - mNeedToRegForRuimLoaded = true; - } - - public void dispose() { - // Unregister for all events. - cm.unregisterForRadioStateChanged(this); - cm.unregisterForVoiceNetworkStateChanged(this); - phone.getIccCard().unregisterForReady(this); - cm.unregisterForCdmaOtaProvision(this); - phone.unregisterForEriFileLoaded(this); - phone.mIccRecords.unregisterForRecordsLoaded(this); - cm.unSetOnSignalStrengthUpdate(this); - cm.unSetOnNITZTime(this); - cr.unregisterContentObserver(mAutoTimeObserver); - cr.unregisterContentObserver(mAutoTimeZoneObserver); - mCdmaSSM.dispose(this); - cm.unregisterForCdmaPrlChanged(this); - } - - @Override - protected void finalize() { - if (DBG) log("CdmaServiceStateTracker finalized"); - } - - /** - * Registration point for subscription info ready - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - cdmaForSubscriptionInfoReadyRegistrants.add(r); - - if (isMinInfoReady()) { - r.notifyRegistrant(); - } - } - - public void unregisterForSubscriptionInfoReady(Handler h) { - cdmaForSubscriptionInfoReadyRegistrants.remove(h); - } - - /** - * Save current source of cdma subscription - * @param source - 1 for NV, 0 for RUIM - */ - private void saveCdmaSubscriptionSource(int source) { - log("Storing cdma subscription source: " + source); - Secure.putInt(phone.getContext().getContentResolver(), - Secure.CDMA_SUBSCRIPTION_MODE, - source ); - } - - private void getSubscriptionInfoAndStartPollingThreads() { - cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION)); - - // Get Registration Information - pollState(); - } - - @Override - public void handleMessage (Message msg) { - AsyncResult ar; - int[] ints; - String[] strings; - - if (!phone.mIsTheCurrentActivePhone) { - loge("Received message " + msg + "[" + msg.what + "]" + - " while being destroyed. Ignoring."); - return; - } - - switch (msg.what) { - case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: - handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); - break; - - case EVENT_RUIM_READY: - // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST. - // cm.setCurrentPreferredNetworkType(); - - // The RUIM is now ready i.e if it was locked it has been - // unlocked. At this stage, the radio is already powered on. - if (mNeedToRegForRuimLoaded) { - phone.mIccRecords.registerForRecordsLoaded(this, - EVENT_RUIM_RECORDS_LOADED, null); - mNeedToRegForRuimLoaded = false; - } - - if (phone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) { - // Subscription will be read from SIM I/O - if (DBG) log("Receive EVENT_RUIM_READY"); - pollState(); - } else { - if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription."); - getSubscriptionInfoAndStartPollingThreads(); - } - phone.prepareEri(); - break; - - case EVENT_NV_READY: - // For Non-RUIM phones, the subscription information is stored in - // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA - // subscription info. - getSubscriptionInfoAndStartPollingThreads(); - break; - - case EVENT_RADIO_STATE_CHANGED: - if(cm.getRadioState() == RadioState.RADIO_ON) { - handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); - - // Signal strength polling stops when radio is off. - queueNextSignalStrengthPoll(); - } - // This will do nothing in the 'radio not available' case. - setPowerStateToDesired(); - pollState(); - break; - - case EVENT_NETWORK_STATE_CHANGED_CDMA: - pollState(); - break; - - 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. - return; - } - ar = (AsyncResult) msg.obj; - onSignalStrengthResult(ar); - queueNextSignalStrengthPoll(); - - break; - - case EVENT_GET_LOC_DONE_CDMA: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - String states[] = (String[])ar.result; - int baseStationId = -1; - int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG; - int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG; - int systemId = -1; - int networkId = -1; - - if (states.length > 9) { - try { - if (states[4] != null) { - baseStationId = Integer.parseInt(states[4]); - } - if (states[5] != null) { - baseStationLatitude = Integer.parseInt(states[5]); - } - if (states[6] != null) { - baseStationLongitude = Integer.parseInt(states[6]); - } - // Some carriers only return lat-lngs of 0,0 - if (baseStationLatitude == 0 && baseStationLongitude == 0) { - baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG; - baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG; - } - if (states[8] != null) { - systemId = Integer.parseInt(states[8]); - } - if (states[9] != null) { - networkId = Integer.parseInt(states[9]); - } - } catch (NumberFormatException ex) { - loge("error parsing cell location data: " + ex); - } - } - - cellLoc.setCellLocationData(baseStationId, baseStationLatitude, - baseStationLongitude, systemId, networkId); - phone.notifyLocationChanged(); - } - - // Release any temporary cell lock, which could have been - // acquired to allow a single-shot location update. - disableSingleLocationUpdate(); - break; - - case EVENT_POLL_STATE_REGISTRATION_CDMA: - case EVENT_POLL_STATE_OPERATOR_CDMA: - ar = (AsyncResult) msg.obj; - handlePollStateResult(msg.what, ar); - break; - - case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - String cdmaSubscription[] = (String[])ar.result; - if (cdmaSubscription != null && cdmaSubscription.length >= 5) { - mMdn = cdmaSubscription[0]; - parseSidNid(cdmaSubscription[1], cdmaSubscription[2]); - - mMin = cdmaSubscription[3]; - mPrlVersion = cdmaSubscription[4]; - if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn); - - mIsMinInfoReady = true; - - updateOtaspState(); - phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI, - null); - } else { - if (DBG) { - log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription params num=" - + cdmaSubscription.length); - } - } - } - break; - - case EVENT_POLL_SIGNAL_STRENGTH: - // Just poll signal strength...not part of pollState() - - cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); - break; - - case EVENT_NITZ_TIME: - ar = (AsyncResult) msg.obj; - - String nitzString = (String)((Object[])ar.result)[0]; - long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue(); - - setTimeFromNITZString(nitzString, nitzReceiveTime); - break; - - case EVENT_SIGNAL_STRENGTH_UPDATE: - // This is a notification from CommandsInterface.setOnSignalStrengthUpdate. - - ar = (AsyncResult) msg.obj; - - // The radio is telling us about signal strength changes, - // so we don't have to ask it. - dontPollSignalStrength = true; - - onSignalStrengthResult(ar); - break; - - case EVENT_RUIM_RECORDS_LOADED: - updateSpnDisplay(); - break; - - case EVENT_LOCATION_UPDATES_ENABLED: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null)); - } - break; - - case EVENT_ERI_FILE_LOADED: - // Repoll the state once the ERI file has been loaded. - if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling."); - pollState(); - break; - - case EVENT_OTA_PROVISION_STATUS_CHANGE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - ints = (int[]) ar.result; - int otaStatus = ints[0]; - if (otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED - || otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) { - if (DBG) log("EVENT_OTA_PROVISION_STATUS_CHANGE: Complete, Reload MDN"); - cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION)); - } - } - break; - - case EVENT_CDMA_PRL_VERSION_CHANGED: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - ints = (int[]) ar.result; - mPrlVersion = Integer.toString(ints[0]); - } - break; - - default: - super.handleMessage(msg); - break; - } - } - - //***** Private Instance Methods - - private void handleCdmaSubscriptionSource(int newSubscriptionSource) { - log("Subscription Source : " + newSubscriptionSource); - isSubscriptionFromRuim = - (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM); - saveCdmaSubscriptionSource(newSubscriptionSource); - if (!isSubscriptionFromRuim) { - // NV is ready when subscription source is NV - sendMessage(obtainMessage(EVENT_NV_READY)); - } else { - phone.getIccCard().registerForReady(this, EVENT_RUIM_READY, null); - } - } - - @Override - protected void setPowerStateToDesired() { - // If we want it on and it's off, turn it on - if (mDesiredPowerState - && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) { - cm.setRadioPower(true, null); - } else if (!mDesiredPowerState && cm.getRadioState().isOn()) { - DataConnectionTracker dcTracker = phone.mDataConnectionTracker; - - // If it's on and available and we want it off gracefully - powerOffRadioSafely(dcTracker); - } // Otherwise, we're in the desired state - } - - @Override - protected void updateSpnDisplay() { - // mOperatorAlphaLong contains the ERI text - String plmn = ss.getOperatorAlphaLong(); - if (!TextUtils.equals(plmn, mCurPlmn)) { - // Allow A blank plmn, "" to set showPlmn to true. Previously, we - // would set showPlmn to true only if plmn was not empty, i.e. was not - // null and not blank. But this would cause us to incorrectly display - // "No Service". Now showPlmn is set to true for any non null string. - boolean showPlmn = plmn != null; - if (DBG) { - log(String.format("updateSpnDisplay: changed sending intent" + - " showPlmn='%b' plmn='%s'", showPlmn, plmn)); - } - Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Intents.EXTRA_SHOW_SPN, false); - intent.putExtra(Intents.EXTRA_SPN, ""); - intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); - intent.putExtra(Intents.EXTRA_PLMN, plmn); - phone.getContext().sendStickyBroadcast(intent); - } - - mCurPlmn = plmn; - } - - @Override - protected Phone getPhone() { - return phone; - } - - /** - * Determine data network type based on radio technology. - */ - protected void setCdmaTechnology(int radioTech){ - mNewDataConnectionState = radioTechnologyToDataServiceState(radioTech); - newSS.setRadioTechnology(radioTech); - mNewRilRadioTechnology = radioTech; - } - - /** - * Hanlde the PollStateResult message - */ - protected void handlePollStateResultMessage(int what, AsyncResult ar){ - int ints[]; - String states[]; - switch (what) { - case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE. - states = (String[])ar.result; - - int registrationState = 4; //[0] registrationState - int radioTechnology = -1; //[3] radioTechnology - int baseStationId = -1; //[4] baseStationId - //[5] baseStationLatitude - int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG; - //[6] baseStationLongitude - int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG; - int cssIndicator = 0; //[7] init with 0, because it is treated as a boolean - int systemId = 0; //[8] systemId - int networkId = 0; //[9] networkId - int roamingIndicator = -1; //[10] Roaming indicator - int systemIsInPrl = 0; //[11] Indicates if current system is in PRL - int defaultRoamingIndicator = 0; //[12] Is default roaming indicator from PRL - int reasonForDenial = 0; //[13] Denial reason if registrationState = 3 - - if (states.length >= 14) { - try { - if (states[0] != null) { - registrationState = Integer.parseInt(states[0]); - } - if (states[3] != null) { - radioTechnology = Integer.parseInt(states[3]); - } - if (states[4] != null) { - baseStationId = Integer.parseInt(states[4]); - } - if (states[5] != null) { - baseStationLatitude = Integer.parseInt(states[5]); - } - if (states[6] != null) { - baseStationLongitude = Integer.parseInt(states[6]); - } - // Some carriers only return lat-lngs of 0,0 - if (baseStationLatitude == 0 && baseStationLongitude == 0) { - baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG; - baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG; - } - if (states[7] != null) { - cssIndicator = Integer.parseInt(states[7]); - } - if (states[8] != null) { - systemId = Integer.parseInt(states[8]); - } - if (states[9] != null) { - networkId = Integer.parseInt(states[9]); - } - if (states[10] != null) { - roamingIndicator = Integer.parseInt(states[10]); - } - if (states[11] != null) { - systemIsInPrl = Integer.parseInt(states[11]); - } - if (states[12] != null) { - defaultRoamingIndicator = Integer.parseInt(states[12]); - } - if (states[13] != null) { - reasonForDenial = Integer.parseInt(states[13]); - } - } catch (NumberFormatException ex) { - loge("EVENT_POLL_STATE_REGISTRATION_CDMA: error parsing: " + ex); - } - } else { - throw new RuntimeException("Warning! Wrong number of parameters returned from " - + "RIL_REQUEST_REGISTRATION_STATE: expected 14 or more " - + "strings and got " + states.length + " strings"); - } - - mRegistrationState = registrationState; - // When registration state is roaming and TSB58 - // roaming indicator is not in the carrier-specified - // list of ERIs for home system, mCdmaRoaming is true. - mCdmaRoaming = - regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]); - newSS.setState (regCodeToServiceState(registrationState)); - - setCdmaTechnology(radioTechnology); - - newSS.setCssIndicator(cssIndicator); - newSS.setSystemAndNetworkId(systemId, networkId); - mRoamingIndicator = roamingIndicator; - mIsInPrl = (systemIsInPrl == 0) ? false : true; - mDefaultRoamingIndicator = defaultRoamingIndicator; - - - // Values are -1 if not available. - newCellLoc.setCellLocationData(baseStationId, baseStationLatitude, - baseStationLongitude, systemId, networkId); - - if (reasonForDenial == 0) { - mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN; - } else if (reasonForDenial == 1) { - mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH; - } else { - mRegistrationDeniedReason = ""; - } - - if (mRegistrationState == 3) { - if (DBG) log("Registration denied, " + mRegistrationDeniedReason); - } - break; - - case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR - String opNames[] = (String[])ar.result; - - if (opNames != null && opNames.length >= 3) { - // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC - if ((opNames[2] == null) || (opNames[2].length() < 5) - || ("00000".equals(opNames[2]))) { - opNames[2] = SystemProperties.get( - CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000"); - if (DBG) { - log("RIL_REQUEST_OPERATOR.response[2], the numeric, " + - " is bad. Using SystemProperties '" + - CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC + - "'= " + opNames[2]); - } - } - - if (!isSubscriptionFromRuim) { - // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the - // ERI text, so here it is ignored what is coming from the modem. - newSS.setOperatorName(null, opNames[1], opNames[2]); - } else { - newSS.setOperatorName(opNames[0], opNames[1], opNames[2]); - } - } else { - if (DBG) log("EVENT_POLL_STATE_OPERATOR_CDMA: error parsing opNames"); - } - break; - default: - loge("handlePollStateResultMessage: RIL response handle in wrong phone!" - + " Expected CDMA RIL request and get GSM RIL request."); - break; - } - } - - /** - * Handle the result of one of the pollState() - related requests - */ - @Override - protected void handlePollStateResult(int what, AsyncResult ar) { - // Ignore stale requests from last poll. - if (ar.userObj != pollingContext) return; - - if (ar.exception != null) { - CommandException.Error err=null; - - if (ar.exception instanceof CommandException) { - err = ((CommandException)(ar.exception)).getCommandError(); - } - - if (err == CommandException.Error.RADIO_NOT_AVAILABLE) { - // Radio has crashed or turned off. - cancelPollState(); - return; - } - - if (!cm.getRadioState().isOn()) { - // Radio has crashed or turned off. - cancelPollState(); - return; - } - - if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) { - loge("handlePollStateResult: RIL returned an error where it must succeed" - + ar.exception); - } - } else try { - handlePollStateResultMessage(what, ar); - } catch (RuntimeException ex) { - loge("handlePollStateResult: Exception while polling service state. " - + "Probably malformed RIL response." + ex); - } - - pollingContext[0]--; - - if (pollingContext[0] == 0) { - boolean namMatch = false; - if (!isSidsAllZeros() && isHomeSid(newSS.getSystemId())) { - namMatch = true; - } - - // Setting SS Roaming (general) - if (isSubscriptionFromRuim) { - newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS)); - } else { - newSS.setRoaming(mCdmaRoaming); - } - - // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator - newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator); - newSS.setCdmaRoamingIndicator(mRoamingIndicator); - boolean isPrlLoaded = true; - if (TextUtils.isEmpty(mPrlVersion)) { - isPrlLoaded = false; - } - if (!isPrlLoaded) { - newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); - } else if (!isSidsAllZeros()) { - if (!namMatch && !mIsInPrl) { - // Use default - newSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator); - } else if (namMatch && !mIsInPrl) { - newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH); - } else if (!namMatch && mIsInPrl) { - // Use the one from PRL/ERI - newSS.setCdmaRoamingIndicator(mRoamingIndicator); - } else { - // It means namMatch && mIsInPrl - if ((mRoamingIndicator <= 2)) { - newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); - } else { - // Use the one from PRL/ERI - newSS.setCdmaRoamingIndicator(mRoamingIndicator); - } - } - } - - int roamingIndicator = newSS.getCdmaRoamingIndicator(); - newSS.setCdmaEriIconIndex(phone.mEriManager.getCdmaEriIconIndex(roamingIndicator, - mDefaultRoamingIndicator)); - newSS.setCdmaEriIconMode(phone.mEriManager.getCdmaEriIconMode(roamingIndicator, - mDefaultRoamingIndicator)); - - // NOTE: Some operator may require overriding mCdmaRoaming - // (set by the modem), depending on the mRoamingIndicator. - - if (DBG) { - log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator() - + ". mCdmaRoaming = " + mCdmaRoaming + ", isPrlLoaded = " + isPrlLoaded - + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl - + ", mRoamingIndicator = " + mRoamingIndicator - + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator); - } - pollStateDone(); - } - - } - - protected void setSignalStrengthDefaultValues() { - mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false); - } - - /** - * A complete "service state" from our perspective is - * composed of a handful of separate requests to the radio. - * - * We make all of these requests at once, but then abandon them - * and start over again if the radio notifies us that some - * event has changed - */ - protected void - pollState() { - pollingContext = new int[1]; - pollingContext[0] = 0; - - switch (cm.getRadioState()) { - case RADIO_UNAVAILABLE: - newSS.setStateOutOfService(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - mGotCountryCode = false; - - pollStateDone(); - break; - - case RADIO_OFF: - newSS.setStateOff(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - 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 - cm.getOperator( - obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext)); - - pollingContext[0]++; - // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA - cm.getVoiceRegistrationState( - obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext)); - - break; - } - } - - protected void fixTimeZone(String isoCountryCode) { - TimeZone zone = null; - // If the offset is (0, false) and the time zone property - // is set, use the time zone property rather than GMT. - String zoneName = SystemProperties.get(TIMEZONE_PROPERTY); - if (DBG) { - log("fixTimeZone zoneName='" + zoneName + - "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst + - " iso-cc='" + isoCountryCode + - "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode)); - } - if ((mZoneOffset == 0) && (mZoneDst == false) && (zoneName != null) - && (zoneName.length() > 0) - && (Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) < 0)) { - // For NITZ string without time zone, - // need adjust time to reflect default time zone setting - zone = TimeZone.getDefault(); - if (mNeedFixZone) { - long ctm = System.currentTimeMillis(); - long tzOffset = zone.getOffset(ctm); - if (DBG) { - log("fixTimeZone: tzOffset=" + tzOffset + - " ltod=" + TimeUtils.logTimeOfDay(ctm)); - } - if (getAutoTime()) { - long adj = ctm - tzOffset; - if (DBG) log("fixTimeZone: adj ltod=" + TimeUtils.logTimeOfDay(adj)); - setAndBroadcastNetworkSetTime(adj); - } else { - // Adjust the saved NITZ time to account for tzOffset. - mSavedTime = mSavedTime - tzOffset; - if (DBG) log("fixTimeZone: adj mSavedTime=" + mSavedTime); - } - } - if (DBG) log("fixTimeZone: using default TimeZone"); - } else if (isoCountryCode.equals("")) { - // Country code not found. This is likely a test network. - // Get a TimeZone based only on the NITZ parameters (best guess). - zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime); - if (DBG) log("fixTimeZone: using NITZ TimeZone"); - } else { - zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, isoCountryCode); - if (DBG) log("fixTimeZone: using getTimeZone(off, dst, time, iso)"); - } - - mNeedFixZone = false; - - if (zone != null) { - log("fixTimeZone: zone != null zone.getID=" + zone.getID()); - if (getAutoTimeZone()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } else { - log("fixTimeZone: skip changing zone as getAutoTimeZone was false"); - } - saveNitzTimeZone(zone.getID()); - } else { - log("fixTimeZone: zone == null, do nothing for zone"); - } - } - - protected void pollStateDone() { - if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]"); - - boolean hasRegistered = - ss.getState() != ServiceState.STATE_IN_SERVICE - && newSS.getState() == ServiceState.STATE_IN_SERVICE; - - boolean hasDeregistered = - ss.getState() == ServiceState.STATE_IN_SERVICE - && newSS.getState() != ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionAttached = - mDataConnectionState != ServiceState.STATE_IN_SERVICE - && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionDetached = - mDataConnectionState == ServiceState.STATE_IN_SERVICE - && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE; - - boolean hasCdmaDataConnectionChanged = - mDataConnectionState != mNewDataConnectionState; - - boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology; - - boolean hasChanged = !newSS.equals(ss); - - boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming(); - - boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming(); - - boolean hasLocationChanged = !newCellLoc.equals(cellLoc); - - // Add an event log when connection state changes - if (ss.getState() != newSS.getState() || - mDataConnectionState != mNewDataConnectionState) { - EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, - ss.getState(), mDataConnectionState, - newSS.getState(), mNewDataConnectionState); - } - - ServiceState tss; - tss = ss; - ss = newSS; - newSS = tss; - // clean slate for next time - newSS.setStateOutOfService(); - - CdmaCellLocation tcl = cellLoc; - cellLoc = newCellLoc; - newCellLoc = tcl; - - mDataConnectionState = mNewDataConnectionState; - mRilRadioTechnology = mNewRilRadioTechnology; - // this new state has been applied - forget it until we get a new new state - mNewRilRadioTechnology = 0; - - newSS.setStateOutOfService(); // clean slate for next time - - if (hasRadioTechnologyChanged) { - phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, - ServiceState.rilRadioTechnologyToString(mRilRadioTechnology)); - } - - if (hasRegistered) { - mNetworkAttachedRegistrants.notifyRegistrants(); - } - - if (hasChanged) { - if ((cm.getRadioState().isOn()) && (!isSubscriptionFromRuim)) { - String eriText; - // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text - if (ss.getState() == ServiceState.STATE_IN_SERVICE) { - eriText = phone.getCdmaEriText(); - } else { - // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for - // mRegistrationState 0,2,3 and 4 - eriText = phone.getContext().getText( - com.android.internal.R.string.roamingTextSearching).toString(); - } - ss.setOperatorAlphaLong(eriText); - } - - String operatorNumeric; - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA, - ss.getOperatorAlphaLong()); - - String prevOperatorNumeric = - SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, ""); - operatorNumeric = ss.getOperatorNumeric(); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); - - if (operatorNumeric == null) { - if (DBG) log("operatorNumeric is null"); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); - mGotCountryCode = false; - } else { - String isoCountryCode = ""; - String mcc = operatorNumeric.substring(0, 3); - try{ - isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt( - operatorNumeric.substring(0,3))); - } catch ( NumberFormatException ex){ - loge("pollStateDone: countryCodeForMcc error" + ex); - } catch ( StringIndexOutOfBoundsException ex) { - loge("pollStateDone: countryCodeForMcc error" + ex); - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, - isoCountryCode); - mGotCountryCode = true; - - if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric, - mNeedFixZone)) { - fixTimeZone(isoCountryCode); - } - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, - ss.getRoaming() ? "true" : "false"); - - updateSpnDisplay(); - phone.notifyServiceStateChanged(ss); - } - - if (hasCdmaDataConnectionAttached) { - mAttachedRegistrants.notifyRegistrants(); - } - - if (hasCdmaDataConnectionDetached) { - mDetachedRegistrants.notifyRegistrants(); - } - - if (hasCdmaDataConnectionChanged || hasRadioTechnologyChanged) { - phone.notifyDataConnection(null); - } - - if (hasRoamingOn) { - mRoamingOnRegistrants.notifyRegistrants(); - } - - if (hasRoamingOff) { - mRoamingOffRegistrants.notifyRegistrants(); - } - - if (hasLocationChanged) { - phone.notifyLocationChanged(); - } - } - - /** - * Returns a TimeZone object based only on parameters from the NITZ string. - */ - private TimeZone getNitzTimeZone(int offset, boolean dst, long when) { - TimeZone guess = findTimeZone(offset, dst, when); - if (guess == null) { - // Couldn't find a proper timezone. Perhaps the DST data is wrong. - guess = findTimeZone(offset, !dst, when); - } - if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID())); - return guess; - } - - private TimeZone findTimeZone(int offset, boolean dst, long when) { - int rawOffset = offset; - if (dst) { - rawOffset -= 3600000; - } - String[] zones = TimeZone.getAvailableIDs(rawOffset); - TimeZone guess = null; - Date d = new Date(when); - for (String zone : zones) { - TimeZone tz = TimeZone.getTimeZone(zone); - if (tz.getOffset(when) == offset && - tz.inDaylightTime(d) == dst) { - guess = tz; - break; - } - } - - return guess; - } - - /** - * TODO: This code is exactly the same as in GsmServiceStateTracker - * and has a TODO to not poll signal strength if screen is off. - * This code should probably be hoisted to the base class so - * the fix, when added, works for both. - */ - private void - queueNextSignalStrengthPoll() { - if (dontPollSignalStrength) { - // The radio is telling us about signal strength changes - // we don't have to ask it - return; - } - - Message msg; - - msg = obtainMessage(); - msg.what = EVENT_POLL_SIGNAL_STRENGTH; - - // TODO Don't poll signal strength if screen is off - sendMessageDelayed(msg, POLL_PERIOD_MILLIS); - } - - /** - * send signal-strength-changed notification if changed - * Called both for solicited and unsolicited signal strength updates - */ - protected void - onSignalStrengthResult(AsyncResult ar) { - SignalStrength oldSignalStrength = mSignalStrength; - - if (ar.exception != null) { - // Most likely radio is resetting/disconnected change to default values. - setSignalStrengthDefaultValues(); - } else { - int[] ints = (int[])ar.result; - int offset = 2; - int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120; - int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160; - int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120; - int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1; - int evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1; - - //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d", - // cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr)); - mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, - evdoRssi, evdoEcio, evdoSnr, false); - } - - try { - phone.notifySignalStrength(); - } catch (NullPointerException ex) { - loge("onSignalStrengthResult() Phone already destroyed: " + ex - + "SignalStrength not notified"); - } - } - - - protected int radioTechnologyToDataServiceState(int code) { - int retVal = ServiceState.STATE_OUT_OF_SERVICE; - switch(code) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - break; - case 6: // RADIO_TECHNOLOGY_1xRTT - case 7: // RADIO_TECHNOLOGY_EVDO_0 - case 8: // RADIO_TECHNOLOGY_EVDO_A - case 12: // RADIO_TECHNOLOGY_EVDO_B - case 13: // RADIO_TECHNOLOGY_EHRPD - retVal = ServiceState.STATE_IN_SERVICE; - break; - default: - loge("radioTechnologyToDataServiceState: Wrong radioTechnology code."); - break; - } - return(retVal); - } - - /** code is registration state 0-5 from TS 27.007 7.2 */ - protected int - regCodeToServiceState(int code) { - switch (code) { - case 0: // Not searching and not registered - return ServiceState.STATE_OUT_OF_SERVICE; - case 1: - return ServiceState.STATE_IN_SERVICE; - case 2: // 2 is "searching", fall through - case 3: // 3 is "registration denied", fall through - case 4: // 4 is "unknown", not valid in current baseband - return ServiceState.STATE_OUT_OF_SERVICE; - case 5:// 5 is "Registered, roaming" - return ServiceState.STATE_IN_SERVICE; - - default: - loge("regCodeToServiceState: unexpected service state " + code); - return ServiceState.STATE_OUT_OF_SERVICE; - } - } - - public int getCurrentDataConnectionState() { - return mDataConnectionState; - } - - /** - * code is registration state 0-5 from TS 27.007 7.2 - * returns true if registered roam, false otherwise - */ - private boolean - regCodeIsRoaming (int code) { - // 5 is "in service -- roam" - return 5 == code; - } - - /** - * Determine whether a roaming indicator is in the carrier-specified list of ERIs for - * home system - * - * @param roamInd roaming indicator in String - * @return true if the roamInd is in the carrier-specified list of ERIs for home network - */ - private boolean isRoamIndForHomeSystem(String roamInd) { - // retrieve the carrier-specified list of ERIs for home system - String homeRoamIndicators = SystemProperties.get("ro.cdma.homesystem"); - - if (!TextUtils.isEmpty(homeRoamIndicators)) { - // searches through the comma-separated list for a match, - // return true if one is found. - for (String homeRoamInd : homeRoamIndicators.split(",")) { - if (homeRoamInd.equals(roamInd)) { - return true; - } - } - // no matches found against the list! - return false; - } - - // no system property found for the roaming indicators for home system - return false; - } - - /** - * Set roaming state when cdmaRoaming is true and ons is different from spn - * @param cdmaRoaming TS 27.007 7.2 CREG registered roaming - * @param s ServiceState hold current ons - * @return true for roaming state set - */ - private - boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) { - String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty"); - - // NOTE: in case of RUIM we should completely ignore the ERI data file and - // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS) - String onsl = s.getOperatorAlphaLong(); - String onss = s.getOperatorAlphaShort(); - - boolean equalsOnsl = onsl != null && spn.equals(onsl); - boolean equalsOnss = onss != null && spn.equals(onss); - - return cdmaRoaming && !(equalsOnsl || equalsOnss); - } - - - /** - * nitzReceiveTime is time_t that the NITZ time was posted - */ - - private - void setTimeFromNITZString (String nitz, long nitzReceiveTime) - { - // "yy/mm/dd,hh:mm:ss(+/-)tz" - // tz is in number of quarter-hours - - long start = SystemClock.elapsedRealtime(); - if (DBG) { - log("NITZ: " + nitz + "," + nitzReceiveTime + - " start=" + start + " delay=" + (start - nitzReceiveTime)); - } - - try { - /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone - * offset as well (which we won't worry about until later) */ - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - - c.clear(); - c.set(Calendar.DST_OFFSET, 0); - - String[] nitzSubs = nitz.split("[/:,+-]"); - - int year = 2000 + Integer.parseInt(nitzSubs[0]); - c.set(Calendar.YEAR, year); - - // month is 0 based! - int month = Integer.parseInt(nitzSubs[1]) - 1; - c.set(Calendar.MONTH, month); - - int date = Integer.parseInt(nitzSubs[2]); - c.set(Calendar.DATE, date); - - int hour = Integer.parseInt(nitzSubs[3]); - c.set(Calendar.HOUR, hour); - - int minute = Integer.parseInt(nitzSubs[4]); - c.set(Calendar.MINUTE, minute); - - int second = Integer.parseInt(nitzSubs[5]); - c.set(Calendar.SECOND, second); - - boolean sign = (nitz.indexOf('-') == -1); - - int tzOffset = Integer.parseInt(nitzSubs[6]); - - int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7]) - : 0; - - // The zone offset received from NITZ is for current local time, - // so DST correction is already applied. Don't add it again. - // - // tzOffset += dst * 4; - // - // We could unapply it if we wanted the raw offset. - - tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000; - - TimeZone zone = null; - - // As a special extension, the Android emulator appends the name of - // the host computer's timezone to the nitz string. this is zoneinfo - // timezone name of the form Area!Location or Area!Location!SubLocation - // so we need to convert the ! into / - if (nitzSubs.length >= 9) { - String tzname = nitzSubs[8].replace('!','/'); - zone = TimeZone.getTimeZone( tzname ); - } - - String iso = SystemProperties.get(TelephonyProperties.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) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){ - // We got the time before the country or the zone has changed - // 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 (DBG) { - log("NITZ: tzOffset=" + tzOffset + " dst=" + dst + " zone=" + zone.getID() + - " iso=" + iso + " mGotCountryCode=" + mGotCountryCode + - " mNeedFixZone=" + mNeedFixZone); - } - - if (zone != null) { - if (getAutoTimeZone()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } - saveNitzTimeZone(zone.getID()); - } - - String ignore = SystemProperties.get("gsm.ignore-nitz"); - if (ignore != null && ignore.equals("yes")) { - if (DBG) log("NITZ: Not setting clock because gsm.ignore-nitz is set"); - return; - } - - try { - mWakeLock.acquire(); - - /** - * Correct the NITZ time by how long its taken to get here. - */ - long millisSinceNitzReceived - = SystemClock.elapsedRealtime() - nitzReceiveTime; - - if (millisSinceNitzReceived < 0) { - // Sanity check: something is wrong - if (DBG) { - log("NITZ: not setting time, clock has rolled " - + "backwards since NITZ time was received, " - + nitz); - } - return; - } - - if (millisSinceNitzReceived > Integer.MAX_VALUE) { - // If the time is this far off, something is wrong > 24 days! - if (DBG) { - log("NITZ: not setting time, processing has taken " - + (millisSinceNitzReceived / (1000 * 60 * 60 * 24)) - + " days"); - } - return; - } - - // Note: with range checks above, cast to int is safe - c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived); - - if (getAutoTime()) { - /** - * Update system time automatically - */ - long gained = c.getTimeInMillis() - System.currentTimeMillis(); - long timeSinceLastUpdate = SystemClock.elapsedRealtime() - mSavedAtTime; - int nitzUpdateSpacing = Settings.Secure.getInt(cr, - Settings.Secure.NITZ_UPDATE_SPACING, mNitzUpdateSpacing); - int nitzUpdateDiff = Settings.Secure.getInt(cr, - Settings.Secure.NITZ_UPDATE_DIFF, mNitzUpdateDiff); - - if ((mSavedAtTime == 0) || (timeSinceLastUpdate > nitzUpdateSpacing) - || (Math.abs(gained) > nitzUpdateDiff)) { - if (DBG) { - log("NITZ: Auto updating time of day to " + c.getTime() - + " NITZ receive delay=" + millisSinceNitzReceived - + "ms gained=" + gained + "ms from " + nitz); - } - - setAndBroadcastNetworkSetTime(c.getTimeInMillis()); - } else { - if (DBG) { - log("NITZ: ignore, a previous update was " - + timeSinceLastUpdate + "ms ago and gained=" + gained + "ms"); - } - return; - } - } - - /** - * Update properties and save the time we did the update - */ - if (DBG) log("NITZ: update nitz time property"); - SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis())); - mSavedTime = c.getTimeInMillis(); - mSavedAtTime = SystemClock.elapsedRealtime(); - } finally { - long end = SystemClock.elapsedRealtime(); - if (DBG) log("NITZ: end=" + end + " dur=" + (end - start)); - mWakeLock.release(); - } - } catch (RuntimeException ex) { - loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex); - } - } - - private boolean getAutoTime() { - try { - return Settings.System.getInt(cr, Settings.System.AUTO_TIME) > 0; - } catch (SettingNotFoundException snfe) { - return true; - } - } - - private boolean getAutoTimeZone() { - try { - return Settings.System.getInt(cr, Settings.System.AUTO_TIME_ZONE) > 0; - } catch (SettingNotFoundException snfe) { - return true; - } - } - - private void saveNitzTimeZone(String zoneId) { - mSavedTimeZone = zoneId; - } - - /** - * Set the timezone and send out a sticky broadcast so the system can - * determine if the timezone was set by the carrier. - * - * @param zoneId timezone set by carrier - */ - private void setAndBroadcastNetworkSetTimeZone(String zoneId) { - if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId); - AlarmManager alarm = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - alarm.setTimeZone(zoneId); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time-zone", zoneId); - phone.getContext().sendStickyBroadcast(intent); - } - - /** - * Set the time and Send out a sticky broadcast so the system can determine - * if the time was set by the carrier. - * - * @param time time set by network - */ - private void setAndBroadcastNetworkSetTime(long time) { - if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms"); - SystemClock.setCurrentTimeMillis(time); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time", time); - phone.getContext().sendStickyBroadcast(intent); - } - - private void revertToNitzTime() { - if (Settings.System.getInt(cr, Settings.System.AUTO_TIME, 0) == 0) { - return; - } - if (DBG) { - log("revertToNitzTime: mSavedTime=" + mSavedTime + " mSavedAtTime=" + mSavedAtTime); - } - if (mSavedTime != 0 && mSavedAtTime != 0) { - setAndBroadcastNetworkSetTime(mSavedTime - + (SystemClock.elapsedRealtime() - mSavedAtTime)); - } - } - - private void revertToNitzTimeZone() { - if (Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME_ZONE, 0) == 0) { - return; - } - if (DBG) log("revertToNitzTimeZone: tz='" + mSavedTimeZone); - if (mSavedTimeZone != null) { - setAndBroadcastNetworkSetTimeZone(mSavedTimeZone); - } - } - - protected boolean isSidsAllZeros() { - if (mHomeSystemId != null) { - for (int i=0; i < mHomeSystemId.length; i++) { - if (mHomeSystemId[i] != 0) { - return false; - } - } - } - return true; - } - - /** - * Check whether a specified system ID that matches one of the home system IDs. - */ - private boolean isHomeSid(int sid) { - if (mHomeSystemId != null) { - for (int i=0; i < mHomeSystemId.length; i++) { - if (sid == mHomeSystemId[i]) { - return true; - } - } - } - return false; - } - - /** - * @return true if phone is camping on a technology - * that could support voice and data simultaneously. - */ - public boolean isConcurrentVoiceAndDataAllowed() { - // 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; - } - - public String getMdnNumber() { - return mMdn; - } - - public String getCdmaMin() { - return mMin; - } - - /** Returns null if NV is not yet ready */ - public String getPrlVersion() { - return mPrlVersion; - } - - /** - * Returns IMSI as MCC + MNC + MIN - */ - String getImsi() { - // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props. - String operatorNumeric = SystemProperties.get( - TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, ""); - - if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) { - return (operatorNumeric + getCdmaMin()); - } else { - return null; - } - } - - /** - * Check if subscription data has been assigned to mMin - * - * return true if MIN info is ready; false otherwise. - */ - public boolean isMinInfoReady() { - return mIsMinInfoReady; - } - - /** - * Returns OTASP_UNKNOWN, OTASP_NEEDED or OTASP_NOT_NEEDED - */ - int getOtasp() { - int provisioningState; - if (mMin == null || (mMin.length() < 6)) { - if (DBG) log("getOtasp: bad mMin='" + mMin + "'"); - provisioningState = OTASP_UNKNOWN; - } else { - if ((mMin.equals(UNACTIVATED_MIN_VALUE) - || mMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE)) - || SystemProperties.getBoolean("test_cdma_setup", false)) { - provisioningState = OTASP_NEEDED; - } else { - provisioningState = OTASP_NOT_NEEDED; - } - } - if (DBG) log("getOtasp: state=" + provisioningState); - return provisioningState; - } - - @Override - protected void hangupAndPowerOff() { - // hang up all active voice calls - phone.mCT.ringingCall.hangupIfAlive(); - phone.mCT.backgroundCall.hangupIfAlive(); - phone.mCT.foregroundCall.hangupIfAlive(); - cm.setRadioPower(false, null); - } - - protected void parseSidNid (String sidStr, String nidStr) { - if (sidStr != null) { - String[] sid = sidStr.split(","); - mHomeSystemId = new int[sid.length]; - for (int i = 0; i < sid.length; i++) { - try { - mHomeSystemId[i] = Integer.parseInt(sid[i]); - } catch (NumberFormatException ex) { - loge("error parsing system id: " + ex); - } - } - } - if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr); - - if (nidStr != null) { - String[] nid = nidStr.split(","); - mHomeNetworkId = new int[nid.length]; - for (int i = 0; i < nid.length; i++) { - try { - mHomeNetworkId[i] = Integer.parseInt(nid[i]); - } catch (NumberFormatException ex) { - loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex); - } - } - } - if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr); - } - - protected void updateOtaspState() { - int otaspMode = getOtasp(); - int oldOtaspMode = mCurrentOtaspMode; - mCurrentOtaspMode = otaspMode; - - // Notify apps subscription info is ready - if (cdmaForSubscriptionInfoReadyRegistrants != null) { - if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()"); - cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants(); - } - if (oldOtaspMode != mCurrentOtaspMode) { - if (DBG) { - log("CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" + - oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode); - } - phone.notifyOtaspChanged(mCurrentOtaspMode); - } - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[CdmaSST] " + s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[CdmaSST] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("CdmaServiceStateTracker extends:"); - super.dump(fd, pw, args); - pw.println(" phone=" + phone); - pw.println(" cellLoc=" + cellLoc); - pw.println(" newCellLoc=" + newCellLoc); - pw.println(" mCurrentOtaspMode=" + mCurrentOtaspMode); - pw.println(" mCdmaRoaming=" + mCdmaRoaming); - pw.println(" mRoamingIndicator=" + mRoamingIndicator); - pw.println(" mIsInPrl=" + mIsInPrl); - pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator); - pw.println(" mDataConnectionState=" + mDataConnectionState); - pw.println(" mNewDataConnectionState=" + mNewDataConnectionState); - pw.println(" mRegistrationState=" + mRegistrationState); - pw.println(" mNeedFixZone=" + mNeedFixZone); - pw.println(" mZoneOffset=" + mZoneOffset); - pw.println(" mZoneDst=" + mZoneDst); - pw.println(" mZoneTime=" + mZoneTime); - pw.println(" mGotCountryCode=" + mGotCountryCode); - pw.println(" mSavedTimeZone=" + mSavedTimeZone); - pw.println(" mSavedTime=" + mSavedTime); - pw.println(" mSavedAtTime=" + mSavedAtTime); - pw.println(" mNeedToRegForRuimLoaded=" + mNeedToRegForRuimLoaded); - pw.println(" mWakeLock=" + mWakeLock); - pw.println(" mCurPlmn=" + mCurPlmn); - pw.println(" mMdn=" + mMdn); - pw.println(" mHomeSystemId=" + mHomeSystemId); - pw.println(" mHomeNetworkId=" + mHomeNetworkId); - pw.println(" mMin=" + mMin); - pw.println(" mPrlVersion=" + mPrlVersion); - pw.println(" mIsMinInfoReady=" + mIsMinInfoReady); - pw.println(" isEriTextLoaded=" + isEriTextLoaded); - pw.println(" isSubscriptionFromRuim=" + isSubscriptionFromRuim); - pw.println(" mCdmaSSM=" + mCdmaSSM); - pw.println(" mRegistrationDeniedReason=" + mRegistrationDeniedReason); - pw.println(" currentCarrier=" + currentCarrier); - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java deleted file mode 100644 index 80af9d45f0d2..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.RILConstants; - -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.provider.Settings; -import android.util.Log; - -/** - * Class that handles the CDMA subscription source changed events from RIL - */ -public class CdmaSubscriptionSourceManager extends Handler { - static final String LOG_TAG = "CDMA"; - private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1; - private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE = 2; - private static final int EVENT_RADIO_ON = 3; - - public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1; - public static final int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM */ - public static final int SUBSCRIPTION_FROM_NV = 1; /* CDMA subscription from NV */ - public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV; - - private static CdmaSubscriptionSourceManager sInstance; - private static final Object sReferenceCountMonitor = new Object(); - private static int sReferenceCount = 0; - - // ***** Instance Variables - private CommandsInterface mCM; - private Context mContext; - private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList(); - - // Type of CDMA subscription source - private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV); - - // Constructor - private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) { - mContext = context; - mCM = ci; - mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); - mCM.registerForOn(this, EVENT_RADIO_ON, null); - int subscriptionSource = getDefaultCdmaSubscriptionSource(); - mCdmaSubscriptionSource.set(subscriptionSource); - } - - /** - * This function creates a single instance of this class - * - * @return object of type CdmaSubscriptionSourceManager - */ - public static CdmaSubscriptionSourceManager getInstance(Context context, - CommandsInterface ci, Handler h, int what, Object obj) { - synchronized (sReferenceCountMonitor) { - if (null == sInstance) { - sInstance = new CdmaSubscriptionSourceManager(context, ci); - } - sInstance.sReferenceCount++; - } - sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj); - return sInstance; - } - - /** - * Unregisters for the registered event with RIL - */ - public void dispose(Handler h) { - mCdmaSubscriptionSourceChangedRegistrants.remove(h); - synchronized (sReferenceCountMonitor) { - sReferenceCount--; - if (sReferenceCount <= 0) { - mCM.unregisterForCdmaSubscriptionChanged(this); - mCM.unregisterForOn(this); - sInstance = null; - } - } - } - - /* - * (non-Javadoc) - * @see android.os.Handler#handleMessage(android.os.Message) - */ - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - switch (msg.what) { - case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: - case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE: - { - log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what); - ar = (AsyncResult) msg.obj; - handleGetCdmaSubscriptionSource(ar); - } - break; - case EVENT_RADIO_ON: { - mCM.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE)); - } - break; - default: - super.handleMessage(msg); - } - } - - /** - * Returns the current CDMA subscription source value - * @return CDMA subscription source value - */ - public int getCdmaSubscriptionSource() { - return mCdmaSubscriptionSource.get(); - } - - /** - * Gets the default CDMA subscription source - * - * @return Default CDMA subscription source from Settings DB if present. - */ - private int getDefaultCdmaSubscriptionSource() { - // Get the default value from the Settings - int subscriptionSource = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION); - return subscriptionSource; - } - - /** - * Clients automatically register for CDMA subscription source changed event - * when they get an instance of this object. - */ - private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - mCdmaSubscriptionSourceChangedRegistrants.add(r); - } - - /** - * Handles the call to get the subscription source - * - * @param ar AsyncResult object that contains the result of get CDMA - * subscription source call - */ - private void handleGetCdmaSubscriptionSource(AsyncResult ar) { - if ((ar.exception == null) && (ar.result != null)) { - int newSubscriptionSource = ((int[]) ar.result)[0]; - - if (newSubscriptionSource != mCdmaSubscriptionSource.get()) { - log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> " - + newSubscriptionSource); - mCdmaSubscriptionSource.set(newSubscriptionSource); - - // Notify registrants of the new CDMA subscription source - mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null, - null, null)); - } - } else { - // GET_CDMA_SUBSCRIPTION is returning Failure. Probably - // because modem created GSM Phone. If modem created - // GSMPhone, then PhoneProxy will trigger a change in - // Phone objects and this object will be destroyed. - logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception - + ", result: " + ar.result); - } - } - - private void log(String s) { - Log.d(LOG_TAG, "[CdmaSSM] " + s); - } - - private void loge(String s) { - Log.e(LOG_TAG, "[CdmaSSM] " + s); - } - - private void logw(String s) { - Log.w(LOG_TAG, "[CdmaSSM] " + s); - } - -} diff --git a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java deleted file mode 100644 index 3e5d37e39b59..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; - -public final class EriInfo { - - public static final int ROAMING_INDICATOR_ON = 0; - public static final int ROAMING_INDICATOR_OFF = 1; - public static final int ROAMING_INDICATOR_FLASH = 2; - - public static final int ROAMING_ICON_MODE_NORMAL = 0; - public static final int ROAMING_ICON_MODE_FLASH = 1; - - public int mRoamingIndicator; - public int mIconIndex; - public int mIconMode; - public String mEriText; - public int mCallPromptId; - public int mAlertId; - - public EriInfo (int roamingIndicator, int iconIndex, int iconMode, String eriText, - int callPromptId, int alertId) { - - this.mRoamingIndicator = roamingIndicator; - this.mIconIndex = iconIndex; - this.mIconMode = iconMode; - this.mEriText = eriText; - this.mCallPromptId = callPromptId; - this.mAlertId = alertId; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java deleted file mode 100644 index 1bcc90a07063..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; -import android.os.Message; -import android.util.Log; -import android.util.Xml; - -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.util.XmlUtils; - - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.HashMap; - -/** - * EriManager loads the ERI file definitions and manages the CDMA roaming information. - * - */ -public final class EriManager { - - class EriFile { - - public int mVersionNumber; // File version number - public int mNumberOfEriEntries; // Number of entries - public int mEriFileType; // Eri Phase 0/1 - //public int mNumberOfIconImages; // reserved for future use - //public int mIconImageType; // reserved for future use - public String[] mCallPromptId; // reserved for future use - public HashMap mRoamIndTable; // Roaming Indicator Table - - public EriFile() { - this.mVersionNumber = -1; - this.mNumberOfEriEntries = 0; - this.mEriFileType = -1; - this.mCallPromptId = new String[] { "", "", "" }; - this.mRoamIndTable = new HashMap(); - } - } - - class EriDisplayInformation { - public int mEriIconIndex; - public int mEriIconMode; - public String mEriIconText; - - public EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) { - mEriIconIndex = eriIconIndex; - mEriIconMode = eriIconMode; - mEriIconText = eriIconText; - } - -// public void setParameters(int eriIconIndex, int eriIconMode, String eriIconText){ -// this.mEriIconIndex = eriIconIndex; -// this.mEriIconMode = eriIconMode; -// this.mEriIconText = eriIconText; -// } - - @Override - public String toString() { - return "EriDisplayInformation: {" + " IconIndex: " + mEriIconIndex + " EriIconMode: " - + mEriIconMode + " EriIconText: " + mEriIconText + " }"; - } - } - - private static final String LOG_TAG = "CDMA"; - private static final boolean DBG = true; - private static final boolean VDBG = false; - - public static final int ERI_FROM_XML = 0; - public static final int ERI_FROM_FILE_SYSTEM = 1; - public static final int ERI_FROM_MODEM = 2; - - private PhoneBase mPhone; - private Context mContext; - private int mEriFileSource = ERI_FROM_XML; - private boolean isEriFileLoaded; - private EriFile mEriFile; - - public EriManager(PhoneBase phone, Context context, int eriFileSource) { - this.mPhone = phone; - this.mContext = context; - this.mEriFileSource = eriFileSource; - this.mEriFile = new EriFile(); - } - - public void dispose() { - mEriFile = new EriFile(); - isEriFileLoaded = false; - } - - - public void loadEriFile() { - switch (mEriFileSource) { - case ERI_FROM_MODEM: - loadEriFileFromModem(); - break; - - case ERI_FROM_FILE_SYSTEM: - loadEriFileFromFileSystem(); - break; - - case ERI_FROM_XML: - default: - loadEriFileFromXml(); - break; - } - } - - /** - * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK - * - * In this case the ERI file can be updated from the Phone Support Tool available - * from the Chipset vendor - */ - private void loadEriFileFromModem() { - // NOT IMPLEMENTED, Chipset vendor/Operator specific - } - - /** - * Load the ERI file from a File System file - * - * In this case the a Phone Support Tool to update the ERI file must be provided - * to the Operator - */ - private void loadEriFileFromFileSystem() { - // NOT IMPLEMENTED, Chipset vendor/Operator specific - } - - /** - * Load the ERI file from the application framework resources encoded in XML - * - */ - private void loadEriFileFromXml() { - XmlPullParser parser = null; - FileInputStream stream = null; - Resources r = mContext.getResources(); - - try { - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: check for alternate file"); - stream = new FileInputStream( - r.getString(com.android.internal.R.string.alternate_eri_file)); - parser = Xml.newPullParser(); - parser.setInput(stream, null); - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: opened alternate file"); - } catch (FileNotFoundException e) { - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no alternate file"); - parser = null; - } catch (XmlPullParserException e) { - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no parser for alternate file"); - parser = null; - } - - if (parser == null) { - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: open normal file"); - parser = r.getXml(com.android.internal.R.xml.eri); - } - - try { - XmlUtils.beginDocument(parser, "EriFile"); - mEriFile.mVersionNumber = Integer.parseInt( - parser.getAttributeValue(null, "VersionNumber")); - mEriFile.mNumberOfEriEntries = Integer.parseInt( - parser.getAttributeValue(null, "NumberOfEriEntries")); - mEriFile.mEriFileType = Integer.parseInt( - parser.getAttributeValue(null, "EriFileType")); - - int parsedEriEntries = 0; - while(true) { - XmlUtils.nextElement(parser); - String name = parser.getName(); - if (name == null) { - if (parsedEriEntries != mEriFile.mNumberOfEriEntries) - Log.e(LOG_TAG, "Error Parsing ERI file: " + mEriFile.mNumberOfEriEntries - + " defined, " + parsedEriEntries + " parsed!"); - break; - } else if (name.equals("CallPromptId")) { - int id = Integer.parseInt(parser.getAttributeValue(null, "Id")); - String text = parser.getAttributeValue(null, "CallPromptText"); - if (id >= 0 && id <= 2) { - mEriFile.mCallPromptId[id] = text; - } else { - Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId"); - } - - } else if (name.equals("EriInfo")) { - int roamingIndicator = Integer.parseInt( - parser.getAttributeValue(null, "RoamingIndicator")); - int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex")); - int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode")); - String eriText = parser.getAttributeValue(null, "EriText"); - int callPromptId = Integer.parseInt( - parser.getAttributeValue(null, "CallPromptId")); - int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId")); - parsedEriEntries++; - mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator, - iconIndex, iconMode, eriText, callPromptId, alertId)); - } - } - - if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: eri parsing successful, file loaded"); - isEriFileLoaded = true; - - } catch (Exception e) { - Log.e(LOG_TAG, "Got exception while loading ERI file.", e); - } finally { - if (parser instanceof XmlResourceParser) { - ((XmlResourceParser)parser).close(); - } - try { - if (stream != null) { - stream.close(); - } - } catch (IOException e) { - // Ignore - } - } - } - - /** - * Returns the version of the ERI file - * - */ - public int getEriFileVersion() { - return mEriFile.mVersionNumber; - } - - /** - * Returns the number of ERI entries parsed - * - */ - public int getEriNumberOfEntries() { - return mEriFile.mNumberOfEriEntries; - } - - /** - * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1) - * - */ - public int getEriFileType() { - return mEriFile.mEriFileType; - } - - /** - * Returns if the ERI file has been loaded - * - */ - public boolean isEriFileLoaded() { - return isEriFileLoaded; - } - - /** - * Returns the EriInfo record associated with roamingIndicator - * or null if the entry is not found - */ - private EriInfo getEriInfo(int roamingIndicator) { - if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) { - return mEriFile.mRoamIndTable.get(roamingIndicator); - } else { - return null; - } - } - - private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){ - EriDisplayInformation ret; - - // Carrier can use eri.xml to customize any built-in roaming display indications - if (isEriFileLoaded) { - EriInfo eriInfo = getEriInfo(roamInd); - if (eriInfo != null) { - if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file"); - ret = new EriDisplayInformation( - eriInfo.mIconIndex, - eriInfo.mIconMode, - eriInfo.mEriText); - return ret; - } - } - - switch (roamInd) { - // Handling the standard roaming indicator (non-ERI) - case EriInfo.ROAMING_INDICATOR_ON: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_ON, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText0).toString()); - break; - - case EriInfo.ROAMING_INDICATOR_OFF: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_OFF, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText1).toString()); - break; - - case EriInfo.ROAMING_INDICATOR_FLASH: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_FLASH, - EriInfo.ROAMING_ICON_MODE_FLASH, - mContext.getText(com.android.internal.R.string.roamingText2).toString()); - break; - - - // Handling the standard ERI - case 3: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText3).toString()); - break; - - case 4: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText4).toString()); - break; - - case 5: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText5).toString()); - break; - - case 6: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText6).toString()); - break; - - case 7: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText7).toString()); - break; - - case 8: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText8).toString()); - break; - - case 9: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText9).toString()); - break; - - case 10: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText10).toString()); - break; - - case 11: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText11).toString()); - break; - - case 12: - ret = new EriDisplayInformation( - roamInd, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal.R.string.roamingText12).toString()); - break; - - // Handling the non standard Enhanced Roaming Indicator (roamInd > 63) - default: - if (!isEriFileLoaded) { - // ERI file NOT loaded - if (DBG) Log.d(LOG_TAG, "ERI File not loaded"); - if(defRoamInd > 2) { - if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd > 2 ...flashing"); - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_FLASH, - EriInfo.ROAMING_ICON_MODE_FLASH, - mContext.getText(com.android.internal - .R.string.roamingText2).toString()); - } else { - if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd <= 2"); - switch (defRoamInd) { - case EriInfo.ROAMING_INDICATOR_ON: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_ON, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal - .R.string.roamingText0).toString()); - break; - - case EriInfo.ROAMING_INDICATOR_OFF: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_OFF, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal - .R.string.roamingText1).toString()); - break; - - case EriInfo.ROAMING_INDICATOR_FLASH: - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_FLASH, - EriInfo.ROAMING_ICON_MODE_FLASH, - mContext.getText(com.android.internal - .R.string.roamingText2).toString()); - break; - - default: - ret = new EriDisplayInformation(-1, -1, "ERI text"); - } - } - } else { - // ERI file loaded - EriInfo eriInfo = getEriInfo(roamInd); - EriInfo defEriInfo = getEriInfo(defRoamInd); - if (eriInfo == null) { - if (VDBG) { - Log.v(LOG_TAG, "ERI roamInd " + roamInd - + " not found in ERI file ...using defRoamInd " + defRoamInd); - } - if(defEriInfo == null) { - Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd - + " not found in ERI file ...on"); - ret = new EriDisplayInformation( - EriInfo.ROAMING_INDICATOR_ON, - EriInfo.ROAMING_ICON_MODE_NORMAL, - mContext.getText(com.android.internal - .R.string.roamingText0).toString()); - - } else { - if (VDBG) { - Log.v(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file"); - } - ret = new EriDisplayInformation( - defEriInfo.mIconIndex, - defEriInfo.mIconMode, - defEriInfo.mEriText); - } - } else { - if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file"); - ret = new EriDisplayInformation( - eriInfo.mIconIndex, - eriInfo.mIconMode, - eriInfo.mEriText); - } - } - break; - } - if (VDBG) Log.v(LOG_TAG, "Displaying ERI " + ret.toString()); - return ret; - } - - public int getCdmaEriIconIndex(int roamInd, int defRoamInd){ - return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex; - } - - public int getCdmaEriIconMode(int roamInd, int defRoamInd){ - return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode; - } - - public String getCdmaEriText(int roamInd, int defRoamInd){ - return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java deleted file mode 100644 index f440935a2f3e..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java +++ /dev/null @@ -1,89 +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.os.*; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -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.PhoneBase; -import com.android.internal.telephony.PhoneProxy; - -import java.util.ArrayList; - -/** - * {@hide} - */ -public final class RuimFileHandler extends IccFileHandler { - static final String LOG_TAG = "CDMA"; - - //***** Instance Variables - - //***** Constructor - public RuimFileHandler(IccCard card, String aid, CommandsInterface ci) { - super(card, aid, ci); - } - - protected void finalize() { - Log.d(LOG_TAG, "RuimFileHandler finalized"); - } - - //***** Overridden from IccFileHandler - - @Override - public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset, - int length, Message onLoaded) { - Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0, - onLoaded); - - mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, "img", 0, 0, - GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, - mAid, response); - } - - @Override - public void handleMessage(Message msg) { - - super.handleMessage(msg); - } - - protected String getEFPath(int efid) { - switch(efid) { - case EF_SMS: - case EF_CST: - case EF_RUIM_SPN: - return MF_SIM + DF_CDMA; - } - return getCommonIccEFPath(efid); - } - - protected void logd(String msg) { - Log.d(LOG_TAG, "[RuimFileHandler] " + msg); - } - - protected void loge(String msg) { - Log.e(LOG_TAG, "[RuimFileHandler] " + msg); - } - -} diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java deleted file mode 100644 index 04ee2dd83009..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -** 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; - -import java.util.concurrent.atomic.AtomicBoolean; - -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.IccPhoneBookInterfaceManager; - -/** - * RuimPhoneBookInterfaceManager to provide an inter-process communication to - * access ADN-like SIM records. - */ - - -public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager { - static final String LOG_TAG = "CDMA"; - - public RuimPhoneBookInterfaceManager(CDMAPhone phone) { - super(phone); - adnCache = phone.mIccRecords.getAdnCache(); - //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy - } - - public void dispose() { - super.dispose(); - } - - protected void finalize() { - try { - super.finalize(); - } catch (Throwable throwable) { - Log.e(LOG_TAG, "Error while finalizing:", throwable); - } - if(DBG) Log.d(LOG_TAG, "RuimPhoneBookInterfaceManager finalized"); - } - - public int[] getAdnRecordsSize(int efid) { - if (DBG) logd("getAdnRecordsSize: efid=" + efid); - synchronized(mLock) { - checkThread(); - recordSize = new int[3]; - - //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling - AtomicBoolean status = new AtomicBoolean(false); - Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status); - - phone.getIccFileHandler().getEFLinearRecordSize(efid, response); - waitForResult(status); - } - - return recordSize; - } - - 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 deleted file mode 100755 index 2fefa3f53e0a..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ /dev/null @@ -1,461 +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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.SystemProperties; -import android.util.Log; - -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.IccRefreshResponse; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.MccTable; - -// 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.IccUtils; -import com.android.internal.telephony.PhoneProxy; - - -/** - * {@hide} - */ -public final class RuimRecords extends IccRecords { - static final String LOG_TAG = "CDMA"; - - private static final boolean DBG = true; - private boolean m_ota_commited=false; - - // ***** Instance Variables - - private String mImsi; - private String mMyMobileNumber; - private String mMin2Min1; - - private String mPrlVersion; - - // ***** Event Constants - - private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; - 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; - private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10; - private static final int EVENT_UPDATE_DONE = 14; - private static final int EVENT_GET_SST_DONE = 17; - private static final int EVENT_GET_ALL_SMS_DONE = 18; - private static final int EVENT_MARK_SMS_READ_DONE = 19; - - 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; - - - public RuimRecords(IccCard card, Context c, CommandsInterface ci) { - super(card, c, ci); - - adnCache = new AdnRecordCache(mFh); - - recordsRequested = false; // No load request is made till SIM ready - - // recordsToLoad is set to 0 because no requests are made yet - recordsToLoad = 0; - - mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - // NOTE the EVENT_SMS_ON_RUIM is not registered - mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null); - - // Start off by setting empty state - onRadioOffOrNotAvailable(); - - } - - @Override - public void dispose() { - if (DBG) log("Disposing RuimRecords " + this); - //Unregister for all events - mCi.unregisterForOffOrNotAvailable( this); - mCi.unregisterForIccRefresh(this); - super.dispose(); - } - - @Override - protected void finalize() { - if(DBG) log("RuimRecords finalized"); - } - - @Override - protected void onRadioOffOrNotAvailable() { - countVoiceMessages = 0; - mncLength = UNINITIALIZED; - iccid = null; - - adnCache.reset(); - - // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and - // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA - // devices have RUIM, these properties should keep the original - // values, e.g. build time settings, when there is no RUIM but - // set new values when RUIM is available and loaded. - - // 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 String getMdnNumber() { - return mMyMobileNumber; - } - - public String getCdmaMin() { - return mMin2Min1; - } - - /** Returns null if RUIM is not yet ready */ - public String getPrlVersion() { - return mPrlVersion; - } - - @Override - public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){ - // In CDMA this is Operator/OEM dependent - AsyncResult.forMessage((onComplete)).exception = - new IccException("setVoiceMailNumber not implemented"); - onComplete.sendToTarget(); - loge("method setVoiceMailNumber is not implemented"); - } - - /** - * 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 - */ - @Override - public void onRefresh(boolean fileChanged, int[] fileList) { - if (fileChanged) { - // A future optimization would be to inspect fileList and - // only reload those files that we care about. For now, - // just re-fetch all RUIM records that we cache. - fetchRuimRecords(); - } - } - - /** - * Returns the 5 or 6 digit MCC/MNC of the operator that - * provided the RUIM card. Returns null of RUIM is not yet ready - */ - public String getRUIMOperatorNumeric() { - if (mImsi == null) { - return null; - } - - if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) { - // Length = length of MCC + length of MNC - // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) - return mImsi.substring(0, 3 + mncLength); - } - - // Guess the MNC length based on the MCC if we don't - // have a valid value in ef[ad] - - int mcc = Integer.parseInt(mImsi.substring(0,3)); - return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - byte data[]; - - boolean isRecordLoadResponse = false; - - if (mDestroyed) { - loge("Received message " + msg + - "[" + msg.what + "] while being destroyed. Ignoring."); - return; - } - - try { switch (msg.what) { - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - onRadioOffOrNotAvailable(); - break; - - case EVENT_GET_DEVICE_IDENTITY_DONE: - log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received"); - break; - - /* IO events */ - case EVENT_GET_IMSI_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - loge("Exception querying IMSI, Exception:" + ar.exception); - break; - } - - mImsi = (String) ar.result; - - // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more - // than 15 (and usually 15). - if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) { - loge("invalid IMSI " + mImsi); - mImsi = null; - } - - log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx"); - - String operatorNumeric = getRUIMOperatorNumeric(); - if (operatorNumeric != null) { - if(operatorNumeric.length() <= 6){ - MccTable.updateMccMncConfiguration(mContext, operatorNumeric); - } - } - break; - - case EVENT_GET_CDMA_SUBSCRIPTION_DONE: - ar = (AsyncResult)msg.obj; - String localTemp[] = (String[])ar.result; - if (ar.exception != null) { - break; - } - - mMyMobileNumber = localTemp[0]; - mMin2Min1 = localTemp[3]; - mPrlVersion = localTemp[4]; - - log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); - - break; - - case EVENT_GET_ICCID_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - iccid = IccUtils.bcdToString(data, 0, data.length); - - log("iccid: " + iccid); - - break; - - case EVENT_UPDATE_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - Log.i(LOG_TAG, "RuimRecords update failed", 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: - log("Event EVENT_GET_SST_DONE Received"); - break; - - case EVENT_RUIM_REFRESH: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - handleRuimRefresh((IccRefreshResponse)ar.result); - } - break; - - }}catch (RuntimeException exc) { - // I don't want these exceptions to be fatal - Log.w(LOG_TAG, "Exception parsing RUIM record", exc); - } finally { - // Count up record load responses even if they are fails - if (isRecordLoadResponse) { - onRecordLoaded(); - } - } - } - - @Override - protected void onRecordLoaded() { - // One record loaded successfully or failed, In either case - // we need to update the recordsToLoad count - recordsToLoad -= 1; - if (DBG) log("RuimRecords:onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested); - - if (recordsToLoad == 0 && recordsRequested == true) { - onAllRecordsLoaded(); - } else if (recordsToLoad < 0) { - loge("RuimRecords: recordsToLoad <0, programmer error suspected"); - recordsToLoad = 0; - } - } - - @Override - protected void onAllRecordsLoaded() { - // Further records that can be inserted are Operator/OEM dependent - - String operator = getRUIMOperatorNumeric(); - log("RuimRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" + - operator + "'"); - SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator); - - if (mImsi != null) { - SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, - MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3)))); - } - recordsLoadedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - mParentCard.broadcastIccStateChangedIntent( - IccCard.INTENT_VALUE_ICC_LOADED, null); - } - - @Override - public void onReady() { - /* broadcast intent ICC_READY here so that we can make sure - READY is sent before IMSI ready - */ - - mParentCard.broadcastIccStateChangedIntent( - IccCard.INTENT_VALUE_ICC_READY, null); - - fetchRuimRecords(); - - mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); - } - - - private void fetchRuimRecords() { - recordsRequested = true; - - Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad); - - mCi.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_ICCID, - obtainMessage(EVENT_GET_ICCID_DONE)); - recordsToLoad++; - - log("RuimRecords:fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested); - // Further records that can be inserted are Operator/OEM dependent - } - - /** - * {@inheritDoc} - * - * No Display rule for RUIMs yet. - */ - @Override - public int getDisplayRule(String plmn) { - // TODO together with spn - return 0; - } - - @Override - public void setVoiceMessageWaiting(int line, int countWaiting) { - if (line != 1) { - // only profile 1 is supported - return; - } - - // range check - if (countWaiting < 0) { - countWaiting = -1; - } else if (countWaiting > 0xff) { - // C.S0015-B v2, 4.5.12 - // range: 0-99 - countWaiting = 0xff; - } - countVoiceMessages = countWaiting; - - mRecordsEventsRegistrants.notifyResult(EVENT_MWI); - } - - private void handleRuimRefresh(IccRefreshResponse refreshResponse) { - if (refreshResponse == null) { - if (DBG) log("handleRuimRefresh received without input"); - return; - } - - if (refreshResponse.aid != null && - !refreshResponse.aid.equals(mParentCard.getAid())) { - // This is for different app. Ignore. - return; - } - - switch (refreshResponse.refreshResult) { - case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE: - if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED"); - adnCache.reset(); - fetchRuimRecords(); - break; - case IccRefreshResponse.REFRESH_RESULT_INIT: - if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT"); - // need to reload all files (that we care about) - fetchRuimRecords(); - break; - case IccRefreshResponse.REFRESH_RESULT_RESET: - if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET"); - mCi.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 - if (DBG) log("handleRuimRefresh with unknown operation"); - break; - } - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[RuimRecords] " + s); - } - - @Override - protected void loge(String s) { - Log.e(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 deleted file mode 100644 index 9cd059d3e397..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java +++ /dev/null @@ -1,222 +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.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -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.SMSDispatcher; -import com.android.internal.telephony.SmsRawData; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; - -/** - * 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 = true; - - private final Object mLock = new Object(); - private boolean mSuccess; - private List mSms; - - private static final int EVENT_LOAD_DONE = 1; - private static final int EVENT_UPDATE_DONE = 2; - - Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_UPDATE_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - mSuccess = (ar.exception == null); - mLock.notifyAll(); - } - break; - case EVENT_LOAD_DONE: - ar = (AsyncResult)msg.obj; - synchronized (mLock) { - if (ar.exception == null) { - mSms = buildValidRawData((ArrayList) ar.result); - } else { - if(DBG) log("Cannot load Sms records"); - if (mSms != null) - mSms.clear(); - } - mLock.notifyAll(); - } - break; - } - } - }; - - public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) { - super(phone); - mDispatcher = dispatcher; - } - - public void dispose() { - } - - protected void finalize() { - try { - super.finalize(); - } catch (Throwable throwable) { - Log.e(LOG_TAG, "Error while finalizing:", throwable); - } - 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 - 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 copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { - //NOTE smsc not used in RUIM - if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + - "pdu=("+ Arrays.toString(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 getAllMessagesFromIccEf() { - if (DBG) log("getAllMessagesFromEF"); - - Context context = mPhone.getContext(); - - 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; - } - - public boolean enableCellBroadcast(int messageIdentifier) { - // Not implemented - Log.e(LOG_TAG, "Error! Not implemented for CDMA."); - return false; - } - - public boolean disableCellBroadcast(int messageIdentifier) { - // Not implemented - Log.e(LOG_TAG, "Error! Not implemented for CDMA."); - return false; - } - - public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { - // Not implemented - Log.e(LOG_TAG, "Error! Not implemented for CDMA."); - return false; - } - - public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { - // Not implemented - Log.e(LOG_TAG, "Error! Not implemented for CDMA."); - return false; - } - - protected void log(String msg) { - Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg); - } -} - diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java deleted file mode 100644 index a149e7225429..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.cdma; - -import java.util.HashMap; -import java.util.HashSet; -import android.util.Log; -import android.media.ToneGenerator; - -public class SignalToneUtil { - /** A marker that isn't a valid TONE */ - public static final int CDMA_INVALID_TONE = -1; - - // public final int int IS95_CONST_IR_SIGNAL_TYPE_TYPE; - static public final int IS95_CONST_IR_SIGNAL_TONE = 0; - static public final int IS95_CONST_IR_SIGNAL_ISDN = 1; - static public final int IS95_CONST_IR_SIGNAL_IS54B = 2; - static public final int IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT = 4; - - // public final int int IS95_CONST_IR_ALERT_PITCH_TYPE; - static public final int IS95_CONST_IR_ALERT_MED = 0; - static public final int IS95_CONST_IR_ALERT_HIGH = 1; - static public final int IS95_CONST_IR_ALERT_LOW = 2; - - // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal, - // set TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN to 0 to avoid - // the alert pitch to be involved in hash calculation for - // signal type other than IS54B. - static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 0; - - // public final int int IS95_CONST_IR_SIGNAL_TYPE; - static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0; - static public final int IS95_CONST_IR_SIG_ISDN_INTGRP = 1; - static public final int IS95_CONST_IR_SIG_ISDN_SP_PRI = 2; - static public final int IS95_CONST_IR_SIG_ISDN_PAT_3 = 3; - static public final int IS95_CONST_IR_SIG_ISDN_PING = 4; - static public final int IS95_CONST_IR_SIG_ISDN_PAT_5 = 5; - static public final int IS95_CONST_IR_SIG_ISDN_PAT_6 = 6; - static public final int IS95_CONST_IR_SIG_ISDN_PAT_7 = 7; - static public final int IS95_CONST_IR_SIG_ISDN_OFF = 15; - static public final int IS95_CONST_IR_SIG_TONE_DIAL = 0; - static public final int IS95_CONST_IR_SIG_TONE_RING = 1; - static public final int IS95_CONST_IR_SIG_TONE_INT = 2; - static public final int IS95_CONST_IR_SIG_TONE_ABB_INT = 3; - static public final int IS95_CONST_IR_SIG_TONE_REORDER = 4; - static public final int IS95_CONST_IR_SIG_TONE_ABB_RE = 5; - static public final int IS95_CONST_IR_SIG_TONE_BUSY = 6; - static public final int IS95_CONST_IR_SIG_TONE_CONFIRM = 7; - static public final int IS95_CONST_IR_SIG_TONE_ANSWER = 8; - static public final int IS95_CONST_IR_SIG_TONE_CALL_W = 9; - static public final int IS95_CONST_IR_SIG_TONE_PIP = 10; - static public final int IS95_CONST_IR_SIG_TONE_NO_TONE = 63; - static public final int IS95_CONST_IR_SIG_IS54B_NO_TONE = 0; - static public final int IS95_CONST_IR_SIG_IS54B_L = 1; - static public final int IS95_CONST_IR_SIG_IS54B_SS = 2; - static public final int IS95_CONST_IR_SIG_IS54B_SSL = 3; - static public final int IS95_CONST_IR_SIG_IS54B_SS_2 = 4; - static public final int IS95_CONST_IR_SIG_IS54B_SLS = 5; - static public final int IS95_CONST_IR_SIG_IS54B_S_X4 = 6; - static public final int IS95_CONST_IR_SIG_IS54B_PBX_L = 7; - static public final int IS95_CONST_IR_SIG_IS54B_PBX_SS = 8; - static public final int IS95_CONST_IR_SIG_IS54B_PBX_SSL = 9; - static public final int IS95_CONST_IR_SIG_IS54B_PBX_SLS = 10; - static public final int IS95_CONST_IR_SIG_IS54B_PBX_S_X4 = 11; - static public final int IS95_CONST_IR_SIG_TONE_ABBR_ALRT = 0; - - // Hashmap to map signalInfo To AudioTone - static private HashMap hm = new HashMap(); - - private static Integer signalParamHash(int signalType, int alertPitch, int signal) { - if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) || - (alertPitch < 0) || (signal > 256) || (signal < 0)) { - return new Integer(CDMA_INVALID_TONE); - } - // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal, - // the alert pitch field is ignored by the mobile station unless - // SIGNAL_TYPE is '10',IS-54B Alerting. - // Set alert pitch to TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN - // so the alert pitch is not involved in hash calculation - // when signal type is not IS-54B. - if (signalType != IS95_CONST_IR_SIGNAL_IS54B) { - alertPitch = TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN; - } - return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal); - } - - public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) { - Integer result = hm.get(signalParamHash(signalType, alertPitch, signal)); - if (result == null) { - return CDMA_INVALID_TONE; - } - return result; - } - - static { - - /* SIGNAL_TYPE_ISDN */ - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_NORMAL), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_INTGRP), - ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_SP_PRI), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_PAT_3), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT3); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_PING), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_PAT_5), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT5); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_PAT_6), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT6); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_PAT_7), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT7); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_ISDN_OFF), ToneGenerator.TONE_CDMA_SIGNAL_OFF); - - /* SIGNAL_TYPE_TONE */ - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_DIAL), ToneGenerator.TONE_CDMA_DIAL_TONE_LITE); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_RING), ToneGenerator.TONE_CDMA_NETWORK_USA_RINGBACK); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_INT), ToneGenerator.TONE_SUP_INTERCEPT); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_ABB_INT), ToneGenerator.TONE_SUP_INTERCEPT_ABBREV); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_REORDER), ToneGenerator.TONE_CDMA_REORDER); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_ABB_RE), ToneGenerator.TONE_CDMA_ABBR_REORDER); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_BUSY), ToneGenerator.TONE_CDMA_NETWORK_BUSY); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_CONFIRM), ToneGenerator.TONE_SUP_CONFIRM); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_ANSWER), ToneGenerator.TONE_CDMA_ANSWER); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_CALL_W), ToneGenerator.TONE_CDMA_NETWORK_CALLWAITING); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_PIP), ToneGenerator.TONE_CDMA_PIP); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_TONE_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF); - - /* SIGNAL_TYPE_IS54B */ - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_HIGH_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_MED_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_LOW_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_HIGH_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_MED_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_LOW_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_HIGH_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_MED_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_LOW_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_HIGH_SS_2); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_MED_SS_2); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_LOW_SS_2); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_HIGH_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_MED_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_LOW_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_HIGH_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_MED_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_LOW_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_HIGH_PBX_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_MED_PBX_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_LOW_PBX_L); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_HIGH_PBX_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_MED_PBX_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_LOW_PBX_SS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_HIGH_PBX_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_MED_PBX_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_LOW_PBX_SSL); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_HIGH_PBX_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_MED_PBX_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_LOW_PBX_SLS); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH, - IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_HIGH_PBX_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED, - IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_MED_PBX_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW, - IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_LOW_PBX_S_X4); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, - IS95_CONST_IR_SIG_IS54B_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT, - TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_ABBR_ALRT), - ToneGenerator.TONE_CDMA_ABBR_ALERT); - - hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT, - TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_NO_TONE), - ToneGenerator.TONE_CDMA_ABBR_ALERT); - - } - - // suppress default constructor for noninstantiability - private SignalToneUtil() { - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java deleted file mode 100644 index a723de3543c3..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ /dev/null @@ -1,997 +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.os.Parcel; -import android.os.SystemProperties; -import android.telephony.PhoneNumberUtils; -import android.telephony.SmsCbLocation; -import android.telephony.SmsCbMessage; -import android.telephony.cdma.CdmaSmsCbProgramData; -import android.util.Log; - -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.cdma.sms.BearerData; -import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; -import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress; -import com.android.internal.telephony.cdma.sms.SmsEnvelope; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.BitwiseInputStream; -import com.android.internal.util.HexDump; - -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.util.List; - -import static android.telephony.SmsMessage.MessageClass; - -/** - * TODO(cleanup): these constants are disturbing... are they not just - * different interpretations on one number? And if we did not have - * terrible class name overlap, they would not need to be directly - * imported like this. The class in this file could just as well be - * named CdmaSmsMessage, could it not? - */ - -/** - * TODO(cleanup): internally returning null in many places makes - * debugging very hard (among many other reasons) and should be made - * more meaningful (replaced with exceptions for example). Null - * returns should only occur at the very outside of the module/class - * scope. - */ - -/** - * A Short Message Service message. - * - */ -public class SmsMessage extends SmsMessageBase { - static final String LOG_TAG = "CDMA"; - static private final String LOGGABLE_TAG = "CDMA:SMS"; - - private final static byte TELESERVICE_IDENTIFIER = 0x00; - private final static byte SERVICE_CATEGORY = 0x01; - private final static byte ORIGINATING_ADDRESS = 0x02; - private final static byte ORIGINATING_SUB_ADDRESS = 0x03; - private final static byte DESTINATION_ADDRESS = 0x04; - private final static byte DESTINATION_SUB_ADDRESS = 0x05; - private final static byte BEARER_REPLY_OPTION = 0x06; - private final static byte CAUSE_CODES = 0x07; - private final static byte BEARER_DATA = 0x08; - - /** - * 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; - - /** 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; - } - } - - /** - * 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(); - CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress(); - byte[] data; - byte count; - int countInt; - int addressDigitMode; - - //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 - addressDigitMode = p.readInt(); - addr.digitMode = (byte) (0xFF & addressDigitMode); //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(); - - // convert the value if it is 4-bit DTMF to 8 bit - if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { - data[index] = msg.convertDtmfToAscii(data[index]); - } - } - - addr.origBytes = data; - - subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType - subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd - count = p.readByte(); // p_cur->sSubAddress.number_of_digits - - if (count < 0) { - count = 0; - } - - // p_cur->sSubAddress.digits[digitCount] : - - data = new byte[count]; - - for (int index = 0; index < count; ++index) { - data[index] = p.readByte(); - } - - subaddr.origBytes = data; - - /* 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) { - countInt = 0; - } - - data = new byte[countInt]; - for (int index=0; index < countInt; index++) { - data[index] = p.readByte(); - } - // BD gets further decoded when accessed in SMSDispatcher - env.bearerData = data; - - // link the the filled objects to the SMS - env.origAddress = addr; - env.origSubaddress = subaddr; - 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 - msg.parsePduFromEfRecord(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 int getTPLayerLengthForPDU(String pdu) { - Log.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode."); - return 0; - } - - /** - * TODO(cleanup): why do getSubmitPdu methods take an scAddr input - * and do nothing with it? GSM allows us to specify a SC (eg, - * when responding to an SMS that explicitly requests the response - * is sent to a specific SC), or pass null to use the default - * value. Is there no similar notion in CDMA? Or do we just not - * have it hooked up? - */ - - /** - * Get an SMS-SUBMIT PDU for a destination address and a message - * - * @param scAddr Service Centre address. Null means use default. - * @param destAddr Address of the recipient. - * @param message String representation of the message payload. - * @param statusReportRequested Indicates whether a report is requested for this message. - * @param smsHeader Array containing the data for the User Data Header, preceded - * by the Element Identifiers. - * @return a SubmitPdu containing the encoded SC - * address, if applicable, and the encoded message. - * Returns null on encode error. - * @hide - */ - public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, - boolean statusReportRequested, SmsHeader smsHeader) { - - /** - * TODO(cleanup): Do we really want silent failure like this? - * Would it not be much more reasonable to make sure we don't - * call this function if we really want nothing done? - */ - if (message == null || destAddr == null) { - return null; - } - - UserData uData = new UserData(); - uData.payloadStr = message; - uData.userDataHeader = smsHeader; - return privateGetSubmitPdu(destAddr, statusReportRequested, uData); - } - - /** - * Get an SMS-SUBMIT PDU for a data message to a destination address and port. - * - * @param scAddr Service Centre address. null == use default - * @param destAddr the address of the destination for the message - * @param destPort the port to deliver the message to at the - * destination - * @param data the data for the message - * @return a SubmitPdu containing the encoded SC - * address, if applicable, and the encoded message. - * Returns null on encode error. - */ - public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort, - byte[] data, boolean statusReportRequested) { - - /** - * TODO(cleanup): this is not a general-purpose SMS creation - * method, but rather something specialized to messages - * containing OCTET encoded (meaning non-human-readable) user - * data. The name should reflect that, and not just overload. - */ - - SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); - portAddrs.destPort = destPort; - portAddrs.origPort = 0; - portAddrs.areEightBits = false; - - SmsHeader smsHeader = new SmsHeader(); - smsHeader.portAddrs = portAddrs; - - UserData uData = new UserData(); - uData.userDataHeader = smsHeader; - uData.msgEncoding = UserData.ENCODING_OCTET; - uData.msgEncodingSet = true; - uData.payload = data; - - return privateGetSubmitPdu(destAddr, statusReportRequested, uData); - } - - /** - * Get an SMS-SUBMIT PDU for a data message to a destination address & port - * - * @param destAddr the address of the destination for the message - * @param userData the data for the message - * @param statusReportRequested Indicates whether a report is requested for this message. - * @return a SubmitPdu containing the encoded SC - * address, if applicable, and the encoded message. - * Returns null on encode error. - */ - public static SubmitPdu getSubmitPdu(String destAddr, UserData userData, - boolean statusReportRequested) { - return privateGetSubmitPdu(destAddr, statusReportRequested, userData); - } - - /** - * 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() { - return ((mBearerData != null) && (mBearerData.numberOfMessages == 0)); - } - - /** - * {@inheritDoc} - */ - public boolean isMWISetMessage() { - return ((mBearerData != null) && (mBearerData.numberOfMessages > 0)); - } - - /** - * {@inheritDoc} - */ - public boolean isMwiDontStore() { - return ((mBearerData != null) && - (mBearerData.numberOfMessages > 0) && - (mBearerData.userData == null)); - } - - /** - * 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); - } - - /** Return true iff the bearer data message type is DELIVERY_ACK. */ - public boolean isStatusReportMessage() { - return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK); - } - - /** - * 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; - } - - /** - * Calculate the number of septets needed to encode the message. - * - * @param messageBody the message to encode - * @param use7bitOnly ignore (but still count) illegal characters if true - * @return TextEncodingDetails - */ - public static TextEncodingDetails calculateLength(CharSequence messageBody, - boolean use7bitOnly) { - return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly); - } - - /** - * 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} - */ - /* package */ int getTeleService() { - return mEnvelope.teleService; - } - - /** - * Returns the message type of the message. - * @return the message type: - * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT}, - * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST}, - * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, - */ - /* package */ int getMessageType() { - return mEnvelope.messageType; - } - - /** - * 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(bais); - byte length; - int bearerDataLength; - 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: - bearerDataLength = dis.readInt(); - env.bearerData = new byte[bearerDataLength]; - dis.read(env.bearerData, 0, bearerDataLength); - 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; - mPdu = pdu; - - parseSms(); - } - - /** - * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0 - */ - private void parsePduFromEfRecord(byte[] pdu) { - ByteArrayInputStream bais = new ByteArrayInputStream(pdu); - DataInputStream dis = new DataInputStream(bais); - SmsEnvelope env = new SmsEnvelope(); - CdmaSmsAddress addr = new CdmaSmsAddress(); - CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress(); - - try { - env.messageType = dis.readByte(); - - while (dis.available() > 0) { - int parameterId = dis.readByte(); - int parameterLen = dis.readByte(); - byte[] parameterData = new byte[parameterLen]; - - switch (parameterId) { - case TELESERVICE_IDENTIFIER: - /* - * 16 bit parameter that identifies which upper layer - * service access point is sending or should receive - * this message - */ - env.teleService = dis.readUnsignedShort(); - Log.i(LOG_TAG, "teleservice = " + env.teleService); - break; - case SERVICE_CATEGORY: - /* - * 16 bit parameter that identifies type of service as - * in 3GPP2 C.S0015-0 Table 3.4.3.2-1 - */ - env.serviceCategory = dis.readUnsignedShort(); - break; - case ORIGINATING_ADDRESS: - case DESTINATION_ADDRESS: - dis.read(parameterData, 0, parameterLen); - BitwiseInputStream addrBis = new BitwiseInputStream(parameterData); - addr.digitMode = addrBis.read(1); - addr.numberMode = addrBis.read(1); - int numberType = 0; - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - numberType = addrBis.read(3); - addr.ton = numberType; - - if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) - addr.numberPlan = addrBis.read(4); - } - - addr.numberOfDigits = addrBis.read(8); - - byte[] data = new byte[addr.numberOfDigits]; - byte b = 0x00; - - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { - /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */ - for (int index = 0; index < addr.numberOfDigits; index++) { - b = (byte) (0xF & addrBis.read(4)); - // convert the value if it is 4-bit DTMF to 8 - // bit - data[index] = convertDtmfToAscii(b); - } - } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) { - for (int index = 0; index < addr.numberOfDigits; index++) { - b = (byte) (0xFF & addrBis.read(8)); - data[index] = b; - } - - } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { - if (numberType == 2) - Log.e(LOG_TAG, "TODO: Originating Addr is email id"); - else - Log.e(LOG_TAG, - "TODO: Originating Addr is data network address"); - } else { - Log.e(LOG_TAG, "Originating Addr is of incorrect type"); - } - } else { - Log.e(LOG_TAG, "Incorrect Digit mode"); - } - addr.origBytes = data; - Log.i(LOG_TAG, "Originating Addr=" + addr.toString()); - break; - case ORIGINATING_SUB_ADDRESS: - case DESTINATION_SUB_ADDRESS: - dis.read(parameterData, 0, parameterLen); - BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData); - subAddr.type = subAddrBis.read(3); - subAddr.odd = subAddrBis.readByteArray(1)[0]; - int subAddrLen = subAddrBis.read(8); - byte[] subdata = new byte[subAddrLen]; - for (int index = 0; index < subAddrLen; index++) { - b = (byte) (0xFF & subAddrBis.read(4)); - // convert the value if it is 4-bit DTMF to 8 bit - subdata[index] = convertDtmfToAscii(b); - } - subAddr.origBytes = subdata; - break; - case BEARER_REPLY_OPTION: - dis.read(parameterData, 0, parameterLen); - BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData); - env.bearerReply = replyOptBis.read(6); - break; - case CAUSE_CODES: - dis.read(parameterData, 0, parameterLen); - BitwiseInputStream ccBis = new BitwiseInputStream(parameterData); - env.replySeqNo = ccBis.readByteArray(6)[0]; - env.errorClass = ccBis.readByteArray(2)[0]; - if (env.errorClass != 0x00) - env.causeCode = ccBis.readByteArray(8)[0]; - break; - case BEARER_DATA: - dis.read(parameterData, 0, parameterLen); - env.bearerData = parameterData; - break; - default: - throw new Exception("unsupported parameterId (" + parameterId + ")"); - } - } - bais.close(); - dis.close(); - } catch (Exception ex) { - Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex); - } - - // link the filled objects to this SMS - originatingAddress = addr; - env.origAddress = addr; - env.origSubaddress = subAddr; - mEnvelope = env; - mPdu = pdu; - - parseSms(); - } - - /** - * Parses a SMS message from its BearerData stream. (mobile-terminated only) - */ - protected void parseSms() { - // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 - // It contains only an 8-bit number with the number of messages waiting - if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) { - mBearerData = new BearerData(); - if (mEnvelope.bearerData != null) { - mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0]; - } - if (false) { - Log.d(LOG_TAG, "parseSms: get MWI " + - Integer.toString(mBearerData.numberOfMessages)); - } - return; - } - mBearerData = BearerData.decode(mEnvelope.bearerData); - if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { - Log.d(LOG_TAG, "MT raw BearerData = '" + - HexDump.toHexString(mEnvelope.bearerData) + "'"); - Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData); - } - messageRef = mBearerData.messageId; - if (mBearerData.userData != null) { - userData = mBearerData.userData.payload; - userDataHeader = mBearerData.userData.userDataHeader; - messageBody = mBearerData.userData.payloadStr; - } - - if (originatingAddress != null) { - originatingAddress.address = new String(originatingAddress.origBytes); - if (false) Log.v(LOG_TAG, "SMS originating address: " - + originatingAddress.address); - } - - if (mBearerData.msgCenterTimeStamp != null) { - scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); - } - - if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); - - // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1) - if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) { - // The BearerData MsgStatus subparameter should only be - // included for DELIVERY_ACK messages. If it occurred for - // other messages, it would be unclear what the status - // being reported refers to. The MsgStatus subparameter - // is primarily useful to indicate error conditions -- a - // message without this subparameter is assumed to - // indicate successful delivery (status == 0). - if (! mBearerData.messageStatusSet) { - Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" + - (userData == null ? "also missing" : "does have") + - " userData)."); - status = 0; - } else { - status = mBearerData.errorClass << 8; - status |= mBearerData.messageStatus; - } - } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { - throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); - } - - if (messageBody != null) { - if (false) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'"); - parseMessageBody(); - } else if ((userData != null) && (false)) { - Log.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(userData) + "'"); - } - } - - /** - * Parses a broadcast SMS, possibly containing a CMAS alert. - */ - SmsCbMessage parseBroadcastSms() { - BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory); - if (bData == null) { - Log.w(LOG_TAG, "BearerData.decode() returned null"); - return null; - } - - if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { - Log.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData)); - } - - String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); - SmsCbLocation location = new SmsCbLocation(plmn); - - return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2, - SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location, - mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr, - bData.priority, null, bData.cmasWarningInfo); - } - - /** - * {@inheritDoc} - */ - public MessageClass getMessageClass() { - if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) { - return MessageClass.CLASS_0; - } else { - return MessageClass.UNKNOWN; - } - } - - /** - * Calculate the next message id, starting at 1 and iteratively - * incrementing within the range 1..65535 remembering the state - * via a persistent system property. (See C.S0015-B, v2.0, - * 4.3.1.5) Since this routine is expected to be accessed via via - * binder-call, and hence should be thread-safe, it has been - * synchronized. - */ - private synchronized static int getNextMessageId() { - // Testing and dialog with partners has indicated that - // msgId==0 is (sometimes?) treated specially by lower levels. - // Specifically, the ID is not preserved for delivery ACKs. - // Hence, avoid 0 -- constraining the range to 1..65535. - int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1); - String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1); - SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId); - if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { - Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId); - Log.d(LOG_TAG, "readback gets " + - SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID)); - } - return msgId; - } - - /** - * Creates BearerData and Envelope from parameters for a Submit SMS. - * @return byte stream for SubmitPdu. - */ - private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested, - UserData userData) { - - /** - * TODO(cleanup): give this function a more meaningful name. - */ - - /** - * TODO(cleanup): Make returning null from the getSubmitPdu - * variations meaningful -- clean up the error feedback - * mechanism, and avoid null pointer exceptions. - */ - - /** - * North America Plus Code : - * Convert + code to 011 and dial out for international SMS - */ - CdmaSmsAddress destAddr = CdmaSmsAddress.parse( - PhoneNumberUtils.cdmaCheckAndProcessPlusCode(destAddrStr)); - if (destAddr == null) return null; - - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; - - bearerData.messageId = getNextMessageId(); - - bearerData.deliveryAckReq = statusReportRequested; - bearerData.userAckReq = false; - bearerData.readAckReq = false; - bearerData.reportReq = false; - - bearerData.userData = userData; - - byte[] encodedBearerData = BearerData.encode(bearerData); - if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { - Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData); - Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'"); - } - if (encodedBearerData == null) return null; - - int teleservice = bearerData.hasUserDataHeader ? - SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; - - SmsEnvelope envelope = new SmsEnvelope(); - envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; - envelope.teleService = teleservice; - envelope.destAddress = destAddr; - envelope.bearerReply = RETURN_ACK; - envelope.bearerData = encodedBearerData; - - /** - * TODO(cleanup): envelope looks to be a pointless class, get - * rid of it. Also -- most of the envelope fields set here - * are ignored, why? - */ - - try { - /** - * TODO(cleanup): reference a spec and get rid of the ugly comments - */ - ByteArrayOutputStream baos = new ByteArrayOutputStream(100); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeInt(envelope.teleService); - dos.writeInt(0); //servicePresent - dos.writeInt(0); //serviceCategory - dos.write(destAddr.digitMode); - dos.write(destAddr.numberMode); - dos.write(destAddr.ton); // number_type - dos.write(destAddr.numberPlan); - dos.write(destAddr.numberOfDigits); - dos.write(destAddr.origBytes, 0, destAddr.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(encodedBearerData.length); - dos.write(encodedBearerData, 0, encodedBearerData.length); - dos.close(); - - SubmitPdu pdu = new SubmitPdu(); - pdu.encodedMessage = baos.toByteArray(); - pdu.encodedScAddress = null; - return pdu; - } catch(IOException ex) { - Log.e(LOG_TAG, "creating SubmitPdu 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.writeInt(env.bearerData.length); - dos.write(env.bearerData, 0, env.bearerData.length); - dos.close(); - - /** - * TODO(cleanup) -- The mPdu field is managed in - * a fragile manner, and it would be much nicer if - * accessing the serialized representation used a less - * fragile mechanism. Maybe the getPdu method could - * generate a representation if there was not yet one? - */ - - mPdu = baos.toByteArray(); - } catch (IOException ex) { - Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex); - } - } - - /** - * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character - */ - private byte convertDtmfToAscii(byte dtmfDigit) { - byte asciiDigit; - - switch (dtmfDigit) { - case 0: asciiDigit = 68; break; // 'D' - case 1: asciiDigit = 49; break; // '1' - case 2: asciiDigit = 50; break; // '2' - case 3: asciiDigit = 51; break; // '3' - case 4: asciiDigit = 52; break; // '4' - case 5: asciiDigit = 53; break; // '5' - case 6: asciiDigit = 54; break; // '6' - case 7: asciiDigit = 55; break; // '7' - case 8: asciiDigit = 56; break; // '8' - case 9: asciiDigit = 57; break; // '9' - case 10: asciiDigit = 48; break; // '0' - case 11: asciiDigit = 42; break; // '*' - case 12: asciiDigit = 35; break; // '#' - case 13: asciiDigit = 65; break; // 'A' - case 14: asciiDigit = 66; break; // 'B' - case 15: asciiDigit = 67; break; // 'C' - default: - asciiDigit = 32; // Invalid DTMF code - break; - } - - return asciiDigit; - } - - /** This function shall be called to get the number of voicemails. - * @hide - */ - /*package*/ int getNumOfVoicemails() { - return mBearerData.numberOfMessages; - } - - /** - * Returns a byte array that can be use to uniquely identify a received SMS message. - * C.S0015-B 4.3.1.6 Unique Message Identification. - * - * @return byte array uniquely identifying the message. - * @hide - */ - /* package */ byte[] getIncomingSmsFingerprint() { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - - output.write(mEnvelope.teleService); - output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length); - output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length); - output.write(mEnvelope.origSubaddress.origBytes, 0, - mEnvelope.origSubaddress.origBytes.length); - - return output.toByteArray(); - } - - /** - * Returns the list of service category program data, if present. - * @return a list of CdmaSmsCbProgramData objects, or null if not present - */ - List getSmsCbProgramData() { - return mBearerData.serviceCategoryProgramData; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java deleted file mode 100644 index 4907aa946800..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java +++ /dev/null @@ -1,67 +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.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"; - - /** - * Broadcast intent action indicating that the TTY preferred operating mode - * has changed. An intent extra provides the new mode as an int. - * @see #TTY_PREFFERED_MODE - * - * {@hide} - */ - public static final String TTY_PREFERRED_MODE_CHANGE_ACTION = - "com.android.internal.telephony.cdma.intent.action.TTY_PREFERRED_MODE_CHANGE"; - - /** - * The lookup key for an int that indicates preferred TTY mode. - * Valid modes are: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * - * {@hide} - */ - public static final String TTY_PREFFERED_MODE = "ttyPreferredMode"; -} diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html deleted file mode 100644 index 4eb1f9c0fd9e..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/package.html +++ /dev/null @@ -1,6 +0,0 @@ - - -Provides classes to control or read data from CDMA phones. -@hide - - diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java deleted file mode 100755 index 0f497625b8a2..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ /dev/null @@ -1,1942 +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.sms; - -import android.content.res.Resources; -import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbMessage; -import android.telephony.SmsMessage; -import android.telephony.cdma.CdmaSmsCbProgramData; -import android.text.format.Time; -import android.util.Log; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; -import com.android.internal.util.BitwiseInputStream; -import com.android.internal.util.BitwiseOutputStream; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.TimeZone; - -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; - -/** - * An object to encode and decode CDMA SMS bearer data. - */ -public final class BearerData { - private final static String LOG_TAG = "SMS"; - - /** - * Bearer Data Subparameter Identifiers - * (See 3GPP2 C.S0015-B, v2.0, table 4.5-1) - * NOTE: Commented subparameter types are not implemented. - */ - private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00; - private final static byte SUBPARAM_USER_DATA = 0x01; - private final static byte SUBPARAM_USER_RESPONSE_CODE = 0x02; - private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03; - private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04; - private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05; - private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06; - private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07; - private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08; - private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09; - private final static byte SUBPARAM_REPLY_OPTION = 0x0A; - private final static byte SUBPARAM_NUMBER_OF_MESSAGES = 0x0B; - private final static byte SUBPARAM_ALERT_ON_MESSAGE_DELIVERY = 0x0C; - private final static byte SUBPARAM_LANGUAGE_INDICATOR = 0x0D; - private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E; - private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F; - //private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10; - private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11; - private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12; - private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13; - private final static byte SUBPARAM_MESSAGE_STATUS = 0x14; - //private final static byte SUBPARAM_TP_FAILURE_CAUSE = 0x15; - //private final static byte SUBPARAM_ENHANCED_VMN = 0x16; - //private final static byte SUBPARAM_ENHANCED_VMN_ACK = 0x17; - - /** - * 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; - - public int 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; - - /** - * 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; - - public boolean priorityIndicatorSet = false; - public int priority = PRIORITY_NORMAL; - - /** - * 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; - - public boolean privacyIndicatorSet = false; - public int privacy = PRIVACY_NOT_RESTRICTED; - - /** - * Supported alert priority 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; - - public boolean alertIndicatorSet = false; - public int alert = ALERT_DEFAULT; - - /** - * Supported display modes for CDMA SMS messages. Display mode is - * a 2-bit value used to indicate to the mobile station when to - * display the received message. (See 3GPP2 C.S0015-B, v2, - * 4.5.16) - */ - public static final int DISPLAY_MODE_IMMEDIATE = 0x0; - public static final int DISPLAY_MODE_DEFAULT = 0x1; - public static final int DISPLAY_MODE_USER = 0x2; - - public boolean displayModeSet = false; - public int displayMode = DISPLAY_MODE_DEFAULT; - - /** - * Language Indicator values. NOTE: the spec (3GPP2 C.S0015-B, - * v2, 4.5.14) is ambiguous as to the meaning of this field, as it - * refers to C.R1001-D but that reference has been crossed out. - * It would seem reasonable to assume the values from C.R1001-F - * (table 9.2-1) are to be used instead. - */ - public static final int LANGUAGE_UNKNOWN = 0x00; - public static final int LANGUAGE_ENGLISH = 0x01; - public static final int LANGUAGE_FRENCH = 0x02; - public static final int LANGUAGE_SPANISH = 0x03; - public static final int LANGUAGE_JAPANESE = 0x04; - public static final int LANGUAGE_KOREAN = 0x05; - public static final int LANGUAGE_CHINESE = 0x06; - public static final int LANGUAGE_HEBREW = 0x07; - - public boolean languageIndicatorSet = false; - public int language = LANGUAGE_UNKNOWN; - - /** - * SMS Message Status Codes. The first component of the Message - * status indicates if an error has occurred and whether the error - * is considered permanent or temporary. The second component of - * the Message status indicates the cause of the error (if any). - * (See 3GPP2 C.S0015-B, v2.0, 4.5.21) - */ - /* 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; - - public boolean messageStatusSet = false; - public int errorClass = ERROR_UNDEFINED; - public int messageStatus = STATUS_UNDEFINED; - - /** - * 1-bit value that indicates whether a User Data Header (UDH) is present. - * (See 3GPP2 C.S0015-B, v2, 4.5.1) - * - * NOTE: during encoding, this value will be set based on the - * presence of a UDH in the structured data, any existing setting - * will be overwritten. - */ - public boolean hasUserDataHeader; - - /** - * 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; - - /** - * The User Response Code subparameter is used in the SMS User - * Acknowledgment Message to respond to previously received short - * messages. This message center-specific element carries the - * identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2, - * 4.5.3) - */ - public boolean userResponseCodeSet = false; - public int userResponseCode; - - /** - * 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4 - */ - public static class TimeStamp extends Time { - - public TimeStamp() { - super(TimeZone.getDefault().getID()); // 3GPP2 timestamps use the local timezone - } - - public static TimeStamp fromByteArray(byte[] data) { - TimeStamp ts = new TimeStamp(); - // C.S0015-B v2.0, 4.5.4: range is 1996-2095 - int year = IccUtils.cdmaBcdByteToInt(data[0]); - if (year > 99 || year < 0) return null; - ts.year = year >= 96 ? year + 1900 : year + 2000; - int month = IccUtils.cdmaBcdByteToInt(data[1]); - if (month < 1 || month > 12) return null; - ts.month = month - 1; - int day = IccUtils.cdmaBcdByteToInt(data[2]); - if (day < 1 || day > 31) return null; - ts.monthDay = day; - int hour = IccUtils.cdmaBcdByteToInt(data[3]); - if (hour < 0 || hour > 23) return null; - ts.hour = hour; - int minute = IccUtils.cdmaBcdByteToInt(data[4]); - if (minute < 0 || minute > 59) return null; - ts.minute = minute; - int second = IccUtils.cdmaBcdByteToInt(data[5]); - if (second < 0 || second > 59) return null; - ts.second = second; - return ts; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("TimeStamp "); - builder.append("{ year=" + year); - builder.append(", month=" + month); - builder.append(", day=" + monthDay); - builder.append(", hour=" + hour); - builder.append(", minute=" + minute); - builder.append(", second=" + second); - builder.append(" }"); - return builder.toString(); - } - } - - public TimeStamp msgCenterTimeStamp; - public TimeStamp validityPeriodAbsolute; - public TimeStamp deferredDeliveryTimeAbsolute; - - /** - * Relative time is specified as one byte, the value of which - * falls into a series of ranges, as specified below. The idea is - * that shorter time intervals allow greater precision -- the - * value means minutes from zero until the MINS_LIMIT (inclusive), - * upon which it means hours until the HOURS_LIMIT, and so - * forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1) - */ - public static final int RELATIVE_TIME_MINS_LIMIT = 143; - public static final int RELATIVE_TIME_HOURS_LIMIT = 167; - public static final int RELATIVE_TIME_DAYS_LIMIT = 196; - public static final int RELATIVE_TIME_WEEKS_LIMIT = 244; - public static final int RELATIVE_TIME_INDEFINITE = 245; - public static final int RELATIVE_TIME_NOW = 246; - public static final int RELATIVE_TIME_MOBILE_INACTIVE = 247; - public static final int RELATIVE_TIME_RESERVED = 248; - - public boolean validityPeriodRelativeSet; - public int validityPeriodRelative; - public boolean deferredDeliveryTimeRelativeSet; - public int deferredDeliveryTimeRelative; - - /** - * The Reply Option subparameter contains 1-bit values which - * indicate whether SMS acknowledgment is requested or not. (See - * 3GPP2 C.S0015-B, v2, 4.5.11) - */ - public boolean userAckReq; - public boolean deliveryAckReq; - public boolean readAckReq; - public boolean reportReq; - - /** - * The Number of Messages subparameter (8-bit value) is a decimal - * number in the 0 to 99 range representing the number of messages - * stored at the Voice Mail System. This element is used by the - * Voice Mail Notification service. (See 3GPP2 C.S0015-B, v2, - * 4.5.12) - */ - public int numberOfMessages; - - /** - * The Message Deposit Index subparameter is assigned by the - * message center as a unique index to the contents of the User - * Data subparameter in each message sent to a particular mobile - * station. The mobile station, when replying to a previously - * received short message which included a Message Deposit Index - * subparameter, may include the Message Deposit Index of the - * received message to indicate to the message center that the - * original contents of the message are to be included in the - * reply. (See 3GPP2 C.S0015-B, v2, 4.5.18) - */ - public int depositIndex; - - /** - * 4-bit or 8-bit value that indicates the number to be dialed in reply to a - * received SMS message. - * (See 3GPP2 C.S0015-B, v2, 4.5.15) - */ - public CdmaSmsAddress callbackNumber; - - /** - * CMAS warning notification information. - * @see #decodeCmasUserData(BearerData, int) - */ - public SmsCbCmasInfo cmasWarningInfo; - - /** - * The Service Category Program Data subparameter is used to enable and disable - * SMS broadcast service categories to display. If this subparameter is present, - * this field will contain a list of one or more - * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects containing the - * operation(s) to perform. - */ - public List serviceCategoryProgramData; - - private static class CodingException extends Exception { - public CodingException(String s) { - super(s); - } - } - - /** - * Returns the language indicator as a two-character ISO 639 string. - * @return a two character ISO 639 language code - */ - public String getLanguage() { - return getLanguageCodeForValue(language); - } - - /** - * Converts a CDMA language indicator value to an ISO 639 two character language code. - * @param languageValue the CDMA language value to convert - * @return the two character ISO 639 language code for the specified value, or null if unknown - */ - private static String getLanguageCodeForValue(int languageValue) { - switch (languageValue) { - case LANGUAGE_ENGLISH: - return "en"; - - case LANGUAGE_FRENCH: - return "fr"; - - case LANGUAGE_SPANISH: - return "es"; - - case LANGUAGE_JAPANESE: - return "ja"; - - case LANGUAGE_KOREAN: - return "ko"; - - case LANGUAGE_CHINESE: - return "zh"; - - case LANGUAGE_HEBREW: - return "he"; - - default: - return null; - } - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("BearerData "); - builder.append("{ messageType=" + messageType); - builder.append(", messageId=" + (int)messageId); - builder.append(", priority=" + (priorityIndicatorSet ? priority : "unset")); - builder.append(", privacy=" + (privacyIndicatorSet ? privacy : "unset")); - builder.append(", alert=" + (alertIndicatorSet ? alert : "unset")); - builder.append(", displayMode=" + (displayModeSet ? displayMode : "unset")); - builder.append(", language=" + (languageIndicatorSet ? language : "unset")); - builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset")); - builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset")); - builder.append(", msgCenterTimeStamp=" + - ((msgCenterTimeStamp != null) ? msgCenterTimeStamp : "unset")); - builder.append(", validityPeriodAbsolute=" + - ((validityPeriodAbsolute != null) ? validityPeriodAbsolute : "unset")); - builder.append(", validityPeriodRelative=" + - ((validityPeriodRelativeSet) ? validityPeriodRelative : "unset")); - builder.append(", deferredDeliveryTimeAbsolute=" + - ((deferredDeliveryTimeAbsolute != null) ? deferredDeliveryTimeAbsolute : "unset")); - builder.append(", deferredDeliveryTimeRelative=" + - ((deferredDeliveryTimeRelativeSet) ? deferredDeliveryTimeRelative : "unset")); - builder.append(", userAckReq=" + userAckReq); - builder.append(", deliveryAckReq=" + deliveryAckReq); - builder.append(", readAckReq=" + readAckReq); - builder.append(", reportReq=" + reportReq); - builder.append(", numberOfMessages=" + numberOfMessages); - builder.append(", callbackNumber=" + callbackNumber); - builder.append(", depositIndex=" + depositIndex); - builder.append(", hasUserDataHeader=" + hasUserDataHeader); - builder.append(", userData=" + userData); - builder.append(" }"); - return builder.toString(); - } - - private static void encodeMessageId(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 3); - outStream.write(4, bData.messageType); - outStream.write(8, bData.messageId >> 8); - outStream.write(8, bData.messageId); - outStream.write(1, bData.hasUserDataHeader ? 1 : 0); - outStream.skip(3); - } - - private static int countAsciiSeptets(CharSequence msg, boolean force) { - int msgLen = msg.length(); - if (force) return msgLen; - for (int i = 0; i < msgLen; i++) { - if (UserData.charToAscii.get(msg.charAt(i), -1) == -1) { - return -1; - } - } - return msgLen; - } - - /** - * Calculate the message text encoding length, fragmentation, and other details. - * - * @param msg message text - * @param force7BitEncoding ignore (but still count) illegal characters if true - * @return septet count, or -1 on failure - */ - public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg, - boolean force7BitEncoding) { - TextEncodingDetails ted; - int septets = countAsciiSeptets(msg, force7BitEncoding); - if (septets != -1 && septets <= SmsMessage.MAX_USER_DATA_SEPTETS) { - ted = new TextEncodingDetails(); - ted.msgCount = 1; - ted.codeUnitCount = septets; - ted.codeUnitsRemaining = SmsMessage.MAX_USER_DATA_SEPTETS - septets; - ted.codeUnitSize = SmsMessage.ENCODING_7BIT; - } else { - ted = com.android.internal.telephony.gsm.SmsMessage.calculateLength( - msg, force7BitEncoding); - if (ted.msgCount == 1 && ted.codeUnitSize == SmsMessage.ENCODING_7BIT) { - // We don't support single-segment EMS, so calculate for 16-bit - // TODO: Consider supporting single-segment EMS - ted.codeUnitCount = msg.length(); - int octets = ted.codeUnitCount * 2; - if (octets > MAX_USER_DATA_BYTES) { - ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) / - MAX_USER_DATA_BYTES_WITH_HEADER; - ted.codeUnitsRemaining = ((ted.msgCount * - MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2; - } else { - ted.msgCount = 1; - ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2; - } - ted.codeUnitSize = ENCODING_16BIT; - } - } - return ted; - } - - private static byte[] encode7bitAscii(String msg, boolean force) - throws CodingException - { - try { - BitwiseOutputStream outStream = new BitwiseOutputStream(msg.length()); - int msgLen = msg.length(); - for (int i = 0; i < msgLen; i++) { - int charCode = UserData.charToAscii.get(msg.charAt(i), -1); - if (charCode == -1) { - if (force) { - outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR); - } else { - throw new CodingException("cannot ASCII encode (" + msg.charAt(i) + ")"); - } - } else { - outStream.write(7, charCode); - } - } - return outStream.toByteArray(); - } catch (BitwiseOutputStream.AccessException ex) { - throw new CodingException("7bit ASCII encode failed: " + ex); - } - } - - private static byte[] encodeUtf16(String msg) - throws CodingException - { - try { - return msg.getBytes("utf-16be"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("UTF-16 encode failed: " + ex); - } - } - - private static class Gsm7bitCodingResult { - int septets; - byte[] data; - } - - private static Gsm7bitCodingResult encode7bitGsm(String msg, int septetOffset, boolean force) - throws CodingException - { - try { - /* - * TODO(cleanup): It would be nice if GsmAlphabet provided - * an option to produce just the data without prepending - * the septet count, as this function is really just a - * wrapper to strip that off. Not to mention that the - * septet count is generally known prior to invocation of - * the encoder. Note that it cannot be derived from the - * resulting array length, since that cannot distinguish - * if the last contains either 1 or 8 valid bits. - * - * TODO(cleanup): The BitwiseXStreams could also be - * extended with byte-wise reversed endianness read/write - * routines to allow a corresponding implementation of - * stringToGsm7BitPacked, and potentially directly support - * access to the main bitwise stream from encode/decode. - */ - byte[] fullData = GsmAlphabet.stringToGsm7BitPacked(msg, septetOffset, !force, 0, 0); - Gsm7bitCodingResult result = new Gsm7bitCodingResult(); - result.data = new byte[fullData.length - 1]; - System.arraycopy(fullData, 1, result.data, 0, fullData.length - 1); - result.septets = fullData[0] & 0x00FF; - return result; - } catch (com.android.internal.telephony.EncodeException ex) { - throw new CodingException("7bit GSM encode failed: " + ex); - } - } - - private static void encode7bitEms(UserData uData, byte[] udhData, boolean force) - throws CodingException - { - int udhBytes = udhData.length + 1; // Add length octet. - int udhSeptets = ((udhBytes * 8) + 6) / 7; - Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, udhSeptets, force); - uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; - uData.msgEncodingSet = true; - uData.numFields = gcr.septets; - uData.payload = gcr.data; - uData.payload[0] = (byte)udhData.length; - System.arraycopy(udhData, 0, uData.payload, 1, udhData.length); - } - - private static void encode16bitEms(UserData uData, byte[] udhData) - throws CodingException - { - byte[] payload = encodeUtf16(uData.payloadStr); - int udhBytes = udhData.length + 1; // Add length octet. - int udhCodeUnits = (udhBytes + 1) / 2; - int udhPadding = udhBytes % 2; - int payloadCodeUnits = payload.length / 2; - uData.msgEncoding = UserData.ENCODING_UNICODE_16; - uData.msgEncodingSet = true; - uData.numFields = udhCodeUnits + payloadCodeUnits; - uData.payload = new byte[uData.numFields * 2]; - uData.payload[0] = (byte)udhData.length; - System.arraycopy(udhData, 0, uData.payload, 1, udhData.length); - System.arraycopy(payload, 0, uData.payload, udhBytes + udhPadding, payload.length); - } - - private static void encodeEmsUserDataPayload(UserData uData) - throws CodingException - { - byte[] headerData = SmsHeader.toByteArray(uData.userDataHeader); - if (uData.msgEncodingSet) { - if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) { - encode7bitEms(uData, headerData, true); - } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) { - encode16bitEms(uData, headerData); - } else { - throw new CodingException("unsupported EMS user data encoding (" + - uData.msgEncoding + ")"); - } - } else { - try { - encode7bitEms(uData, headerData, false); - } catch (CodingException ex) { - encode16bitEms(uData, headerData); - } - } - } - - private static void encodeUserDataPayload(UserData uData) - throws CodingException - { - if ((uData.payloadStr == null) && (uData.msgEncoding != UserData.ENCODING_OCTET)) { - Log.e(LOG_TAG, "user data with null payloadStr"); - uData.payloadStr = ""; - } - - if (uData.userDataHeader != null) { - encodeEmsUserDataPayload(uData); - return; - } - - if (uData.msgEncodingSet) { - if (uData.msgEncoding == UserData.ENCODING_OCTET) { - if (uData.payload == null) { - Log.e(LOG_TAG, "user data with octet encoding but null payload"); - uData.payload = new byte[0]; - uData.numFields = 0; - } else { - uData.numFields = uData.payload.length; - } - } else { - if (uData.payloadStr == null) { - Log.e(LOG_TAG, "non-octet user data with null payloadStr"); - uData.payloadStr = ""; - } - if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) { - Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, 0, true); - uData.payload = gcr.data; - uData.numFields = gcr.septets; - } else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) { - uData.payload = encode7bitAscii(uData.payloadStr, true); - uData.numFields = uData.payloadStr.length(); - } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) { - uData.payload = encodeUtf16(uData.payloadStr); - uData.numFields = uData.payloadStr.length(); - } else { - throw new CodingException("unsupported user data encoding (" + - uData.msgEncoding + ")"); - } - } - } else { - try { - uData.payload = encode7bitAscii(uData.payloadStr, false); - uData.msgEncoding = UserData.ENCODING_7BIT_ASCII; - } catch (CodingException ex) { - uData.payload = encodeUtf16(uData.payloadStr); - uData.msgEncoding = UserData.ENCODING_UNICODE_16; - } - uData.numFields = uData.payloadStr.length(); - uData.msgEncodingSet = true; - } - } - - private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException, CodingException - { - /* - * TODO(cleanup): Do we really need to set userData.payload as - * a side effect of encoding? If not, we could avoid data - * copies by passing outStream directly. - */ - encodeUserDataPayload(bData.userData); - bData.hasUserDataHeader = bData.userData.userDataHeader != null; - - if (bData.userData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) { - throw new CodingException("encoded user data too large (" + - bData.userData.payload.length + - " > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)"); - } - - /* - * TODO(cleanup): figure out what the right answer is WRT paddingBits field - * - * userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7); - * userData.paddingBits = 0; // XXX this seems better, but why? - * - */ - int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits; - int paramBits = dataBits + 13; - if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || - (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { - paramBits += 8; - } - int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0); - int paddingBits = (paramBytes * 8) - paramBits; - outStream.write(8, paramBytes); - outStream.write(5, bData.userData.msgEncoding); - if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || - (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { - outStream.write(8, bData.userData.msgType); - } - outStream.write(8, bData.userData.numFields); - outStream.writeByteArray(dataBits, bData.userData.payload); - if (paddingBits > 0) outStream.write(paddingBits, 0); - } - - private static void encodeReplyOption(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(1, bData.userAckReq ? 1 : 0); - outStream.write(1, bData.deliveryAckReq ? 1 : 0); - outStream.write(1, bData.readAckReq ? 1 : 0); - outStream.write(1, bData.reportReq ? 1 : 0); - outStream.write(4, 0); - } - - private static byte[] encodeDtmfSmsAddress(String address) { - int digits = address.length(); - int dataBits = digits * 4; - int dataBytes = (dataBits / 8); - dataBytes += (dataBits % 8) > 0 ? 1 : 0; - byte[] rawData = new byte[dataBytes]; - for (int i = 0; i < digits; i++) { - char c = address.charAt(i); - int val = 0; - if ((c >= '1') && (c <= '9')) val = c - '0'; - else if (c == '0') val = 10; - else if (c == '*') val = 11; - else if (c == '#') val = 12; - else return null; - rawData[i / 2] |= val << (4 - ((i % 2) * 4)); - } - return rawData; - } - - /* - * TODO(cleanup): CdmaSmsAddress encoding should make use of - * CdmaSmsAddress.parse provided that DTMF encoding is unified, - * and the difference in 4-bit vs. 8-bit is resolved. - */ - - private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException { - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - try { - addr.origBytes = addr.address.getBytes("US-ASCII"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("invalid SMS address, cannot convert to ASCII"); - } - } else { - addr.origBytes = encodeDtmfSmsAddress(addr.address); - } - } - - private static void encodeCallbackNumber(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException, CodingException - { - CdmaSmsAddress addr = bData.callbackNumber; - encodeCdmaSmsAddress(addr); - int paramBits = 9; - int dataBits = 0; - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - paramBits += 7; - dataBits = addr.numberOfDigits * 8; - } else { - dataBits = addr.numberOfDigits * 4; - } - paramBits += dataBits; - int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0); - int paddingBits = (paramBytes * 8) - paramBits; - outStream.write(8, paramBytes); - outStream.write(1, addr.digitMode); - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - outStream.write(3, addr.ton); - outStream.write(4, addr.numberPlan); - } - outStream.write(8, addr.numberOfDigits); - outStream.writeByteArray(dataBits, addr.origBytes); - if (paddingBits > 0) outStream.write(paddingBits, 0); - } - - private static void encodeMsgStatus(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(2, bData.errorClass); - outStream.write(6, bData.messageStatus); - } - - private static void encodeMsgCount(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(8, bData.numberOfMessages); - } - - private static void encodeValidityPeriodRel(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(8, bData.validityPeriodRelative); - } - - private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(2, bData.privacy); - outStream.skip(6); - } - - private static void encodeLanguageIndicator(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(8, bData.language); - } - - private static void encodeDisplayMode(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(2, bData.displayMode); - outStream.skip(6); - } - - private static void encodePriorityIndicator(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(2, bData.priority); - outStream.skip(6); - } - - private static void encodeMsgDeliveryAlert(BearerData bData, BitwiseOutputStream outStream) - throws BitwiseOutputStream.AccessException - { - outStream.write(8, 1); - outStream.write(2, bData.alert); - outStream.skip(6); - } - - /** - * Create serialized representation for BearerData object. - * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) - * - * @param bData an instance of BearerData. - * - * @return byte array of raw encoded SMS bearer data. - */ - public static byte[] encode(BearerData bData) { - bData.hasUserDataHeader = ((bData.userData != null) && - (bData.userData.userDataHeader != null)); - try { - BitwiseOutputStream outStream = new BitwiseOutputStream(200); - outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER); - encodeMessageId(bData, outStream); - if (bData.userData != null) { - outStream.write(8, SUBPARAM_USER_DATA); - encodeUserData(bData, outStream); - } - if (bData.callbackNumber != null) { - outStream.write(8, SUBPARAM_CALLBACK_NUMBER); - encodeCallbackNumber(bData, outStream); - } - if (bData.userAckReq || bData.deliveryAckReq || bData.readAckReq || bData.reportReq) { - outStream.write(8, SUBPARAM_REPLY_OPTION); - encodeReplyOption(bData, outStream); - } - if (bData.numberOfMessages != 0) { - outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES); - encodeMsgCount(bData, outStream); - } - if (bData.validityPeriodRelativeSet) { - outStream.write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE); - encodeValidityPeriodRel(bData, outStream); - } - if (bData.privacyIndicatorSet) { - outStream.write(8, SUBPARAM_PRIVACY_INDICATOR); - encodePrivacyIndicator(bData, outStream); - } - if (bData.languageIndicatorSet) { - outStream.write(8, SUBPARAM_LANGUAGE_INDICATOR); - encodeLanguageIndicator(bData, outStream); - } - if (bData.displayModeSet) { - outStream.write(8, SUBPARAM_MESSAGE_DISPLAY_MODE); - encodeDisplayMode(bData, outStream); - } - if (bData.priorityIndicatorSet) { - outStream.write(8, SUBPARAM_PRIORITY_INDICATOR); - encodePriorityIndicator(bData, outStream); - } - if (bData.alertIndicatorSet) { - outStream.write(8, SUBPARAM_ALERT_ON_MESSAGE_DELIVERY); - encodeMsgDeliveryAlert(bData, outStream); - } - if (bData.messageStatusSet) { - outStream.write(8, SUBPARAM_MESSAGE_STATUS); - encodeMsgStatus(bData, outStream); - } - return outStream.toByteArray(); - } catch (BitwiseOutputStream.AccessException ex) { - Log.e(LOG_TAG, "BearerData encode failed: " + ex); - } catch (CodingException ex) { - Log.e(LOG_TAG, "BearerData encode failed: " + ex); - } - return null; - } - - private static boolean decodeMessageId(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 3 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.messageType = inStream.read(4); - bData.messageId = inStream.read(8) << 8; - bData.messageId |= inStream.read(8); - bData.hasUserDataHeader = (inStream.read(1) == 1); - inStream.skip(3); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeUserData(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException - { - int paramBits = inStream.read(8) * 8; - bData.userData = new UserData(); - bData.userData.msgEncoding = inStream.read(5); - bData.userData.msgEncodingSet = true; - bData.userData.msgType = 0; - int consumedBits = 5; - if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || - (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { - bData.userData.msgType = inStream.read(8); - consumedBits += 8; - } - bData.userData.numFields = inStream.read(8); - consumedBits += 8; - int dataBits = paramBits - consumedBits; - bData.userData.payload = inStream.readByteArray(dataBits); - return true; - } - - private static String decodeUtf8(byte[] data, int offset, int numFields) - throws CodingException - { - if (numFields < 0 || (numFields + offset) > data.length) { - throw new CodingException("UTF-8 decode failed: offset or length out of range"); - } - try { - return new String(data, offset, numFields, "UTF-8"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("UTF-8 decode failed: " + ex); - } - } - - private static String decodeUtf16(byte[] data, int offset, int numFields) - throws CodingException - { - int byteCount = numFields * 2; - if (byteCount < 0 || (byteCount + offset) > data.length) { - throw new CodingException("UTF-16 decode failed: offset or length out of range"); - } - try { - return new String(data, offset, byteCount, "utf-16be"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("UTF-16 decode failed: " + ex); - } - } - - private static String decode7bitAscii(byte[] data, int offset, int numFields) - throws CodingException - { - try { - offset *= 8; - StringBuffer strBuf = new StringBuffer(numFields); - BitwiseInputStream inStream = new BitwiseInputStream(data); - int wantedBits = (offset * 8) + (numFields * 7); - if (inStream.available() < wantedBits) { - throw new CodingException("insufficient data (wanted " + wantedBits + - " bits, but only have " + inStream.available() + ")"); - } - inStream.skip(offset); - for (int i = 0; i < numFields; i++) { - int charCode = inStream.read(7); - if ((charCode >= UserData.ASCII_MAP_BASE_INDEX) && - (charCode <= UserData.ASCII_MAP_MAX_INDEX)) { - strBuf.append(UserData.ASCII_MAP[charCode - UserData.ASCII_MAP_BASE_INDEX]); - } else if (charCode == UserData.ASCII_NL_INDEX) { - strBuf.append('\n'); - } else if (charCode == UserData.ASCII_CR_INDEX) { - strBuf.append('\r'); - } else { - /* For other charCodes, they are unprintable, and so simply use SPACE. */ - strBuf.append(' '); - } - } - return strBuf.toString(); - } catch (BitwiseInputStream.AccessException ex) { - throw new CodingException("7bit ASCII decode failed: " + ex); - } - } - - private static String decode7bitGsm(byte[] data, int offset, int numFields) - throws CodingException - { - // Start reading from the next 7-bit aligned boundary after offset. - int offsetBits = offset * 8; - int offsetSeptets = (offsetBits + 6) / 7; - numFields -= offsetSeptets; - int paddingBits = (offsetSeptets * 7) - offsetBits; - String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits, - 0, 0); - if (result == null) { - throw new CodingException("7bit GSM decoding failed"); - } - return result; - } - - private static String decodeLatin(byte[] data, int offset, int numFields) - throws CodingException - { - if (numFields < 0 || (numFields + offset) > data.length) { - throw new CodingException("ISO-8859-1 decode failed: offset or length out of range"); - } - try { - return new String(data, offset, numFields, "ISO-8859-1"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("ISO-8859-1 decode failed: " + ex); - } - } - - private static void decodeUserDataPayload(UserData userData, boolean hasUserDataHeader) - throws CodingException - { - int offset = 0; - if (hasUserDataHeader) { - int udhLen = userData.payload[0] & 0x00FF; - offset += udhLen + 1; - byte[] headerData = new byte[udhLen]; - System.arraycopy(userData.payload, 1, headerData, 0, udhLen); - userData.userDataHeader = SmsHeader.fromByteArray(headerData); - } - switch (userData.msgEncoding) { - case UserData.ENCODING_OCTET: - /* - * Octet decoding depends on the carrier service. - */ - boolean decodingtypeUTF8 = Resources.getSystem() - .getBoolean(com.android.internal.R.bool.config_sms_utf8_support); - - // Strip off any padding bytes, meaning any differences between the length of the - // array and the target length specified by numFields. This is to avoid any - // confusion by code elsewhere that only considers the payload array length. - byte[] payload = new byte[userData.numFields]; - int copyLen = userData.numFields < userData.payload.length - ? userData.numFields : userData.payload.length; - - System.arraycopy(userData.payload, 0, payload, 0, copyLen); - userData.payload = payload; - - if (!decodingtypeUTF8) { - // There are many devices in the market that send 8bit text sms (latin encoded) as - // octet encoded. - userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields); - } else { - userData.payloadStr = decodeUtf8(userData.payload, offset, userData.numFields); - } - break; - - case UserData.ENCODING_IA5: - case UserData.ENCODING_7BIT_ASCII: - userData.payloadStr = decode7bitAscii(userData.payload, offset, userData.numFields); - break; - case UserData.ENCODING_UNICODE_16: - userData.payloadStr = decodeUtf16(userData.payload, offset, userData.numFields); - break; - case UserData.ENCODING_GSM_7BIT_ALPHABET: - userData.payloadStr = decode7bitGsm(userData.payload, offset, userData.numFields); - break; - case UserData.ENCODING_LATIN: - userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields); - break; - default: - throw new CodingException("unsupported user data encoding (" - + userData.msgEncoding + ")"); - } - } - - /** - * IS-91 Voice Mail message decoding - * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) - * (For character encodings, see TIA/EIA/IS-91, Annex B) - * - * Protocol Summary: The user data payload may contain 3-14 - * characters. The first two characters are parsed as a number - * and indicate the number of voicemails. The third character is - * either a SPACE or '!' to indicate normal or urgent priority, - * respectively. Any following characters are treated as normal - * text user data payload. - * - * Note that the characters encoding is 6-bit packed. - */ - private static void decodeIs91VoicemailStatus(BearerData bData) - throws BitwiseInputStream.AccessException, CodingException - { - BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); - int dataLen = inStream.available() / 6; // 6-bit packed character encoding. - int numFields = bData.userData.numFields; - if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { - throw new CodingException("IS-91 voicemail status decoding failed"); - } - try { - StringBuffer strbuf = new StringBuffer(dataLen); - while (inStream.available() >= 6) { - strbuf.append(UserData.ASCII_MAP[inStream.read(6)]); - } - String data = strbuf.toString(); - bData.numberOfMessages = Integer.parseInt(data.substring(0, 2)); - char prioCode = data.charAt(2); - if (prioCode == ' ') { - bData.priority = PRIORITY_NORMAL; - } else if (prioCode == '!') { - bData.priority = PRIORITY_URGENT; - } else { - throw new CodingException("IS-91 voicemail status decoding failed: " + - "illegal priority setting (" + prioCode + ")"); - } - bData.priorityIndicatorSet = true; - bData.userData.payloadStr = data.substring(3, numFields - 3); - } catch (java.lang.NumberFormatException ex) { - throw new CodingException("IS-91 voicemail status decoding failed: " + ex); - } catch (java.lang.IndexOutOfBoundsException ex) { - throw new CodingException("IS-91 voicemail status decoding failed: " + ex); - } - } - - /** - * IS-91 Short Message decoding - * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) - * (For character encodings, see TIA/EIA/IS-91, Annex B) - * - * Protocol Summary: The user data payload may contain 1-14 - * characters, which are treated as normal text user data payload. - * Note that the characters encoding is 6-bit packed. - */ - private static void decodeIs91ShortMessage(BearerData bData) - throws BitwiseInputStream.AccessException, CodingException - { - BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); - int dataLen = inStream.available() / 6; // 6-bit packed character encoding. - int numFields = bData.userData.numFields; - // dataLen may be > 14 characters due to octet padding - if ((numFields > 14) || (dataLen < numFields)) { - throw new CodingException("IS-91 short message decoding failed"); - } - StringBuffer strbuf = new StringBuffer(dataLen); - for (int i = 0; i < numFields; i++) { - strbuf.append(UserData.ASCII_MAP[inStream.read(6)]); - } - bData.userData.payloadStr = strbuf.toString(); - } - - /** - * IS-91 CLI message (callback number) decoding - * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1) - * - * Protocol Summary: The data payload may contain 1-32 digits, - * encoded using standard 4-bit DTMF, which are treated as a - * callback number. - */ - private static void decodeIs91Cli(BearerData bData) throws CodingException { - BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); - int dataLen = inStream.available() / 4; // 4-bit packed DTMF digit encoding. - int numFields = bData.userData.numFields; - if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) { - throw new CodingException("IS-91 voicemail status decoding failed"); - } - CdmaSmsAddress addr = new CdmaSmsAddress(); - addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF; - addr.origBytes = bData.userData.payload; - addr.numberOfDigits = (byte)numFields; - decodeSmsAddress(addr); - bData.callbackNumber = addr; - } - - private static void decodeIs91(BearerData bData) - throws BitwiseInputStream.AccessException, CodingException - { - switch (bData.userData.msgType) { - case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS: - decodeIs91VoicemailStatus(bData); - break; - case UserData.IS91_MSG_TYPE_CLI: - decodeIs91Cli(bData); - break; - case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL: - case UserData.IS91_MSG_TYPE_SHORT_MESSAGE: - decodeIs91ShortMessage(bData); - break; - default: - throw new CodingException("unsupported IS-91 message type (" + - bData.userData.msgType + ")"); - } - } - - private static boolean decodeReplyOption(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.userAckReq = (inStream.read(1) == 1); - bData.deliveryAckReq = (inStream.read(1) == 1); - bData.readAckReq = (inStream.read(1) == 1); - bData.reportReq = (inStream.read(1) == 1); - inStream.skip(4); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "REPLY_OPTION decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeMsgCount(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.numberOfMessages = IccUtils.cdmaBcdByteToInt((byte)inStream.read(8)); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeDepositIndex(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 2 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static String decodeDtmfSmsAddress(byte[] rawData, int numFields) - throws CodingException - { - /* DTMF 4-bit digit encoding, defined in at - * 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */ - StringBuffer strBuf = new StringBuffer(numFields); - for (int i = 0; i < numFields; i++) { - int val = 0x0F & (rawData[i / 2] >>> (4 - ((i % 2) * 4))); - if ((val >= 1) && (val <= 9)) strBuf.append(Integer.toString(val, 10)); - else if (val == 10) strBuf.append('0'); - else if (val == 11) strBuf.append('*'); - else if (val == 12) strBuf.append('#'); - else throw new CodingException("invalid SMS address DTMF code (" + val + ")"); - } - return strBuf.toString(); - } - - private static void decodeSmsAddress(CdmaSmsAddress addr) throws CodingException { - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - try { - /* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually - * just 7-bit ASCII encoding, with the MSB being zero. */ - addr.address = new String(addr.origBytes, 0, addr.origBytes.length, "US-ASCII"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new CodingException("invalid SMS address ASCII code"); - } - } else { - addr.address = decodeDtmfSmsAddress(addr.origBytes, addr.numberOfDigits); - } - } - - private static boolean decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - int paramBits = inStream.read(8) * 8; - CdmaSmsAddress addr = new CdmaSmsAddress(); - addr.digitMode = inStream.read(1); - byte fieldBits = 4; - byte consumedBits = 1; - if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { - addr.ton = inStream.read(3); - addr.numberPlan = inStream.read(4); - fieldBits = 8; - consumedBits += 7; - } - addr.numberOfDigits = inStream.read(8); - consumedBits += 8; - int remainingBits = paramBits - consumedBits; - int dataBits = addr.numberOfDigits * fieldBits; - int paddingBits = remainingBits - dataBits; - if (remainingBits < dataBits) { - throw new CodingException("CALLBACK_NUMBER subparam encoding size error (" + - "remainingBits + " + remainingBits + ", dataBits + " + - dataBits + ", paddingBits + " + paddingBits + ")"); - } - addr.origBytes = inStream.readByteArray(dataBits); - inStream.skip(paddingBits); - decodeSmsAddress(addr); - bData.callbackNumber = addr; - return true; - } - - private static boolean decodeMsgStatus(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.errorClass = inStream.read(2); - bData.messageStatus = inStream.read(6); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "MESSAGE_STATUS decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.messageStatusSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeMsgCenterTimeStamp(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 6 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8)); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeValidityAbs(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 6 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8)); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeDeferredDeliveryAbs(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 6 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray( - inStream.readByteArray(6 * 8)); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - return decodeSuccess; - } - - private static boolean decodeValidityRel(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.deferredDeliveryTimeRelative = inStream.read(8); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.deferredDeliveryTimeRelativeSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeDeferredDeliveryRel(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.validityPeriodRelative = inStream.read(8); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.validityPeriodRelativeSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.privacy = inStream.read(2); - inStream.skip(6); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "PRIVACY_INDICATOR decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.privacyIndicatorSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeLanguageIndicator(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.language = inStream.read(8); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "LANGUAGE_INDICATOR decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.languageIndicatorSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeDisplayMode(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.displayMode = inStream.read(2); - inStream.skip(6); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "DISPLAY_MODE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.displayModeSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodePriorityIndicator(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.priority = inStream.read(2); - inStream.skip(6); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "PRIORITY_INDICATOR decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.priorityIndicatorSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeMsgDeliveryAlert(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.alert = inStream.read(2); - inStream.skip(6); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.alertIndicatorSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeUserResponseCode(BearerData bData, BitwiseInputStream inStream) - throws BitwiseInputStream.AccessException, CodingException - { - final int EXPECTED_PARAM_SIZE = 1 * 8; - boolean decodeSuccess = false; - int paramBits = inStream.read(8) * 8; - if (paramBits >= EXPECTED_PARAM_SIZE) { - paramBits -= EXPECTED_PARAM_SIZE; - decodeSuccess = true; - bData.userResponseCode = inStream.read(8); - } - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "USER_RESPONSE_CODE decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ")"); - } - inStream.skip(paramBits); - bData.userResponseCodeSet = decodeSuccess; - return decodeSuccess; - } - - private static boolean decodeServiceCategoryProgramData(BearerData bData, - BitwiseInputStream inStream) throws BitwiseInputStream.AccessException, CodingException - { - if (inStream.available() < 13) { - throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only " - + inStream.available() + " bits available"); - } - - int paramBits = inStream.read(8) * 8; - int msgEncoding = inStream.read(5); - paramBits -= 5; - - if (inStream.available() < paramBits) { - throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only " - + inStream.available() + " bits available (" + paramBits + " bits expected)"); - } - - ArrayList programDataList = new ArrayList(); - - final int CATEGORY_FIELD_MIN_SIZE = 6 * 8; - boolean decodeSuccess = false; - while (paramBits >= CATEGORY_FIELD_MIN_SIZE) { - int operation = inStream.read(4); - int category = (inStream.read(8) << 8) | inStream.read(8); - String language = getLanguageCodeForValue(inStream.read(8)); - int maxMessages = inStream.read(8); - int alertOption = inStream.read(4); - int numFields = inStream.read(8); - paramBits -= CATEGORY_FIELD_MIN_SIZE; - - int textBits = getBitsForNumFields(msgEncoding, numFields); - if (paramBits < textBits) { - throw new CodingException("category name is " + textBits + " bits in length," - + " but there are only " + paramBits + " bits available"); - } - - UserData userData = new UserData(); - userData.msgEncoding = msgEncoding; - userData.msgEncodingSet = true; - userData.numFields = numFields; - userData.payload = inStream.readByteArray(textBits); - paramBits -= textBits; - - decodeUserDataPayload(userData, false); - String categoryName = userData.payloadStr; - CdmaSmsCbProgramData programData = new CdmaSmsCbProgramData(operation, category, - language, maxMessages, alertOption, categoryName); - programDataList.add(programData); - - decodeSuccess = true; - } - - if ((! decodeSuccess) || (paramBits > 0)) { - Log.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " + - (decodeSuccess ? "succeeded" : "failed") + - " (extra bits = " + paramBits + ')'); - } - - inStream.skip(paramBits); - bData.serviceCategoryProgramData = programDataList; - return decodeSuccess; - } - - private static int serviceCategoryToCmasMessageClass(int serviceCategory) { - switch (serviceCategory) { - case SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT: - return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT; - - case SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT: - return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT; - - case SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT: - return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT; - - case SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY: - return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY; - - case SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE: - return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST; - - default: - return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN; - } - } - - /** - * Calculates the number of bits to read for the specified number of encoded characters. - * @param msgEncoding the message encoding to use - * @param numFields the number of characters to read. For Shift-JIS and Korean encodings, - * this is the number of bytes to read. - * @return the number of bits to read from the stream - * @throws CodingException if the specified encoding is not supported - */ - private static int getBitsForNumFields(int msgEncoding, int numFields) - throws CodingException { - switch (msgEncoding) { - case UserData.ENCODING_OCTET: - case UserData.ENCODING_SHIFT_JIS: - case UserData.ENCODING_KOREAN: - case UserData.ENCODING_LATIN: - case UserData.ENCODING_LATIN_HEBREW: - return numFields * 8; - - case UserData.ENCODING_IA5: - case UserData.ENCODING_7BIT_ASCII: - case UserData.ENCODING_GSM_7BIT_ALPHABET: - return numFields * 7; - - case UserData.ENCODING_UNICODE_16: - return numFields * 16; - - default: - throw new CodingException("unsupported message encoding (" + msgEncoding + ')'); - } - } - - /** - * CMAS message decoding. - * (See TIA-1149-0-1, CMAS over CDMA) - * - * @param serviceCategory is the service category from the SMS envelope - */ - private static void decodeCmasUserData(BearerData bData, int serviceCategory) - throws BitwiseInputStream.AccessException, CodingException { - BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload); - if (inStream.available() < 8) { - throw new CodingException("emergency CB with no CMAE_protocol_version"); - } - int protocolVersion = inStream.read(8); - if (protocolVersion != 0) { - throw new CodingException("unsupported CMAE_protocol_version " + protocolVersion); - } - - int messageClass = serviceCategoryToCmasMessageClass(serviceCategory); - int category = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN; - int responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN; - int severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; - int urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; - int certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; - - while (inStream.available() >= 16) { - int recordType = inStream.read(8); - int recordLen = inStream.read(8); - switch (recordType) { - case 0: // Type 0 elements (Alert text) - UserData alertUserData = new UserData(); - alertUserData.msgEncoding = inStream.read(5); - alertUserData.msgEncodingSet = true; - alertUserData.msgType = 0; - - int numFields; // number of chars to decode - switch (alertUserData.msgEncoding) { - case UserData.ENCODING_OCTET: - case UserData.ENCODING_LATIN: - numFields = recordLen - 1; // subtract 1 byte for encoding - break; - - case UserData.ENCODING_IA5: - case UserData.ENCODING_7BIT_ASCII: - case UserData.ENCODING_GSM_7BIT_ALPHABET: - numFields = ((recordLen * 8) - 5) / 7; // subtract 5 bits for encoding - break; - - case UserData.ENCODING_UNICODE_16: - numFields = (recordLen - 1) / 2; - break; - - default: - numFields = 0; // unsupported encoding - } - - alertUserData.numFields = numFields; - alertUserData.payload = inStream.readByteArray(recordLen * 8 - 5); - decodeUserDataPayload(alertUserData, false); - bData.userData = alertUserData; - break; - - case 1: // Type 1 elements - category = inStream.read(8); - responseType = inStream.read(8); - severity = inStream.read(4); - urgency = inStream.read(4); - certainty = inStream.read(4); - inStream.skip(recordLen * 8 - 28); - break; - - default: - Log.w(LOG_TAG, "skipping unsupported CMAS record type " + recordType); - inStream.skip(recordLen * 8); - break; - } - } - - bData.cmasWarningInfo = new SmsCbCmasInfo(messageClass, category, responseType, severity, - urgency, certainty); - } - - /** - * Create BearerData object from serialized representation. - * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) - * - * @param smsData byte array of raw encoded SMS bearer data. - * @return an instance of BearerData. - */ - public static BearerData decode(byte[] smsData) { - return decode(smsData, 0); - } - - private static boolean isCmasAlertCategory(int category) { - return category >= SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT - && category <= SmsEnvelope.SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE; - } - - /** - * Create BearerData object from serialized representation. - * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) - * - * @param smsData byte array of raw encoded SMS bearer data. - * @param serviceCategory the envelope service category (for CMAS alert handling) - * @return an instance of BearerData. - */ - public static BearerData decode(byte[] smsData, int serviceCategory) { - try { - BitwiseInputStream inStream = new BitwiseInputStream(smsData); - BearerData bData = new BearerData(); - int foundSubparamMask = 0; - while (inStream.available() > 0) { - int subparamId = inStream.read(8); - int subparamIdBit = 1 << subparamId; - if ((foundSubparamMask & subparamIdBit) != 0) { - throw new CodingException("illegal duplicate subparameter (" + - subparamId + ")"); - } - boolean decodeSuccess; - switch (subparamId) { - case SUBPARAM_MESSAGE_IDENTIFIER: - decodeSuccess = decodeMessageId(bData, inStream); - break; - case SUBPARAM_USER_DATA: - decodeSuccess = decodeUserData(bData, inStream); - break; - case SUBPARAM_USER_RESPONSE_CODE: - decodeSuccess = decodeUserResponseCode(bData, inStream); - break; - case SUBPARAM_REPLY_OPTION: - decodeSuccess = decodeReplyOption(bData, inStream); - break; - case SUBPARAM_NUMBER_OF_MESSAGES: - decodeSuccess = decodeMsgCount(bData, inStream); - break; - case SUBPARAM_CALLBACK_NUMBER: - decodeSuccess = decodeCallbackNumber(bData, inStream); - break; - case SUBPARAM_MESSAGE_STATUS: - decodeSuccess = decodeMsgStatus(bData, inStream); - break; - case SUBPARAM_MESSAGE_CENTER_TIME_STAMP: - decodeSuccess = decodeMsgCenterTimeStamp(bData, inStream); - break; - case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE: - decodeSuccess = decodeValidityAbs(bData, inStream); - break; - case SUBPARAM_VALIDITY_PERIOD_RELATIVE: - decodeSuccess = decodeValidityRel(bData, inStream); - break; - case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE: - decodeSuccess = decodeDeferredDeliveryAbs(bData, inStream); - break; - case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE: - decodeSuccess = decodeDeferredDeliveryRel(bData, inStream); - break; - case SUBPARAM_PRIVACY_INDICATOR: - decodeSuccess = decodePrivacyIndicator(bData, inStream); - break; - case SUBPARAM_LANGUAGE_INDICATOR: - decodeSuccess = decodeLanguageIndicator(bData, inStream); - break; - case SUBPARAM_MESSAGE_DISPLAY_MODE: - decodeSuccess = decodeDisplayMode(bData, inStream); - break; - case SUBPARAM_PRIORITY_INDICATOR: - decodeSuccess = decodePriorityIndicator(bData, inStream); - break; - case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY: - decodeSuccess = decodeMsgDeliveryAlert(bData, inStream); - break; - case SUBPARAM_MESSAGE_DEPOSIT_INDEX: - decodeSuccess = decodeDepositIndex(bData, inStream); - break; - case SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA: - decodeSuccess = decodeServiceCategoryProgramData(bData, inStream); - break; - default: - throw new CodingException("unsupported bearer data subparameter (" - + subparamId + ")"); - } - if (decodeSuccess) foundSubparamMask |= subparamIdBit; - } - if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) { - throw new CodingException("missing MESSAGE_IDENTIFIER subparam"); - } - if (bData.userData != null) { - if (isCmasAlertCategory(serviceCategory)) { - decodeCmasUserData(bData, serviceCategory); - } else if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) { - if ((foundSubparamMask ^ - (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^ - (1 << SUBPARAM_USER_DATA)) - != 0) { - Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" + - foundSubparamMask + ")"); - } - decodeIs91(bData); - } else { - decodeUserDataPayload(bData.userData, bData.hasUserDataHeader); - } - } - return bData; - } catch (BitwiseInputStream.AccessException ex) { - Log.e(LOG_TAG, "BearerData decode failed: " + ex); - } catch (CodingException ex) { - Log.e(LOG_TAG, "BearerData decode failed: " + ex); - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java deleted file mode 100644 index 5f2e561b687f..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java +++ /dev/null @@ -1,228 +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.sms; - -import android.util.SparseBooleanArray; - -import com.android.internal.telephony.SmsAddress; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.HexDump; - -public class CdmaSmsAddress extends SmsAddress { - - /** - * Digit Mode Indicator is a 1-bit value that indicates whether - * the address digits are 4-bit DTMF codes or 8-bit codes. (See - * 3GPP2 C.S0015-B, v2, 3.4.3.3) - */ - static public final int DIGIT_MODE_4BIT_DTMF = 0x00; - static public final int DIGIT_MODE_8BIT_CHAR = 0x01; - - public int digitMode; - - /** - * Number Mode Indicator is 1-bit value that indicates whether the - * address type is a data network address or not. (See 3GPP2 - * C.S0015-B, v2, 3.4.3.3) - */ - static public final int NUMBER_MODE_NOT_DATA_NETWORK = 0x00; - static public final int NUMBER_MODE_DATA_NETWORK = 0x01; - - public int numberMode; - - /** - * Number Types for data networks. - * (See 3GPP2 C.S005-D, table2.7.1.3.2.4-2 for complete table) - * (See 3GPP2 C.S0015-B, v2, 3.4.3.3 for data network subset) - * NOTE: value is stored in the parent class ton field. - */ - static public final int TON_UNKNOWN = 0x00; - static public final int TON_INTERNATIONAL_OR_IP = 0x01; - 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; - - /** - * This field shall be set to the number of address digits - * (See 3GPP2 C.S0015-B, v2, 3.4.3.3) - */ - public int numberOfDigits; - - /** - * Numbering Plan identification is a 0 or 4-bit value that - * indicates which numbering plan identification is set. (See - * 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3) - */ - static public final int NUMBERING_PLAN_UNKNOWN = 0x0; - static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1; - //static protected final int NUMBERING_PLAN_DATA = 0x3; - //static protected final int NUMBERING_PLAN_TELEX = 0x4; - //static protected final int NUMBERING_PLAN_PRIVATE = 0x9; - - public int numberPlan; - - /** - * NOTE: the parsed string address and the raw byte array values - * are stored in the parent class address and origBytes fields, - * respectively. - */ - - public CdmaSmsAddress(){ - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("CdmaSmsAddress "); - builder.append("{ digitMode=" + digitMode); - builder.append(", numberMode=" + numberMode); - builder.append(", numberPlan=" + numberPlan); - builder.append(", numberOfDigits=" + numberOfDigits); - builder.append(", ton=" + ton); - builder.append(", address=\"" + address + "\""); - builder.append(", origBytes=" + HexDump.toHexString(origBytes)); - builder.append(" }"); - return builder.toString(); - } - - /* - * TODO(cleanup): Refactor the parsing for addresses to better - * share code and logic with GSM. Also, gather all DTMF/BCD - * processing code in one place. - */ - - private static byte[] parseToDtmf(String address) { - int digits = address.length(); - byte[] result = new byte[digits]; - for (int i = 0; i < digits; i++) { - char c = address.charAt(i); - int val = 0; - if ((c >= '1') && (c <= '9')) val = c - '0'; - else if (c == '0') val = 10; - else if (c == '*') val = 11; - else if (c == '#') val = 12; - else return null; - result[i] = (byte)val; - } - return result; - } - - private static final char[] numericCharsDialable = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#' - }; - - private static final char[] numericCharsSugar = { - '(', ')', ' ', '-', '+', '.', '/', '\\' - }; - - private static final SparseBooleanArray numericCharDialableMap = new SparseBooleanArray ( - numericCharsDialable.length + numericCharsSugar.length); - static { - for (int i = 0; i < numericCharsDialable.length; i++) { - numericCharDialableMap.put(numericCharsDialable[i], true); - } - for (int i = 0; i < numericCharsSugar.length; i++) { - numericCharDialableMap.put(numericCharsSugar[i], false); - } - } - - /** - * Given a numeric address string, return the string without - * syntactic sugar, meaning parens, spaces, hyphens/minuses, or - * plus signs. If the input string contains non-numeric - * non-punctuation characters, return null. - */ - private static String filterNumericSugar(String address) { - StringBuilder builder = new StringBuilder(); - int len = address.length(); - for (int i = 0; i < len; i++) { - char c = address.charAt(i); - int mapIndex = numericCharDialableMap.indexOfKey(c); - if (mapIndex < 0) return null; - if (! numericCharDialableMap.valueAt(mapIndex)) continue; - builder.append(c); - } - return builder.toString(); - } - - /** - * Given a string, return the string without whitespace, - * including CR/LF. - */ - private static String filterWhitespace(String address) { - StringBuilder builder = new StringBuilder(); - int len = address.length(); - for (int i = 0; i < len; i++) { - char c = address.charAt(i); - if ((c == ' ') || (c == '\r') || (c == '\n') || (c == '\t')) continue; - builder.append(c); - } - return builder.toString(); - } - - /** - * Given a string, create a corresponding CdmaSmsAddress object. - * - * The result will be null if the input string is not - * representable using printable ASCII. - * - * For numeric addresses, the string is cleaned up by removing - * common punctuation. For alpha addresses, the string is cleaned - * up by removing whitespace. - */ - public static CdmaSmsAddress parse(String address) { - CdmaSmsAddress addr = new CdmaSmsAddress(); - addr.address = address; - addr.ton = CdmaSmsAddress.TON_UNKNOWN; - byte[] origBytes = null; - String filteredAddr = filterNumericSugar(address); - if (filteredAddr != null) { - origBytes = parseToDtmf(filteredAddr); - } - if (origBytes != null) { - addr.digitMode = DIGIT_MODE_4BIT_DTMF; - addr.numberMode = NUMBER_MODE_NOT_DATA_NETWORK; - if (address.indexOf('+') != -1) { - addr.ton = TON_INTERNATIONAL_OR_IP; - } - } else { - filteredAddr = filterWhitespace(address); - origBytes = UserData.stringToAscii(filteredAddr); - if (origBytes == null) { - return null; - } - addr.digitMode = DIGIT_MODE_8BIT_CHAR; - addr.numberMode = NUMBER_MODE_DATA_NETWORK; - if (address.indexOf('@') != -1) { - addr.ton = TON_NATIONAL_OR_EMAIL; - } - } - addr.origBytes = origBytes; - addr.numberOfDigits = origBytes.length; - return addr; - } - -} diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java deleted file mode 100644 index f9cebf576a43..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project. All rights reserved. - * Copyright (C) 2010 Code Aurora Forum. All rights reserved. - * - * 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 class CdmaSmsSubaddress { - public int type; - - public byte odd; - - public byte[] origBytes; -} - diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java deleted file mode 100644 index f73df56a9ba6..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java +++ /dev/null @@ -1,130 +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.sms; - - -import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress; - -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; - static public final int TELESERVICE_SCPT = 0x1006; - - /** - * The following are defined as extensions to the standard teleservices - */ - // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode. - // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the - // number of messages waiting, it's used by some CDMA carriers for a voice mail count. - static public final int TELESERVICE_MWI = 0x40000; - - // Service Categories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1 - // static final int SERVICE_CATEGORY_EMERGENCY = 0x0001; - //... - - // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1 - public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000; - public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = 0x1001; - public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = 0x1002; - public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003; - public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = 0x1004; - public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff; - - /** - * 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.3) - */ - public CdmaSmsAddress origAddress; - - /** - * The destination address identifies the target of the SMS message. - * (See 3GPP2 C.S0015-B, v2, 3.4.3.3) - */ - public CdmaSmsAddress destAddress; - - /** - * The origination subaddress identifies the originator of the SMS message. - * (See 3GPP2 C.S0015-B, v2, 3.4.3.4) - */ - public CdmaSmsSubaddress origSubaddress; - - /** - * 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 deleted file mode 100644 index 599c2b393a6b..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java +++ /dev/null @@ -1,165 +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.sms; - -import android.util.SparseIntArray; - -import com.android.internal.telephony.SmsHeader; -import com.android.internal.util.HexDump; - -public class UserData { - - /** - * User data encoding types. - * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1) - */ - public static final int ENCODING_OCTET = 0x00; - public static final int ENCODING_IS91_EXTENDED_PROTOCOL = 0x01; - public static final int ENCODING_7BIT_ASCII = 0x02; - public static final int ENCODING_IA5 = 0x03; - public static final int ENCODING_UNICODE_16 = 0x04; - public static final int ENCODING_SHIFT_JIS = 0x05; - public static final int ENCODING_KOREAN = 0x06; - public static final int ENCODING_LATIN_HEBREW = 0x07; - public static final int ENCODING_LATIN = 0x08; - public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09; - public static final int ENCODING_GSM_DCS = 0x0A; - - /** - * IS-91 message types. - * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3) - */ - public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82; - public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83; - public static final int IS91_MSG_TYPE_CLI = 0x84; - public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85; - - /** - * US ASCII character mapping table. - * - * This table contains only the printable ASCII characters, with a - * 0x20 offset, meaning that the ASCII SPACE character is at index - * 0, with the resulting code of 0x20. - * - * Note this mapping is also equivalent to that used by both the - * IA5 and the IS-91 encodings. For the former this is defined - * using CCITT Rec. T.50 Tables 1 and 3. For the latter IS 637 B, - * Table 4.3.1.4.1-1 -- and note the encoding uses only 6 bits, - * and hence only maps entries up to the '_' character. - * - */ - public static final char[] ASCII_MAP = { - ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'}; - - /** - * Character to use when forced to encode otherwise unencodable - * characters, meaning those not in the respective ASCII or GSM - * 7-bit encoding tables. Current choice is SPACE, which is 0x20 - * in both the GSM-7bit and ASCII-7bit encodings. - */ - static final byte UNENCODABLE_7_BIT_CHAR = 0x20; - - /** - * Only elements between these indices in the ASCII table are printable. - */ - public static final int PRINTABLE_ASCII_MIN_INDEX = 0x20; - public static final int ASCII_NL_INDEX = 0x0A; - public static final int ASCII_CR_INDEX = 0x0D; - public static final SparseIntArray charToAscii = new SparseIntArray(); - static { - for (int i = 0; i < ASCII_MAP.length; i++) { - charToAscii.put(ASCII_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i); - } - charToAscii.put('\n', ASCII_NL_INDEX); - charToAscii.put('\r', ASCII_CR_INDEX); - } - - /* - * TODO(cleanup): Move this very generic functionality somewhere - * more general. - */ - /** - * Given a string generate a corresponding ASCII-encoded byte - * array, but limited to printable characters. If the input - * contains unprintable characters, return null. - */ - public static byte[] stringToAscii(String str) { - int len = str.length(); - byte[] result = new byte[len]; - for (int i = 0; i < len; i++) { - int charCode = charToAscii.get(str.charAt(i), -1); - if (charCode == -1) return null; - result[i] = (byte)charCode; - } - return result; - } - - /** - * Mapping for ASCII values less than 32 are flow control signals - * and not used here. - */ - public static final int ASCII_MAP_BASE_INDEX = 0x20; - public static final int ASCII_MAP_MAX_INDEX = ASCII_MAP_BASE_INDEX + ASCII_MAP.length - 1; - - /** - * Contains the data header of the user data - */ - public SmsHeader userDataHeader; - - /** - * Contains the data encoding type for the SMS message - */ - public int msgEncoding; - public boolean msgEncodingSet = false; - - public int msgType; - - /** - * Number of invalid bits in the last byte of data. - */ - public int paddingBits; - - public int numFields; - - /** - * Contains the user data of a SMS message - * (See 3GPP2 C.S0015-B, v2, 4.5.2) - */ - public byte[] payload; - public String payloadStr; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("UserData "); - builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset")); - builder.append(", msgType=" + msgType); - builder.append(", paddingBits=" + paddingBits); - builder.append(", numFields=" + numFields); - builder.append(", userDataHeader=" + userDataHeader); - builder.append(", payload='" + HexDump.toHexString(payload) + "'"); - builder.append(", payloadStr='" + payloadStr + "'"); - builder.append(" }"); - return builder.toString(); - } - -} diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html deleted file mode 100644 index b2bc7364748f..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/package.html +++ /dev/null @@ -1,6 +0,0 @@ - - -Provides CDMA-specific features for text/data/PDU SMS messages -@hide - - diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java deleted file mode 100644 index af2ad48a9bc0..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java +++ /dev/null @@ -1,53 +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; - -/** - * Call fail causes from TS 24.008 . - * These are mostly the cause codes we need to distinguish for the UI. - * See 22.001 Annex F.4 for mapping of cause codes to local tones. - * - * {@hide} - * - */ -public interface CallFailCause { - // Unassigned/Unobtainable number - static final int UNOBTAINABLE_NUMBER = 1; - - static final int NORMAL_CLEARING = 16; - // Busy Tone - static final int USER_BUSY = 17; - - // No Tone - static final int NUMBER_CHANGED = 22; - static final int STATUS_ENQUIRY = 30; - static final int NORMAL_UNSPECIFIED = 31; - - // Congestion Tone - static final int NO_CIRCUIT_AVAIL = 34; - static final int TEMPORARY_FAILURE = 41; - static final int SWITCHING_CONGESTION = 42; - static final int CHANNEL_NOT_AVAIL = 44; - static final int QOS_NOT_AVAIL = 49; - static final int BEARER_NOT_AVAIL = 58; - - // others - static final int ACM_LIMIT_EXCEEDED = 68; - static final int CALL_BARRED = 240; - static final int FDN_BLOCKED = 241; - static final int ERROR_UNSPECIFIED = 0xffff; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java deleted file mode 100644 index 484bab0190a7..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ /dev/null @@ -1,1507 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.content.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Telephony; -import android.telephony.CellLocation; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import com.android.internal.telephony.CallTracker; -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.cat.CatService; -import com.android.internal.telephony.Call; -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.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccPhoneBookInterfaceManager; -import com.android.internal.telephony.IccSmsInterfaceManager; -import com.android.internal.telephony.MmiCode; -import com.android.internal.telephony.OperatorInfo; -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.TelephonyProperties; -import com.android.internal.telephony.UUSInfo; -import com.android.internal.telephony.test.SimulatedRadioControl; -import com.android.internal.telephony.uicc.UiccController; -import com.android.internal.telephony.IccVmNotSupportedException; -import com.android.internal.telephony.ServiceStateTracker; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; - -/** - * {@hide} - */ -public class GSMPhone extends PhoneBase { - // NOTE that LOG_TAG here is "GSM", which means that log messages - // 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 = true; - private static final boolean VDBG = false; /* STOP SHIP if true */ - - // Key used to read/write current ciphering state - public static final String CIPHERING_KEY = "ciphering_key"; - // Key used to read/write voice mail number - public static final String VM_NUMBER = "vm_number_key"; - // Key used to read/write the SIM IMSI used for storing the voice mail - public static final String VM_SIM_IMSI = "vm_sim_imsi_key"; - - // Instance Variables - GsmCallTracker mCT; - GsmServiceStateTracker mSST; - ArrayList mPendingMMIs = new ArrayList(); - SimPhoneBookInterfaceManager mSimPhoneBookIntManager; - SimSmsInterfaceManager mSimSmsIntManager; - PhoneSubInfo mSubInfo; - - - Registrant mPostDialHandler; - - /** List of Registrants to receive Supplementary Service Notifications. */ - RegistrantList mSsnRegistrants = new RegistrantList(); - - Thread debugPortThread; - ServerSocket debugSocket; - - private String mImei; - private String mImeiSv; - private String mVmNumber; - - - // Constructors - - public - GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) { - this(context,ci,notifier, false); - } - - public - GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) { - super(notifier, context, ci, unitTestMode); - - if (ci instanceof SimulatedRadioControl) { - mSimulatedRadioControl = (SimulatedRadioControl) ci; - } - - mCM.setPhoneType(Phone.PHONE_TYPE_GSM); - mIccCard.set(UiccController.getInstance(this).getIccCard()); - mIccRecords = mIccCard.get().getIccRecords(); - mCT = new GsmCallTracker(this); - mSST = new GsmServiceStateTracker (this); - mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); - mDataConnectionTracker = new GsmDataConnectionTracker (this); - if (!unitTestMode) { - mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); - mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS); - mSubInfo = new PhoneSubInfo(this); - } - - mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); - registerForSimRecordEvents(); - mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - mCM.registerForOn(this, EVENT_RADIO_ON, null); - mCM.setOnUSSD(this, EVENT_USSD, null); - mCM.setOnSuppServiceNotification(this, EVENT_SSN, null); - mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); - - if (false) { - try { - //debugSocket = new LocalServerSocket("com.android.internal.telephony.debug"); - debugSocket = new ServerSocket(); - debugSocket.setReuseAddress(true); - debugSocket.bind (new InetSocketAddress("127.0.0.1", 6666)); - - debugPortThread - = new Thread( - new Runnable() { - public void run() { - for(;;) { - try { - Socket sock; - sock = debugSocket.accept(); - Log.i(LOG_TAG, "New connection; resetting radio"); - mCM.resetRadio(null); - sock.close(); - } catch (IOException ex) { - Log.w(LOG_TAG, - "Exception accepting socket", ex); - } - } - } - }, - "GSMPhone debug"); - - debugPortThread.start(); - - } catch (IOException ex) { - Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex); - } - } - - //Change the system property - SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, - new Integer(Phone.PHONE_TYPE_GSM).toString()); - } - - @Override - public void dispose() { - synchronized(PhoneProxy.lockForRadioTechnologyChange) { - super.dispose(); - - //Unregister from all former registered events - mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE - unregisterForSimRecordEvents(); - mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE - mCM.unregisterForOn(this); //EVENT_RADIO_ON - mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK - mCM.unSetOnUSSD(this); - mCM.unSetOnSuppServiceNotification(this); - - mPendingMMIs.clear(); - - //Force all referenced classes to unregister their former registered events - mCT.dispose(); - mDataConnectionTracker.dispose(); - mSST.dispose(); - mSimPhoneBookIntManager.dispose(); - mSimSmsIntManager.dispose(); - mSubInfo.dispose(); - } - } - - @Override - public void removeReferences() { - Log.d(LOG_TAG, "removeReferences"); - mSimulatedRadioControl = null; - mSimPhoneBookIntManager = null; - mSimSmsIntManager = null; - mSubInfo = null; - mCT = null; - mSST = null; - super.removeReferences(); - } - - protected void finalize() { - if(LOCAL_DEBUG) Log.d(LOG_TAG, "GSMPhone finalized"); - } - - - public ServiceState - getServiceState() { - return mSST.ss; - } - - public CellLocation getCellLocation() { - return mSST.cellLoc; - } - - public Phone.State getState() { - return mCT.state; - } - - public String getPhoneName() { - return "GSM"; - } - - public int getPhoneType() { - return Phone.PHONE_TYPE_GSM; - } - - public SignalStrength getSignalStrength() { - return mSST.mSignalStrength; - } - - public CallTracker getCallTracker() { - return mCT; - } - - public ServiceStateTracker getServiceStateTracker() { - return mSST; - } - - public List - getPendingMmiCodes() { - return mPendingMMIs; - } - - public DataState getDataConnectionState(String apnType) { - DataState ret = DataState.DISCONNECTED; - - if (mSST == null) { - // Radio Technology Change is ongoning, dispose() and removeReferences() have - // already been called - - ret = DataState.DISCONNECTED; - } else if (mSST.getCurrentGprsState() - != ServiceState.STATE_IN_SERVICE) { - // If we're out of service, open TCP sockets may still work - // but no data will flow - ret = DataState.DISCONNECTED; - } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false || - mDataConnectionTracker.isApnTypeActive(apnType) == false) { - //TODO: isApnTypeActive() is just checking whether ApnContext holds - // Dataconnection or not. Checking each ApnState below should - // provide the same state. Calling isApnTypeActive() can be removed. - ret = DataState.DISCONNECTED; - } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */ - switch (mDataConnectionTracker.getState(apnType)) { - case FAILED: - case IDLE: - ret = DataState.DISCONNECTED; - break; - - case CONNECTED: - case DISCONNECTING: - if ( mCT.state != Phone.State.IDLE - && !mSST.isConcurrentVoiceAndDataAllowed()) { - ret = DataState.SUSPENDED; - } else { - ret = DataState.CONNECTED; - } - break; - - case INITING: - case CONNECTING: - case SCANNING: - ret = DataState.CONNECTING; - break; - } - } - - return ret; - } - - public DataActivityState getDataActivityState() { - DataActivityState ret = DataActivityState.NONE; - - if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) { - switch (mDataConnectionTracker.getActivity()) { - case DATAIN: - ret = DataActivityState.DATAIN; - break; - - case DATAOUT: - ret = DataActivityState.DATAOUT; - break; - - case DATAINANDOUT: - ret = DataActivityState.DATAINANDOUT; - break; - } - } - - return ret; - } - - /** - * Notify any interested party of a Phone state change {@link Phone.State} - */ - /*package*/ void notifyPhoneStateChanged() { - mNotifier.notifyPhoneState(this); - } - - /** - * Notify registrants of a change in the call state. This notifies changes in {@link Call.State} - * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged. - */ - /*package*/ void notifyPreciseCallStateChanged() { - /* we'd love it if this was package-scoped*/ - super.notifyPreciseCallStateChangedP(); - } - - /*package*/ void - notifyNewRingingConnection(Connection c) { - /* we'd love it if this was package-scoped*/ - super.notifyNewRingingConnectionP(c); - } - - /*package*/ void - notifyDisconnect(Connection cn) { - mDisconnectRegistrants.notifyResult(cn); - } - - void notifyUnknownConnection() { - mUnknownConnectionRegistrants.notifyResult(this); - } - - void notifySuppServiceFailed(SuppService code) { - mSuppServiceFailedRegistrants.notifyResult(code); - } - - /*package*/ void - notifyServiceStateChanged(ServiceState ss) { - super.notifyServiceStateChangedP(ss); - } - - /*package*/ - void notifyLocationChanged() { - mNotifier.notifyCellLocation(this); - } - - /*package*/ void - notifySignalStrength() { - mNotifier.notifySignalStrength(this); - } - - public void - notifyCallForwardingIndicator() { - mNotifier.notifyCallForwardingChanged(this); - } - - // override for allowing access from other classes of this package - /** - * {@inheritDoc} - */ - public final void - setSystemProperty(String property, String value) { - super.setSystemProperty(property, value); - } - - public void registerForSuppServiceNotification( - Handler h, int what, Object obj) { - mSsnRegistrants.addUnique(h, what, obj); - if (mSsnRegistrants.size() == 1) mCM.setSuppServiceNotifications(true, null); - } - - public void unregisterForSuppServiceNotification(Handler h) { - mSsnRegistrants.remove(h); - if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null); - } - - public void - acceptCall() throws CallStateException { - mCT.acceptCall(); - } - - public void - rejectCall() throws CallStateException { - mCT.rejectCall(); - } - - public void - switchHoldingAndActive() throws CallStateException { - mCT.switchWaitingOrHoldingAndActive(); - } - - public boolean canConference() { - return mCT.canConference(); - } - - public boolean canDial() { - return mCT.canDial(); - } - - public void conference() throws CallStateException { - mCT.conference(); - } - - public void clearDisconnected() { - mCT.clearDisconnected(); - } - - public boolean canTransfer() { - return mCT.canTransfer(); - } - - public void explicitCallTransfer() throws CallStateException { - mCT.explicitCallTransfer(); - } - - public GsmCall - getForegroundCall() { - return mCT.foregroundCall; - } - - public GsmCall - getBackgroundCall() { - return mCT.backgroundCall; - } - - public GsmCall - getRingingCall() { - return mCT.ringingCall; - } - - private boolean handleCallDeflectionIncallSupplementaryService( - String dialString) throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - if (getRingingCall().getState() != GsmCall.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 0: rejectCall"); - try { - mCT.rejectCall(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "reject failed", e); - notifySuppServiceFailed(Phone.SuppService.REJECT); - } - } else if (getBackgroundCall().getState() != GsmCall.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 0: hangupWaitingOrBackground"); - mCT.hangupWaitingOrBackground(); - } - - return true; - } - - private boolean handleCallWaitingIncallSupplementaryService( - String dialString) throws CallStateException { - int len = dialString.length(); - - if (len > 2) { - return false; - } - - GsmCall call = (GsmCall) getForegroundCall(); - - try { - if (len > 1) { - char ch = dialString.charAt(1); - int callIndex = ch - '0'; - - if (callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: hangupConnectionByIndex " + - callIndex); - mCT.hangupConnectionByIndex(call, callIndex); - } - } else { - if (call.getState() != GsmCall.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: hangup foreground"); - //mCT.hangupForegroundResumeBackground(); - mCT.hangup(call); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: switchWaitingOrHoldingAndActive"); - mCT.switchWaitingOrHoldingAndActive(); - } - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "hangup failed", e); - notifySuppServiceFailed(Phone.SuppService.HANGUP); - } - - return true; - } - - private boolean handleCallHoldIncallSupplementaryService(String dialString) - throws CallStateException { - int len = dialString.length(); - - if (len > 2) { - return false; - } - - GsmCall call = (GsmCall) getForegroundCall(); - - if (len > 1) { - try { - 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 "+ - callIndex); - mCT.separate(conn); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "separate: invalid call index "+ - callIndex); - notifySuppServiceFailed(Phone.SuppService.SEPARATE); - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "separate failed", e); - notifySuppServiceFailed(Phone.SuppService.SEPARATE); - } - } else { - try { - if (getRingingCall().getState() != GsmCall.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 2: accept ringing call"); - mCT.acceptCall(); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 2: switchWaitingOrHoldingAndActive"); - mCT.switchWaitingOrHoldingAndActive(); - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "switch failed", e); - notifySuppServiceFailed(Phone.SuppService.SWITCH); - } - } - - return true; - } - - private boolean handleMultipartyIncallSupplementaryService( - String dialString) throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 3: merge calls"); - try { - conference(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "conference failed", e); - notifySuppServiceFailed(Phone.SuppService.CONFERENCE); - } - return true; - } - - private boolean handleEctIncallSupplementaryService(String dialString) - throws CallStateException { - - int len = dialString.length(); - - if (len != 1) { - return false; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 4: explicit call transfer"); - try { - explicitCallTransfer(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "transfer failed", e); - notifySuppServiceFailed(Phone.SuppService.TRANSFER); - } - return true; - } - - private boolean handleCcbsIncallSupplementaryService(String dialString) - throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - Log.i(LOG_TAG, "MmiCode 5: CCBS not supported!"); - // Treat it as an "unknown" service. - notifySuppServiceFailed(Phone.SuppService.UNKNOWN); - return true; - } - - public boolean handleInCallMmiCommands(String dialString) - throws CallStateException { - if (!isInCall()) { - return false; - } - - if (TextUtils.isEmpty(dialString)) { - return false; - } - - boolean result = false; - char ch = dialString.charAt(0); - switch (ch) { - case '0': - result = handleCallDeflectionIncallSupplementaryService( - dialString); - break; - case '1': - result = handleCallWaitingIncallSupplementaryService( - dialString); - break; - case '2': - result = handleCallHoldIncallSupplementaryService(dialString); - break; - case '3': - result = handleMultipartyIncallSupplementaryService(dialString); - break; - case '4': - result = handleEctIncallSupplementaryService(dialString); - break; - case '5': - result = handleCcbsIncallSupplementaryService(dialString); - break; - default: - break; - } - - return result; - } - - boolean isInCall() { - GsmCall.State foregroundCallState = getForegroundCall().getState(); - GsmCall.State backgroundCallState = getBackgroundCall().getState(); - GsmCall.State ringingCallState = getRingingCall().getState(); - - return (foregroundCallState.isAlive() || - backgroundCallState.isAlive() || - ringingCallState.isAlive()); - } - - public Connection - dial(String dialString) throws CallStateException { - return dial(dialString, null); - } - - public Connection - dial (String dialString, UUSInfo uusInfo) throws CallStateException { - // Need to make sure dialString gets parsed properly - String newDialString = PhoneNumberUtils.stripSeparators(dialString); - - // handle in-call MMI first if applicable - if (handleInCallMmiCommands(newDialString)) { - return null; - } - - // Only look at the Network portion for mmi - String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString); - GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this); - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "dialing w/ mmi '" + mmi + "'..."); - - if (mmi == null) { - return mCT.dial(newDialString, uusInfo); - } else if (mmi.isTemporaryModeCLIR()) { - return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo); - } else { - mPendingMMIs.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.processCode(); - - // FIXME should this return null or something else? - return null; - } - } - - 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; - } - - public void sendUssdResponse(String ussdMessge) { - GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this); - mPendingMMIs.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.sendUssd(ussdMessge); - } - - public void - sendDtmf(char c) { - 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) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "startDtmf called with invalid character '" + c + "'"); - } else { - mCM.startDtmf(c, null); - } - } - - public void - stopDtmf() { - mCM.stopDtmf(null); - } - - public void - sendBurstDtmf(String dtmfString) { - Log.e(LOG_TAG, "[GSMPhone] sendBurstDtmf() is a CDMA method"); - } - - public void - setRadioPower(boolean power) { - mSST.setRadioPower(power); - } - - private void storeVoiceMailNumber(String number) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_NUMBER, number); - editor.apply(); - setVmSimImsi(getSubscriberId()); - } - - public String getVoiceMailNumber() { - // Read from the SIM. If its null, try reading from the shared preference area. - String number = mIccRecords.getVoiceMailNumber(); - if (TextUtils.isEmpty(number)) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - number = sp.getString(VM_NUMBER, null); - } - return number; - } - - private String getVmSimImsi() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - return sp.getString(VM_SIM_IMSI, null); - } - - private void setVmSimImsi(String imsi) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_SIM_IMSI, imsi); - editor.apply(); - } - - public String getVoiceMailAlphaTag() { - String ret; - - ret = mIccRecords.getVoiceMailAlphaTag(); - - if (ret == null || ret.length() == 0) { - return mContext.getText( - com.android.internal.R.string.defaultVoiceMailAlphaTag).toString(); - } - - return ret; - } - - public String getDeviceId() { - return mImei; - } - - public String getDeviceSvn() { - return mImeiSv; - } - - public String getImei() { - return mImei; - } - - public String getEsn() { - 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"; - } - - public String getSubscriberId() { - return mIccRecords.getIMSI(); - } - - public String getLine1Number() { - return mIccRecords.getMsisdnNumber(); - } - - @Override - public String getMsisdn() { - return mIccRecords.getMsisdnNumber(); - } - - public String getLine1AlphaTag() { - return mIccRecords.getMsisdnAlphaTag(); - } - - public void setLine1Number(String alphaTag, String number, Message onComplete) { - mIccRecords.setMsisdnNumber(alphaTag, number, onComplete); - } - - public void setVoiceMailNumber(String alphaTag, - String voiceMailNumber, - Message onComplete) { - - Message resp; - mVmNumber = voiceMailNumber; - resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete); - mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp); - } - - 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."); - Message resp; - if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) { - resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete); - } else { - resp = onComplete; - } - mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp); - } - } - - 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 = 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, - Message onComplete) { - mCM.setCLIR(commandInterfaceCLIRMode, - obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete)); - } - - public void getCallWaiting(Message onComplete) { - //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service - //class parameter in call waiting interrogation to network - mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete); - } - - public void - getAvailableNetworks(Message response) { - mCM.getAvailableNetworks(response); - } - - /** - * Small container class used to hold information relevant to - * the carrier selection process. operatorNumeric can be "" - * if we are looking for automatic selection. operatorAlphaLong is the - * corresponding operator name. - */ - private static class NetworkSelectMessage { - public Message message; - public String operatorNumeric; - public String operatorAlphaLong; - } - - public void - setNetworkSelectionModeAutomatic(Message response) { - // wrap the response message in our own message along with - // an empty string (to indicate automatic selection) for the - // operator's id. - NetworkSelectMessage nsm = new NetworkSelectMessage(); - nsm.message = response; - nsm.operatorNumeric = ""; - nsm.operatorAlphaLong = ""; - - // get the message - Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); - if (LOCAL_DEBUG) - Log.d(LOG_TAG, "wrapping and sending message to connect automatically"); - - mCM.setNetworkSelectionModeAutomatic(msg); - } - - public void - selectNetworkManually(OperatorInfo network, - 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.getOperatorNumeric(); - nsm.operatorAlphaLong = network.getOperatorAlphaLong(); - - // get the message - Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); - - mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), 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 getDataCallList(Message response) { - mCM.getDataCallList(response); - } - - public void updateServiceLocation() { - mSST.enableSingleLocationUpdate(); - } - - public void enableLocationUpdates() { - mSST.enableLocationUpdates(); - } - - public void disableLocationUpdates() { - mSST.disableLocationUpdates(); - } - - public boolean getDataRoamingEnabled() { - return mDataConnectionTracker.getDataOnRoamingEnabled(); - } - - public void setDataRoamingEnabled(boolean enable) { - mDataConnectionTracker.setDataOnRoamingEnabled(enable); - } - - /** - * Removes the given MMI from the pending list and notifies - * registrants that it is complete. - * @param mmi MMI that is done - */ - /*package*/ void - onMMIDone(GsmMmiCode mmi) { - /* 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(mmi) || mmi.isUssdRequest()) { - mMmiCompleteRegistrants.notifyRegistrants( - new AsyncResult(null, mmi, null)); - } - } - - - private void - onNetworkInitiatedUssd(GsmMmiCode mmi) { - mMmiCompleteRegistrants.notifyRegistrants( - new AsyncResult(null, mmi, null)); - } - - - /** ussdMode is one of CommandsInterface.USSD_MODE_* */ - private void - onIncomingUSSD (int ussdMode, String ussdMessage) { - boolean isUssdError; - boolean isUssdRequest; - - isUssdRequest - = (ussdMode == CommandsInterface.USSD_MODE_REQUEST); - - 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 - GsmMmiCode found = null; - for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { - if(mPendingMMIs.get(i).isPendingUSSD()) { - found = mPendingMMIs.get(i); - break; - } - } - - if (found != null) { - // Complete pending USSD - - if (isUssdError) { - found.onUssdFinishedError(); - } else { - found.onUssdFinished(ussdMessage, isUssdRequest); - } - } else { // pending USSD not found - // The network may initiate its own USSD request - - // ignore everything that isnt a Notify or a Request - // also, discard if there is no message to present - if (!isUssdError && ussdMessage != null) { - GsmMmiCode mmi; - mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, - isUssdRequest, - GSMPhone.this); - onNetworkInitiatedUssd(mmi); - } - } - } - - /** - * 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); - } - } - - @Override - public void handleMessage (Message msg) { - AsyncResult ar; - Message onComplete; - - switch (msg.what) { - case EVENT_RADIO_AVAILABLE: { - mCM.getBasebandVersion( - obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE)); - - mCM.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE)); - mCM.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE)); - } - break; - - case EVENT_RADIO_ON: - break; - - case EVENT_REGISTERED_TO_NETWORK: - syncClirSetting(); - break; - - case EVENT_SIM_RECORDS_LOADED: - updateCurrentCarrierInProvider(); - - // Check if this is a different SIM than the previous one. If so unset the - // voice mail number. - String imsi = getVmSimImsi(); - String imsiFromSIM = getSubscriberId(); - if (imsi != null && imsiFromSIM != null && !imsiFromSIM.equals(imsi)) { - storeVoiceMailNumber(null); - setVmSimImsi(null); - } - - break; - - case EVENT_GET_BASEBAND_VERSION_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result); - setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result); - break; - - case EVENT_GET_IMEI_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mImei = (String)ar.result; - break; - - case EVENT_GET_IMEISV_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mImeiSv = (String)ar.result; - break; - - case EVENT_USSD: - ar = (AsyncResult)msg.obj; - - String[] ussdResult = (String[]) ar.result; - - if (ussdResult.length > 1) { - try { - onIncomingUSSD(Integer.parseInt(ussdResult[0]), ussdResult[1]); - } catch (NumberFormatException e) { - Log.w(LOG_TAG, "error parsing USSD"); - } - } - break; - - 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 - // is pending, we need to clean up. - - for (int i = mPendingMMIs.size() - 1; i >= 0; i--) { - if (mPendingMMIs.get(i).isPendingUSSD()) { - mPendingMMIs.get(i).onUssdFinishedError(); - } - } - break; - - case EVENT_SSN: - ar = (AsyncResult)msg.obj; - SuppServiceNotification not = (SuppServiceNotification) ar.result; - mSsnRegistrants.notifyRegistrants(ar); - break; - - case EVENT_SET_CALL_FORWARD_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - mIccRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1); - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - - case EVENT_SET_VM_NUMBER_DONE: - ar = (AsyncResult)msg.obj; - if (IccVmNotSupportedException.class.isInstance(ar.exception)) { - storeVoiceMailNumber(mVmNumber); - ar.exception = null; - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - - - 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; - - case EVENT_NEW_ICC_SMS: - ar = (AsyncResult)msg.obj; - mSMS.dispatchMessage((SmsMessage)ar.result); - break; - - case EVENT_SET_NETWORK_AUTOMATIC: - ar = (AsyncResult)msg.obj; - setNetworkSelectionModeAutomatic((Message)ar.result); - break; - - case EVENT_ICC_RECORD_EVENTS: - ar = (AsyncResult)msg.obj; - processIccRecordEvents((Integer)ar.result); - break; - - // handle the select network completion callbacks. - case EVENT_SET_NETWORK_MANUAL_COMPLETE: - case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: - handleSetSelectNetwork((AsyncResult) msg.obj); - break; - - 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: - super.handleMessage(msg); - } - } - - private void processIccRecordEvents(int eventCode) { - switch (eventCode) { - case SIMRecords.EVENT_CFI: - notifyCallForwardingIndicator(); - break; - case SIMRecords.EVENT_MWI: - notifyMessageWaitingIndicator(); - break; - } - } - - /** - * Sets the "current" field in the telephony provider according to the SIM's operator - * - * @return true for success; false otherwise. - */ - boolean updateCurrentCarrierInProvider() { - if (mIccRecords != null) { - try { - Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); - ContentValues map = new ContentValues(); - map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric()); - mContext.getContentResolver().insert(uri, map); - return true; - } catch (SQLException e) { - Log.e(LOG_TAG, "Can't store current operator", e); - } - } - return false; - } - - /** - * 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. - 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. - 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); - editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); - - // commit and log the result. - if (! editor.commit()) { - Log.e(LOG_TAG, "failed to commit network selection preference"); - } - - } - - /** - * 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 - // Set unconditional CFF in SIM to false - mIccRecords.setVoiceCallForwardingFlag(1, false); - } else { - for (int i = 0, s = infos.length; i < s; i++) { - if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) { - mIccRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1)); - // should only have the one - break; - } - } - } - } - - /** - * Retrieves the PhoneSubInfo of the GSMPhone - */ - public PhoneSubInfo getPhoneSubInfo(){ - return mSubInfo; - } - - /** - * Retrieves the IccSmsInterfaceManager of the GSMPhone - */ - public IccSmsInterfaceManager getIccSmsInterfaceManager(){ - return mSimSmsIntManager; - } - - /** - * Retrieves the IccPhoneBookInterfaceManager of the GSMPhone - */ - public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ - return mSimPhoneBookIntManager; - } - - /** - * 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) { - Log.e(LOG_TAG, "[GSMPhone] activateCellBroadcastSms() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - /** - * Query the current configuration of cdma cell broadcast SMS. - * - * @param response Callback message is empty on completion - */ - public void getCellBroadcastSmsConfig(Message response) { - Log.e(LOG_TAG, "[GSMPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - /** - * Configure cdma cell broadcast SMS. - * - * @param response Callback message is empty on completion - */ - public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) { - Log.e(LOG_TAG, "[GSMPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager"); - response.sendToTarget(); - } - - public boolean isCspPlmnEnabled() { - return mIccRecords.isCspPlmnEnabled(); - } - - private void registerForSimRecordEvents() { - mIccRecords.registerForNetworkSelectionModeAutomatic( - this, EVENT_SET_NETWORK_AUTOMATIC, null); - mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null); - mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null); - mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); - } - - private void unregisterForSimRecordEvents() { - mIccRecords.unregisterForNetworkSelectionModeAutomatic(this); - mIccRecords.unregisterForNewSms(this); - mIccRecords.unregisterForRecordsEvents(this); - mIccRecords.unregisterForRecordsLoaded(this); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("GSMPhone extends:"); - super.dump(fd, pw, args); - pw.println(" mCT=" + mCT); - pw.println(" mSST=" + mSST); - pw.println(" mPendingMMIs=" + mPendingMMIs); - pw.println(" mSimPhoneBookIntManager=" + mSimPhoneBookIntManager); - pw.println(" mSimSmsIntManager=" + mSimSmsIntManager); - pw.println(" mSubInfo=" + mSubInfo); - if (VDBG) pw.println(" mImei=" + mImei); - if (VDBG) pw.println(" mImeiSv=" + mImeiSv); - pw.println(" mVmNumber=" + mVmNumber); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java b/telephony/java/com/android/internal/telephony/gsm/GsmCall.java deleted file mode 100644 index 58124a25beea..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java +++ /dev/null @@ -1,208 +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 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; - -/** - * {@hide} - */ -class GsmCall extends Call { - /*************************** Instance Variables **************************/ - - /*package*/ ArrayList connections = new ArrayList(); - /*package*/ GsmCallTracker owner; - - - /***************************** Class Methods *****************************/ - - static State - stateFromDCState (DriverCall.State dcState) { - switch (dcState) { - case ACTIVE: return State.ACTIVE; - case HOLDING: return State.HOLDING; - case DIALING: return State.DIALING; - case ALERTING: return State.ALERTING; - case INCOMING: return State.INCOMING; - case WAITING: return State.WAITING; - default: throw new RuntimeException ("illegal call state:" + dcState); - } - } - - - /****************************** Constructors *****************************/ - /*package*/ - GsmCall (GsmCallTracker owner) { - this.owner = owner; - } - - public void dispose() { - } - - /************************** Overridden from Call *************************/ - - public List - getConnections() { - // FIXME should return Collections.unmodifiableList(); - return connections; - } - - public Phone - getPhone() { - return owner.phone; - } - - public boolean - isMultiparty() { - return connections.size() > 1; - } - - /** Please note: if this is the foreground call and a - * background call exists, the background call will be resumed - * because an AT+CHLD=1 will be sent - */ - public void - hangup() throws CallStateException { - owner.hangup(this); - } - - public String - toString() { - return state.toString(); - } - - //***** Called from GsmConnection - - /*package*/ void - attach(Connection conn, DriverCall dc) { - connections.add(conn); - - state = stateFromDCState (dc.state); - } - - /*package*/ void - attachFake(Connection conn, State state) { - connections.add(conn); - - this.state = state; - } - - /** - * Called by GsmConnection when it has disconnected - */ - void - connectionDisconnected(GsmConnection conn) { - if (state != State.DISCONNECTED) { - /* 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() - != State.DISCONNECTED - ) { - hasOnlyDisconnectedConnections = false; - break; - } - } - - if (hasOnlyDisconnectedConnections) { - state = State.DISCONNECTED; - } - } - } - - - /*package*/ void - detach(GsmConnection conn) { - connections.remove(conn); - - if (connections.size() == 0) { - state = State.IDLE; - } - } - - /*package*/ boolean - update (GsmConnection conn, DriverCall dc) { - State newState; - boolean changed = false; - - newState = stateFromDCState(dc.state); - - if (newState != state) { - state = newState; - changed = true; - } - - return changed; - } - - /** - * @return true if there's no space in this call for additional - * connections to be added via "conference" - */ - /*package*/ boolean - isFull() { - return connections.size() == GsmCallTracker.MAX_CONNECTIONS_PER_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 - */ - void - onHangupLocal() { - for (int i = 0, s = connections.size() - ; i < s; i++ - ) { - GsmConnection cn = (GsmConnection)connections.get(i); - - cn.onHangupLocal(); - } - state = State.DISCONNECTING; - } - - /** - * Called when it's time to clean up disconnected Connection objects - */ - void - 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 deleted file mode 100644 index e86d85388b06..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.telephony.gsm.GsmCellLocation; -import android.util.EventLog; -import android.util.Log; - -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.CallTracker; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.DriverCall; -import com.android.internal.telephony.EventLogTags; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.UUSInfo; -import com.android.internal.telephony.gsm.CallFailCause; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.gsm.GsmCall; -import com.android.internal.telephony.gsm.GsmConnection; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.List; -import java.util.ArrayList; - -/** - * {@hide} - */ -public final class GsmCallTracker extends CallTracker { - static final String LOG_TAG = "GSM"; - 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 during last poll - ArrayList droppedDuringPoll - = new ArrayList(MAX_CONNECTIONS); - - GsmCall ringingCall = new GsmCall(this); - // A call that is ringing or (call) waiting - GsmCall foregroundCall = new GsmCall(this); - GsmCall backgroundCall = new GsmCall(this); - - GsmConnection pendingMO; - boolean hangupPendingMO; - - GSMPhone phone; - - boolean desiredMute = false; // false = mute off - - Phone.State state = Phone.State.IDLE; - - - - //***** Events - - - //***** Constructors - - GsmCallTracker (GSMPhone phone) { - this.phone = phone; - cm = phone.mCM; - - cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); - - cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null); - 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 - public void registerForVoiceCallStarted(Handler h, int what, Object obj) { - 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 connCopy; - - // We need to make a copy here, since fakeHoldBeforeDial() - // modifies the lists, and we don't want to reverse the order - connCopy = (List) foregroundCall.connections.clone(); - - for (int i = 0, s = connCopy.size() ; i < s ; i++) { - GsmConnection conn = (GsmConnection)connCopy.get(i); - - conn.fakeHoldBeforeDial(); - } - } - - /** - * clirMode is one of the CLIR_ constants - */ - synchronized Connection - dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException { - // note that this triggers call state changed notif - clearDisconnected(); - - if (!canDial()) { - throw new CallStateException("cannot dial in current state"); - } - - // The new call must be assigned to the foreground call. - // That call must be idle, so place anything that's - // there on hold - if (foregroundCall.getState() == GsmCall.State.ACTIVE) { - // this will probably be done by the radio anyway - // but the dial might fail before this happens - // and we need to make sure the foreground call is clear - // for the newly dialed connection - switchWaitingOrHoldingAndActive(); - - // Fake local state so that - // a) foregroundCall is empty for the newly dialed connection - // b) hasNonHangupStateChanged remains false in the - // next poll, so that we don't clear a failed dialing call - fakeHoldForegroundBeforeDial(); - } - - if (foregroundCall.getState() != GsmCall.State.IDLE) { - //we should have failed in !canDial() above before we get here - throw new CallStateException("cannot dial in current state"); - } - - pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), - this, foregroundCall); - hangupPendingMO = false; - - if (pendingMO.address == null || pendingMO.address.length() == 0 - || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0 - ) { - // Phone number is invalid - pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER; - - // handlePollCalls() will notice this call not present - // and will mark it as dropped. - pollCallsWhenSafe(); - } else { - // Always unmute when initiating a new call - setMute(false); - - cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage()); - } - - updatePhoneState(); - phone.notifyPreciseCallStateChanged(); - - return pendingMO; - } - - Connection - dial(String dialString) throws CallStateException { - return dial(dialString, CommandsInterface.CLIR_DEFAULT, null); - } - - Connection - dial(String dialString, UUSInfo uusInfo) throws CallStateException { - return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo); - } - - Connection - dial(String dialString, int clirMode) throws CallStateException { - return dial(dialString, clirMode, null); - } - - 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() == GsmCall.State.INCOMING) { - Log.i("phone", "acceptCall: incoming..."); - // Always unmute when answering a new call - setMute(false); - cm.acceptCall(obtainCompleteMessage()); - } else if (ringingCall.getState() == GsmCall.State.WAITING) { - setMute(false); - switchWaitingOrHoldingAndActive(); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - rejectCall () throws CallStateException { - // AT+CHLD=0 means "release held or UDUB" - // so if the phone isn't ringing, this could hang up held - if (ringingCall.getState().isRinging()) { - cm.rejectCall(obtainCompleteMessage()); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - switchWaitingOrHoldingAndActive() throws CallStateException { - // Should we bother with this check? - if (ringingCall.getState() == GsmCall.State.INCOMING) { - throw new CallStateException("cannot be in the incoming state"); - } else { - cm.switchWaitingOrHoldingAndActive( - obtainCompleteMessage(EVENT_SWITCH_RESULT)); - } - } - - void - conference() throws CallStateException { - cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); - } - - void - explicitCallTransfer() throws CallStateException { - cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); - } - - void - clearDisconnected() { - internalClearDisconnected(); - - updatePhoneState(); - phone.notifyPreciseCallStateChanged(); - } - - boolean - canConference() { - return foregroundCall.getState() == GsmCall.State.ACTIVE - && backgroundCall.getState() == GsmCall.State.HOLDING - && !backgroundCall.isFull() - && !foregroundCall.isFull(); - } - - boolean - canDial() { - boolean ret; - int serviceState = phone.getServiceState().getState(); - String disableCall = SystemProperties.get( - TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); - - ret = (serviceState != ServiceState.STATE_POWER_OFF) - && pendingMO == null - && !ringingCall.isRinging() - && !disableCall.equals("true") - && (!foregroundCall.getState().isAlive() - || !backgroundCall.getState().isAlive()); - - return ret; - } - - boolean - canTransfer() { - return foregroundCall.getState() == GsmCall.State.ACTIVE - && backgroundCall.getState() == GsmCall.State.HOLDING; - } - - //***** Private Instance Methods - - private void - internalClearDisconnected() { - ringingCall.clearDisconnected(); - foregroundCall.clearDisconnected(); - backgroundCall.clearDisconnected(); - } - - /** - * Obtain a message to use for signalling "invoke getCurrentCalls() when - * this operation and all other pending operations are complete - */ - private Message - 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 - */ - private Message - obtainCompleteMessage(int what) { - pendingOperations++; - lastRelevantPoll = null; - needsPoll = true; - - if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + - pendingOperations + ", needsPoll=" + needsPoll); - - return obtainMessage(what); - } - - 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); - } 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 || - !(foregroundCall.isIdle() && backgroundCall.isIdle())) { - state = Phone.State.OFFHOOK; - } else { - state = Phone.State.IDLE; - } - - if (state == Phone.State.IDLE && oldState != state) { - voiceCallEndedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - } else if (oldState == Phone.State.IDLE && oldState != state) { - voiceCallStartedRegistrants.notifyRegistrants ( - new AsyncResult(null, null, null)); - } - - if (state != oldState) { - phone.notifyPhoneStateChanged(); - } - } - - protected synchronized void - handlePollCalls(AsyncResult ar) { - List polledCalls; - - if (ar.exception == null) { - polledCalls = (List)ar.result; - } else if (isCommandExceptionRadioNotAvailable(ar.exception)) { - // just a dummy empty ArrayList to cause the loop - // to hang up all the calls - polledCalls = new ArrayList(); - } else { - // Radio probably wasn't ready--try again in a bit - // But don't keep polling if the channel is closed - pollCallsAfterDelay(); - return; - } - - Connection newRinging = null; //or waiting - boolean hasNonHangupStateChanged = false; // Any change besides - // a dropped connection - boolean needsPollDelay = false; - boolean unknownConnectionAppeared = false; - - for (int i = 0, curDC = 0, dcSize = polledCalls.size() - ; i < connections.length; i++) { - GsmConnection conn = connections[i]; - DriverCall dc = null; - - // polledCall list is sparse - if (curDC < dcSize) { - dc = (DriverCall) polledCalls.get(curDC); - - if (dc.index == i+1) { - curDC++; - } else { - dc = null; - } - } - - if (DBG_POLL) log("poll: conn[i=" + i + "]=" + - conn+", dc=" + dc); - - if (conn == null && dc != null) { - // Connection appeared in CLCC response that we don't know about - if (pendingMO != null && pendingMO.compareTo(dc)) { - - if (DBG_POLL) log("poll: pendingMO=" + pendingMO); - - // It's our pending mobile originating call - connections[i] = pendingMO; - pendingMO.index = i; - pendingMO.update(dc); - pendingMO = null; - - // Someone has already asked to hangup this call - if (hangupPendingMO) { - hangupPendingMO = false; - try { - if (Phone.DEBUG_PHONE) log( - "poll: hangupPendingMO, hangup conn " + i); - hangup(connections[i]); - } catch (CallStateException ex) { - Log.e(LOG_TAG, "unexpected error on hangup"); - } - - // Do not continue processing this poll - // Wait for hangup and repoll - return; - } - } else { - connections[i] = new GsmConnection(phone.getContext(), dc, this, i); - - // it's a ringing call - if (connections[i].getCall() == ringingCall) { - newRinging = connections[i]; - } else { - // Something strange happened: a call appeared - // 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 - // it's non-zero. It may not be accurate, but at least - // it won't appear as a Missed Call. - if (dc.state != DriverCall.State.ALERTING - && dc.state != DriverCall.State.DIALING) { - connections[i].connectTime = System.currentTimeMillis(); - } - - unknownConnectionAppeared = true; - } - } - hasNonHangupStateChanged = true; - } else if (conn != null && dc == null) { - // Connection missing in CLCC response that we were - // tracking. - droppedDuringPoll.add(conn); - // Dropped connections are removed from the CallTracker - // list but kept in the GsmCall list - connections[i] = null; - } else if (conn != null && dc != null && !conn.compareTo(dc)) { - // Connection in CLCC response does not match what - // we were tracking. Assume dropped call and new call - - droppedDuringPoll.add(conn); - connections[i] = new GsmConnection (phone.getContext(), dc, this, i); - - if (connections[i].getCall() == ringingCall) { - newRinging = connections[i]; - } // else something strange happened - hasNonHangupStateChanged = true; - } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */ - boolean changed; - changed = conn.update(dc); - hasNonHangupStateChanged = hasNonHangupStateChanged || changed; - } - - if (REPEAT_POLLING) { - if (dc != null) { - // FIXME with RIL, we should not need this anymore - if ((dc.state == DriverCall.State.DIALING - /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/) - || (dc.state == DriverCall.State.ALERTING - /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/) - || (dc.state == DriverCall.State.INCOMING - /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/) - || (dc.state == DriverCall.State.WAITING - /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/) - ) { - // Sometimes there's no unsolicited notification - // for state transitions - needsPollDelay = true; - } - } - } - } - - // 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:" - + foregroundCall.getState()); - - droppedDuringPoll.add(pendingMO); - pendingMO = null; - hangupPendingMO = false; - } - - if (newRinging != null) { - phone.notifyNewRingingConnection(newRinging); - } - - // clear the "local hangup" and "missed/rejected call" - // cases from the "dropped during poll" list - // These cases need no "last call fail" reason - for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) { - GsmConnection conn = droppedDuringPoll.get(i); - - if (conn.isIncoming() && conn.getConnectTime() == 0) { - // Missed or rejected call - Connection.DisconnectCause cause; - if (conn.cause == Connection.DisconnectCause.LOCAL) { - cause = Connection.DisconnectCause.INCOMING_REJECTED; - } else { - cause = Connection.DisconnectCause.INCOMING_MISSED; - } - - if (Phone.DEBUG_PHONE) { - log("missed/rejected call, conn.cause=" + conn.cause); - log("setting cause to " + cause); - } - droppedDuringPoll.remove(i); - conn.onDisconnect(cause); - } else if (conn.cause == Connection.DisconnectCause.LOCAL) { - // Local hangup - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.LOCAL); - } else if (conn.cause == - Connection.DisconnectCause.INVALID_NUMBER) { - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); - } - } - - // Any non-local disconnects: determine cause - if (droppedDuringPoll.size() > 0) { - cm.getLastCallFailCause( - obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE)); - } - - if (needsPollDelay) { - pollCallsAfterDelay(); - } - - // Cases when we can no longer keep disconnected Connection's - // with their previous calls - // 1) the phone has started to ring - // 2) A Call/Connection object has changed state... - // we may have switched or held or answered (but not hung up) - if (newRinging != null || hasNonHangupStateChanged) { - internalClearDisconnected(); - } - - updatePhoneState(); - - if (unknownConnectionAppeared) { - phone.notifyUnknownConnection(); - } - - if (hasNonHangupStateChanged || newRinging != null) { - phone.notifyPreciseCallStateChanged(); - } - - //dumpState(); - } - - private void - handleRadioNotAvailable() { - // handlePollCalls will clear out its - // call list when it gets the CommandException - // error result from this - pollCallsWhenSafe(); - } - - private void - dumpState() { - List l; - - Log.i(LOG_TAG,"Phone State:" + state); - - Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString()); - - l = ringingCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - Log.i(LOG_TAG,"Foreground call: " + foregroundCall.toString()); - - l = foregroundCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - Log.i(LOG_TAG,"Background call: " + backgroundCall.toString()); - - l = backgroundCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - } - - //***** Called from GsmConnection - - /*package*/ void - hangup (GsmConnection conn) throws CallStateException { - if (conn.owner != this) { - throw new CallStateException ("GsmConnection " + conn - + "does not belong to GsmCallTracker " + this); - } - - if (conn == pendingMO) { - // We're hanging up an outgoing call that doesn't have it's - // GSM index assigned yet - - if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); - hangupPendingMO = true; - } else { - 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 " - + conn); - } - } - - conn.onHangupLocal(); - } - - /*package*/ void - separate (GsmConnection conn) throws CallStateException { - if (conn.owner != this) { - throw new CallStateException ("GsmConnection " + conn - + "does not belong to GsmCallTracker " + this); - } - try { - 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 " - + conn); - } - } - - //***** Called from GSMPhone - - /*package*/ void - setMute(boolean mute) { - desiredMute = mute; - cm.setMute(desiredMute, null); - } - - /*package*/ boolean - getMute() { - return desiredMute; - } - - - //***** Called from GsmCall - - /* package */ void - hangup (GsmCall call) throws CallStateException { - if (call.getConnections().size() == 0) { - throw new CallStateException("no connections in call"); - } - - if (call == ringingCall) { - if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } else if (call == foregroundCall) { - if (call.isDialingOrAlerting()) { - if (Phone.DEBUG_PHONE) { - log("(foregnd) hangup dialing or alerting..."); - } - hangup((GsmConnection)(call.getConnections().get(0))); - } else { - hangupForegroundResumeBackground(); - } - } else if (call == backgroundCall) { - if (ringingCall.isRinging()) { - if (Phone.DEBUG_PHONE) { - log("hangup all conns in background call"); - } - hangupAllConnections(call); - } else { - hangupWaitingOrBackground(); - } - } else { - throw new RuntimeException ("GsmCall " + call + - "does not belong to GsmCallTracker " + this); - } - - call.onHangupLocal(); - phone.notifyPreciseCallStateChanged(); - } - - /* package */ - void hangupWaitingOrBackground() { - if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } - - /* package */ - void hangupForegroundResumeBackground() { - if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground"); - cm.hangupForegroundResumeBackground(obtainCompleteMessage()); - } - - void hangupConnectionByIndex(GsmCall call, int index) - throws CallStateException { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GsmConnection cn = (GsmConnection)call.connections.get(i); - if (cn.getGSMIndex() == index) { - cm.hangupConnection(index, obtainCompleteMessage()); - return; - } - } - - throw new CallStateException("no gsm index found"); - } - - void hangupAllConnections(GsmCall call) throws CallStateException{ - try { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GsmConnection cn = (GsmConnection)call.connections.get(i); - cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage()); - } - } catch (CallStateException ex) { - Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex); - } - } - - /* package */ - GsmConnection getConnectionByIndex(GsmCall call, int index) - throws CallStateException { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GsmConnection cn = (GsmConnection)call.connections.get(i); - if (cn.getGSMIndex() == index) { - return cn; - } - } - - return null; - } - - private Phone.SuppService getFailedService(int what) { - switch (what) { - case EVENT_SWITCH_RESULT: - return Phone.SuppService.SWITCH; - case EVENT_CONFERENCE_RESULT: - return Phone.SuppService.CONFERENCE; - case EVENT_SEPARATE_RESULT: - return Phone.SuppService.SEPARATE; - case EVENT_ECT_RESULT: - return Phone.SuppService.TRANSFER; - } - return Phone.SuppService.UNKNOWN; - } - - //****** Overridden from Handler - - public void - handleMessage (Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_POLL_CALLS_RESULT: - ar = (AsyncResult)msg.obj; - - if (msg == lastRelevantPoll) { - if (DBG_POLL) log( - "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); - needsPoll = false; - lastRelevantPoll = null; - handlePollCalls((AsyncResult)msg.obj); - } - break; - - case EVENT_OPERATION_COMPLETE: - ar = (AsyncResult)msg.obj; - operationComplete(); - break; - - case EVENT_SWITCH_RESULT: - case EVENT_CONFERENCE_RESULT: - case EVENT_SEPARATE_RESULT: - case EVENT_ECT_RESULT: - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - phone.notifySuppServiceFailed(getFailedService(msg.what)); - } - operationComplete(); - break; - - case EVENT_GET_LAST_CALL_FAIL_CAUSE: - int causeCode; - ar = (AsyncResult)msg.obj; - - operationComplete(); - - if (ar.exception != null) { - // An exception occurred...just treat the disconnect - // cause as "normal" - causeCode = CallFailCause.NORMAL_CLEARING; - Log.i(LOG_TAG, - "Exception during getLastCallFailCause, assuming normal disconnect"); - } else { - causeCode = ((int[])ar.result)[0]; - } - // Log the causeCode if its not normal - if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL || - causeCode == CallFailCause.TEMPORARY_FAILURE || - causeCode == CallFailCause.SWITCHING_CONGESTION || - causeCode == CallFailCause.CHANNEL_NOT_AVAIL || - causeCode == CallFailCause.QOS_NOT_AVAIL || - causeCode == CallFailCause.BEARER_NOT_AVAIL || - causeCode == CallFailCause.ERROR_UNSPECIFIED) { - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - EventLog.writeEvent(EventLogTags.CALL_DROP, - causeCode, loc != null ? loc.getCid() : -1, - TelephonyManager.getDefault().getNetworkType()); - } - - for (int i = 0, s = droppedDuringPoll.size() - ; i < s ; i++ - ) { - GsmConnection conn = droppedDuringPoll.get(i); - - conn.onRemoteDisconnect(causeCode); - } - - updatePhoneState(); - - phone.notifyPreciseCallStateChanged(); - droppedDuringPoll.clear(); - break; - - case EVENT_REPOLL_AFTER_DELAY: - case EVENT_CALL_STATE_CHANGE: - pollCallsWhenSafe(); - break; - - case EVENT_RADIO_AVAILABLE: - handleRadioAvailable(); - break; - - case EVENT_RADIO_NOT_AVAILABLE: - handleRadioNotAvailable(); - break; - } - } - - protected void log(String msg) { - Log.d(LOG_TAG, "[GsmCallTracker] " + msg); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("GsmCallTracker extends:"); - super.dump(fd, pw, args); - pw.println("connections: length=" + connections.length); - for(int i=0; i < connections.length; i++) { - pw.printf(" connections[%d]=%s\n", i, connections[i]); - } - pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants); - pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants); - pw.println(" droppedDuringPoll: size=" + droppedDuringPoll.size()); - for(int i = 0; i < droppedDuringPoll.size(); i++) { - pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i)); - } - pw.println(" ringingCall=" + ringingCall); - pw.println(" foregroundCall=" + foregroundCall); - pw.println(" backgroundCall=" + backgroundCall); - pw.println(" pendingMO=" + pendingMO); - pw.println(" hangupPendingMO=" + hangupPendingMO); - pw.println(" phone=" + phone); - pw.println(" desiredMute=" + desiredMute); - pw.println(" state=" + state); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java deleted file mode 100644 index 9e32e8d57b0a..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java +++ /dev/null @@ -1,761 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.SystemClock; -import android.util.Log; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.text.TextUtils; - -import com.android.internal.telephony.*; - -/** - * {@hide} - */ -public class GsmConnection extends Connection { - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - GsmCallTracker owner; - GsmCall parent; - - String address; // MAY BE NULL!!! - String dialString; // outgoing calls only - String postDialString; // outgoing calls only - boolean isIncoming; - boolean disconnected; - - int index; // index in GsmCallTracker.connections[], -1 if unassigned - // The GSM index is 1 + this - - /* - * These time/timespan values are based on System.currentTimeMillis(), - * i.e., "wall clock" time. - */ - long createTime; - long connectTime; - long disconnectTime; - - /* - * These time/timespan values are based on SystemClock.elapsedRealTime(), - * i.e., time since boot. They are appropriate for comparison and - * calculating deltas. - */ - long connectTimeReal; - long duration; - 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; - int numberPresentation = Connection.PRESENTATION_ALLOWED; - UUSInfo uusInfo; - - Handler h; - - private PowerManager.WakeLock mPartialWakeLock; - - //***** Event Constants - static final int EVENT_DTMF_DONE = 1; - static final int EVENT_PAUSE_DONE = 2; - static final int EVENT_NEXT_POST_DIAL = 3; - static final int EVENT_WAKE_LOCK_TIMEOUT = 4; - - //***** Constants - static final int PAUSE_DELAY_FIRST_MILLIS = 100; - static final int PAUSE_DELAY_MILLIS = 3 * 1000; - static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000; - - //***** Inner Classes - - class MyHandler extends Handler { - MyHandler(Looper l) {super(l);} - - public void - handleMessage(Message msg) { - - switch (msg.what) { - case EVENT_NEXT_POST_DIAL: - case EVENT_DTMF_DONE: - case EVENT_PAUSE_DONE: - processNextPostDialChar(); - break; - case EVENT_WAKE_LOCK_TIMEOUT: - releaseWakeLock(); - break; - } - } - } - - //***** Constructors - - /** This is probably an MT call that we first saw in a CLCC response */ - /*package*/ - GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - address = dc.number; - - isIncoming = dc.isMT; - createTime = System.currentTimeMillis(); - cnapName = dc.name; - cnapNamePresentation = dc.namePresentation; - numberPresentation = dc.numberPresentation; - uusInfo = dc.uusInfo; - - this.index = index; - - parent = parentFromDCState (dc.state); - parent.attach(this, dc); - } - - /** This is an MO call, created when dialing */ - /*package*/ - GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - this.dialString = dialString; - - this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString); - this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString); - - index = -1; - - isIncoming = false; - cnapName = null; - cnapNamePresentation = Connection.PRESENTATION_ALLOWED; - numberPresentation = Connection.PRESENTATION_ALLOWED; - createTime = System.currentTimeMillis(); - - 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); - } - - /*package*/ boolean - compareTo(DriverCall c) { - // On mobile originated (MO) calls, the phone number may have changed - // due to a SIM Toolkit call control modification. - // - // We assume we know when MO calls are created (since we created them) - // and therefore don't need to compare the phone number anyway. - if (! (isIncoming || c.isMT)) return true; - - // ... but we can compare phone numbers on MT calls, and we have - // 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); - } - - public String getAddress() { - return address; - } - - public GsmCall getCall() { - return parent; - } - - public long getCreateTime() { - return createTime; - } - - public long getConnectTime() { - return connectTime; - } - - public long getDisconnectTime() { - return disconnectTime; - } - - public long getDurationMillis() { - if (connectTimeReal == 0) { - return 0; - } else if (duration == 0) { - return SystemClock.elapsedRealtime() - connectTimeReal; - } else { - return duration; - } - } - - public long getHoldDurationMillis() { - if (getState() != GsmCall.State.HOLDING) { - // If not holding, return 0 - return 0; - } else { - return SystemClock.elapsedRealtime() - holdingStartTime; - } - } - - public DisconnectCause getDisconnectCause() { - return cause; - } - - public boolean isIncoming() { - return isIncoming; - } - - public GsmCall.State getState() { - if (disconnected) { - return GsmCall.State.DISCONNECTED; - } else { - return super.getState(); - } - } - - public void hangup() throws CallStateException { - if (!disconnected) { - owner.hangup(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public void separate() throws CallStateException { - if (!disconnected) { - owner.separate(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public PostDialState getPostDialState() { - return postDialState; - } - - public void proceedAfterWaitChar() { - if (postDialState != PostDialState.WAIT) { - Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WAIT but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - processNextPostDialChar(); - } - - public void proceedAfterWildChar(String str) { - if (postDialState != PostDialState.WILD) { - Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WILD but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - if (false) { - boolean playedTone = false; - int len = (str != null ? str.length() : 0); - - for (int i=0; i(); - initApnContextsAndDataConnection(); - broadcastMessenger(); - } - - @Override - public void dispose() { - if (DBG) log("GsmDCT.dispose"); - cleanUpAllConnections(false, null); - - super.dispose(); - - //Unregister for all events - mPhone.mCM.unregisterForAvailable(this); - mPhone.mCM.unregisterForOffOrNotAvailable(this); - mPhone.mIccRecords.unregisterForRecordsLoaded(this); - mPhone.mCM.unregisterForDataNetworkStateChanged(this); - mPhone.getCallTracker().unregisterForVoiceCallEnded(this); - mPhone.getCallTracker().unregisterForVoiceCallStarted(this); - mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this); - mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this); - mPhone.getServiceStateTracker().unregisterForRoamingOn(this); - mPhone.getServiceStateTracker().unregisterForRoamingOff(this); - mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this); - mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this); - - mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver); - mApnContexts.clear(); - - destroyDataConnections(); - } - - @Override - public boolean isApnTypeActive(String type) { - ApnContext apnContext = mApnContexts.get(type); - if (apnContext == null) return false; - - return (apnContext.getDataConnection() != null); - } - - @Override - protected boolean isDataPossible(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext == null) { - return false; - } - boolean apnContextIsEnabled = apnContext.isEnabled(); - State apnContextState = apnContext.getState(); - boolean apnTypePossible = !(apnContextIsEnabled && - (apnContextState == State.FAILED)); - boolean dataAllowed = isDataAllowed(); - boolean possible = dataAllowed && apnTypePossible; - - if (DBG) { - log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " + - "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s", - apnType, possible, dataAllowed, apnTypePossible, - apnContextIsEnabled, apnContextState)); - } - return possible; - } - - @Override - protected void finalize() { - if(DBG) log("finalize"); - } - - @Override - protected String getActionIntentReconnectAlarm() { - return INTENT_RECONNECT_ALARM; - } - - @Override - protected String getActionIntentDataStallAlarm() { - return INTENT_DATA_STALL_ALARM; - } - - private ApnContext addApnContext(String type) { - ApnContext apnContext = new ApnContext(type, LOG_TAG); - apnContext.setDependencyMet(false); - mApnContexts.put(type, apnContext); - return apnContext; - } - - protected void initApnContextsAndDataConnection() { - boolean defaultEnabled = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, true); - // Load device network attributes from resources - String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray( - com.android.internal.R.array.networkAttributes); - for (String networkConfigString : networkConfigStrings) { - NetworkConfig networkConfig = new NetworkConfig(networkConfigString); - ApnContext apnContext = null; - - switch (networkConfig.type) { - case ConnectivityManager.TYPE_MOBILE: - apnContext = addApnContext(Phone.APN_TYPE_DEFAULT); - apnContext.setEnabled(defaultEnabled); - break; - case ConnectivityManager.TYPE_MOBILE_MMS: - apnContext = addApnContext(Phone.APN_TYPE_MMS); - break; - case ConnectivityManager.TYPE_MOBILE_SUPL: - apnContext = addApnContext(Phone.APN_TYPE_SUPL); - break; - case ConnectivityManager.TYPE_MOBILE_DUN: - apnContext = addApnContext(Phone.APN_TYPE_DUN); - break; - case ConnectivityManager.TYPE_MOBILE_HIPRI: - apnContext = addApnContext(Phone.APN_TYPE_HIPRI); - ApnContext defaultContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT); - if (defaultContext != null) { - applyNewState(apnContext, apnContext.isEnabled(), - defaultContext.getDependencyMet()); - } else { - // the default will set the hipri dep-met when it is created - } - continue; - case ConnectivityManager.TYPE_MOBILE_FOTA: - apnContext = addApnContext(Phone.APN_TYPE_FOTA); - break; - case ConnectivityManager.TYPE_MOBILE_IMS: - apnContext = addApnContext(Phone.APN_TYPE_IMS); - break; - case ConnectivityManager.TYPE_MOBILE_CBS: - apnContext = addApnContext(Phone.APN_TYPE_CBS); - break; - default: - // skip unknown types - continue; - } - if (apnContext != null) { - // set the prop, but also apply the newly set enabled and dependency values - onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet); - } - } - } - - @Override - protected LinkProperties getLinkProperties(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext != null) { - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (dcac != null) { - if (DBG) log("return link properites for " + apnType); - return dcac.getLinkPropertiesSync(); - } - } - if (DBG) log("return new LinkProperties"); - return new LinkProperties(); - } - - @Override - protected LinkCapabilities getLinkCapabilities(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext!=null) { - DataConnectionAc dataConnectionAc = apnContext.getDataConnectionAc(); - if (dataConnectionAc != null) { - if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType); - return dataConnectionAc.getLinkCapabilitiesSync(); - } - } - if (DBG) log("return new LinkCapabilities"); - return new LinkCapabilities(); - } - - @Override - // Return all active apn types - public String[] getActiveApnTypes() { - if (DBG) log("get all active apn types"); - ArrayList result = new ArrayList(); - - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.isReady()) { - result.add(apnContext.getApnType()); - } - } - - return (String[])result.toArray(new String[0]); - } - - @Override - // Return active apn of specific apn type - public String getActiveApnString(String apnType) { - if (DBG) log( "get active apn string for type:" + apnType); - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext != null) { - ApnSetting apnSetting = apnContext.getApnSetting(); - if (apnSetting != null) { - return apnSetting.apn; - } - } - return null; - } - - @Override - public boolean isApnTypeEnabled(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext == null) { - return false; - } - return apnContext.isEnabled(); - } - - @Override - protected void setState(State s) { - if (DBG) log("setState should not be used in GSM" + s); - } - - // Return state of specific apn type - @Override - public State getState(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext != null) { - return apnContext.getState(); - } - return State.FAILED; - } - - // Return state of overall - public State getOverallState() { - boolean isConnecting = false; - boolean isFailed = true; // All enabled Apns should be FAILED. - boolean isAnyEnabled = false; - - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.isEnabled()) { - isAnyEnabled = true; - switch (apnContext.getState()) { - case CONNECTED: - case DISCONNECTING: - if (DBG) log("overall state is CONNECTED"); - return State.CONNECTED; - case CONNECTING: - case INITING: - isConnecting = true; - isFailed = false; - break; - case IDLE: - case SCANNING: - isFailed = false; - break; - } - } - } - - if (!isAnyEnabled) { // Nothing enabled. return IDLE. - if (DBG) log( "overall state is IDLE"); - return State.IDLE; - } - - if (isConnecting) { - if (DBG) log( "overall state is CONNECTING"); - return State.CONNECTING; - } else if (!isFailed) { - if (DBG) log( "overall state is IDLE"); - return State.IDLE; - } else { - if (DBG) log( "overall state is FAILED"); - return State.FAILED; - } - } - - /** - * Ensure that we are connected to an APN of the specified type. - * - * @param type the APN type - * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or - * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a - * broadcast will be sent by the ConnectivityManager when a - * connection to the APN has been established. - */ - @Override - public synchronized int enableApnType(String apnType) { - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext == null || !isApnTypeAvailable(apnType)) { - if (DBG) log("enableApnType: " + apnType + " is type not available"); - return Phone.APN_TYPE_NOT_AVAILABLE; - } - - // If already active, return - if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")"); - - if (apnContext.getState() == State.CONNECTED) { - if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE"); - return Phone.APN_ALREADY_ACTIVE; - } - setEnabled(apnTypeToId(apnType), true); - if (DBG) { - log("enableApnType: new apn request for type " + apnType + - " return APN_REQUEST_STARTED"); - } - return Phone.APN_REQUEST_STARTED; - } - - // A new APN has gone active and needs to send events to catch up with the - // current condition - private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) { - switch (apnContext.getState()) { - case IDLE: - case INITING: - break; - case CONNECTING: - case SCANNING: - mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING); - break; - case CONNECTED: - case DISCONNECTING: - mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING); - mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTED); - break; - } - } - - @Override - public synchronized int disableApnType(String type) { - if (DBG) log("disableApnType:" + type); - ApnContext apnContext = mApnContexts.get(type); - - if (apnContext != null) { - setEnabled(apnTypeToId(type), false); - if (apnContext.getState() != State.IDLE && apnContext.getState() != State.FAILED) { - if (DBG) log("diableApnType: return APN_REQUEST_STARTED"); - return Phone.APN_REQUEST_STARTED; - } else { - if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE"); - return Phone.APN_ALREADY_INACTIVE; - } - - } else { - if (DBG) { - log("disableApnType: no apn context was found, return APN_REQUEST_FAILED"); - } - return Phone.APN_REQUEST_FAILED; - } - } - - @Override - protected boolean isApnTypeAvailable(String type) { - if (type.equals(Phone.APN_TYPE_DUN) && fetchDunApn() != null) { - return true; - } - - if (mAllApns != null) { - for (ApnSetting apn : mAllApns) { - if (apn.canHandleType(type)) { - return true; - } - } - } - return false; - } - - /** - * Report on whether data connectivity is enabled for any APN. - * @return {@code false} if data connectivity has been explicitly disabled, - * {@code true} otherwise. - */ - @Override - public boolean getAnyDataEnabled() { - synchronized (mDataEnabledLock) { - if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false; - for (ApnContext apnContext : mApnContexts.values()) { - // Make sure we dont have a context that going down - // and is explicitly disabled. - if (isDataAllowed(apnContext)) { - return true; - } - } - return false; - } - } - - private boolean isDataAllowed(ApnContext apnContext) { - return apnContext.isReady() && isDataAllowed(); - } - - //****** Called from ServiceStateTracker - /** - * Invoked when ServiceStateTracker observes a transition from GPRS - * attach to detach. - */ - protected void onDataConnectionDetached() { - /* - * We presently believe it is unnecessary to tear down the PDP context - * when GPRS detaches, but we should stop the network polling. - */ - if (DBG) log ("onDataConnectionDetached: stop polling and notify detached"); - stopNetStatPoll(); - stopDataStallAlarm(); - notifyDataConnection(Phone.REASON_DATA_DETACHED); - } - - private void onDataConnectionAttached() { - if (DBG) log("onDataConnectionAttached"); - if (getOverallState() == State.CONNECTED) { - if (DBG) log("onDataConnectionAttached: start polling notify attached"); - startNetStatPoll(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - notifyDataConnection(Phone.REASON_DATA_ATTACHED); - } else { - // update APN availability so that APN can be enabled. - notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED); - } - - setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED); - } - - @Override - protected boolean isDataAllowed() { - final boolean internalDataEnabled; - synchronized (mDataEnabledLock) { - internalDataEnabled = mInternalDataEnabled; - } - - int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState(); - boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState(); - - boolean allowed = - (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) && - mPhone.mIccRecords.getRecordsLoaded() && - (mPhone.getState() == Phone.State.IDLE || - mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) && - internalDataEnabled && - (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) && - !mIsPsRestricted && - desiredPowerState; - if (!allowed && DBG) { - String reason = ""; - if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) { - reason += " - gprs= " + gprsState; - } - if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded"; - if (mPhone.getState() != Phone.State.IDLE && - !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { - reason += " - PhoneState= " + mPhone.getState(); - reason += " - Concurrent voice and data not allowed"; - } - if (!internalDataEnabled) reason += " - mInternalDataEnabled= false"; - if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) { - reason += " - Roaming and data roaming not enabled"; - } - if (mIsPsRestricted) reason += " - mIsPsRestricted= true"; - if (!desiredPowerState) reason += " - desiredPowerState= false"; - if (DBG) log("isDataAllowed: not allowed due to" + reason); - } - return allowed; - } - - private void setupDataOnReadyApns(String reason) { - // Stop reconnect alarms on all data connections pending - // retry. Reset ApnContext state to IDLE. - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - if (dcac.getReconnectIntentSync() != null) { - cancelReconnectAlarm(dcac); - } - // update retry config for existing calls to match up - // ones for the new RAT. - if (dcac.dataConnection != null) { - Collection apns = dcac.getApnListSync(); - - boolean hasDefault = false; - for (ApnContext apnContext : apns) { - if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) { - hasDefault = true; - break; - } - } - configureRetry(dcac.dataConnection, hasDefault); - } - } - - // Only check for default APN state - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getState() == State.FAILED) { - // By this time, alarms for all failed Apns - // should be stopped if any. - // Make sure to set the state back to IDLE - // so that setup data can happen. - apnContext.setState(State.IDLE); - } - if (apnContext.isReady()) { - if (apnContext.getState() == State.IDLE) { - apnContext.setReason(reason); - trySetupData(apnContext); - } - } - } - } - - private boolean trySetupData(String reason, String type) { - if (DBG) { - log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason) - + " isPsRestricted=" + mIsPsRestricted); - } - - if (type == null) { - type = Phone.APN_TYPE_DEFAULT; - } - - ApnContext apnContext = mApnContexts.get(type); - - if (apnContext == null ){ - if (DBG) log("trySetupData new apn context for type:" + type); - apnContext = new ApnContext(type, LOG_TAG); - mApnContexts.put(type, apnContext); - } - apnContext.setReason(reason); - - return trySetupData(apnContext); - } - - private boolean trySetupData(ApnContext apnContext) { - if (DBG) { - log("trySetupData for type:" + apnContext.getApnType() + - " due to " + apnContext.getReason()); - log("trySetupData with mIsPsRestricted=" + mIsPsRestricted); - } - - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - apnContext.setState(State.CONNECTED); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - - log("trySetupData: (fix?) We're on the simulator; assuming data is connected"); - return true; - } - - boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState(); - - if ((apnContext.getState() == State.IDLE || apnContext.getState() == State.SCANNING) && - isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) { - - if (apnContext.getState() == State.IDLE) { - ArrayList waitingApns = buildWaitingApns(apnContext.getApnType()); - if (waitingApns.isEmpty()) { - if (DBG) log("trySetupData: No APN found"); - notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext); - notifyOffApnsOfAvailability(apnContext.getReason()); - return false; - } else { - apnContext.setWaitingApns(waitingApns); - if (DBG) { - log ("trySetupData: Create from mAllApns : " + apnListToString(mAllApns)); - } - } - } - - if (DBG) { - log ("Setup watingApns : " + apnListToString(apnContext.getWaitingApns())); - } - // apnContext.setReason(apnContext.getReason()); - boolean retValue = setupData(apnContext); - notifyOffApnsOfAvailability(apnContext.getReason()); - return retValue; - } else { - // TODO: check the condition. - if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT) - && (apnContext.getState() == State.IDLE - || apnContext.getState() == State.SCANNING)) - mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType()); - notifyOffApnsOfAvailability(apnContext.getReason()); - return false; - } - } - - @Override - // Disabled apn's still need avail/unavail notificiations - send them out - protected void notifyOffApnsOfAvailability(String reason) { - for (ApnContext apnContext : mApnContexts.values()) { - if (!apnContext.isReady()) { - if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType()); - mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(), - apnContext.getApnType(), - Phone.DataState.DISCONNECTED); - } else { - if (DBG) { - log("notifyOffApnsOfAvailability skipped apn due to isReady==false: " + - apnContext.toString()); - } - } - } - } - - /** - * If tearDown is true, this only tears down a CONNECTED session. Presently, - * there is no mechanism for abandoning an INITING/CONNECTING session, - * but would likely involve cancelling pending async requests or - * setting a flag or new state to ignore them when they came in - * @param tearDown true if the underlying GsmDataConnection should be - * disconnected. - * @param reason reason for the clean up. - */ - protected void cleanUpAllConnections(boolean tearDown, String reason) { - if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason); - - for (ApnContext apnContext : mApnContexts.values()) { - apnContext.setReason(reason); - cleanUpConnection(tearDown, apnContext); - } - - stopNetStatPoll(); - stopDataStallAlarm(); - - // TODO: Do we need mRequestedApnType? - mRequestedApnType = Phone.APN_TYPE_DEFAULT; - } - - /** - * Cleanup all connections. - * - * TODO: Cleanup only a specified connection passed as a parameter. - * Also, make sure when you clean up a conn, if it is last apply - * logic as though it is cleanupAllConnections - * - * @param tearDown true if the underlying DataConnection should be disconnected. - * @param reason for the clean up. - */ - - @Override - protected void onCleanUpAllConnections(String cause) { - cleanUpAllConnections(true, cause); - } - - private void cleanUpConnection(boolean tearDown, ApnContext apnContext) { - - if (apnContext == null) { - if (DBG) log("cleanUpConnection: apn context is null"); - return; - } - - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (DBG) { - log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() + - " apnContext=" + apnContext); - } - if (tearDown) { - if (apnContext.isDisconnected()) { - // The request is tearDown and but ApnContext is not connected. - // If apnContext is not enabled anymore, break the linkage to the DCAC/DC. - apnContext.setState(State.IDLE); - if (!apnContext.isReady()) { - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); - } - } else { - // Connection is still there. Try to clean up. - if (dcac != null) { - if (apnContext.getState() != State.DISCONNECTING) { - boolean disconnectAll = false; - if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) { - ApnSetting dunSetting = fetchDunApn(); - if (dunSetting != null && - dunSetting.equals(apnContext.getApnSetting())) { - if (DBG) log("tearing down dedicated DUN connection"); - // we need to tear it down - we brought it up just for dun and - // other people are camped on it and now dun is done. We need - // to stop using it and let the normal apn list get used to find - // connections for the remaining desired connections - disconnectAll = true; - } - } - if (DBG) { - log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :"")); - } - Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext); - if (disconnectAll) { - apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg); - } else { - apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); - } - apnContext.setState(State.DISCONNECTING); - } - } else { - // apn is connected but no reference to dcac. - // Should not be happen, but reset the state in case. - apnContext.setState(State.IDLE); - mPhone.notifyDataConnection(apnContext.getReason(), - apnContext.getApnType()); - } - } - } else { - // force clean up the data connection. - if (dcac != null) dcac.resetSync(); - apnContext.setState(State.IDLE); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); - } - - // make sure reconnection alarm is cleaned up if there is no ApnContext - // associated to the connection. - if (dcac != null) { - Collection apnList = dcac.getApnListSync(); - if (apnList.isEmpty()) { - cancelReconnectAlarm(dcac); - } - } - if (DBG) { - log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() + - " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection()); - } - } - - /** - * Cancels the alarm associated with DCAC. - * - * @param DataConnectionAc on which the alarm should be stopped. - */ - private void cancelReconnectAlarm(DataConnectionAc dcac) { - if (dcac == null) return; - - PendingIntent intent = dcac.getReconnectIntentSync(); - - if (intent != null) { - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - am.cancel(intent); - dcac.setReconnectIntentSync(null); - } - } - - /** - * @param types comma delimited list of APN types - * @return array of APN types - */ - private String[] parseTypes(String types) { - String[] result; - // If unset, set to DEFAULT. - if (types == null || types.equals("")) { - result = new String[1]; - result[0] = Phone.APN_TYPE_ALL; - } else { - result = types.split(","); - } - return result; - } - - private ArrayList createApnList(Cursor cursor) { - ArrayList result = new ArrayList(); - if (cursor.moveToFirst()) { - do { - String[] types = parseTypes( - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE))); - ApnSetting apn = new ApnSetting( - cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)), - NetworkUtils.trimV4AddrZeros( - cursor.getString( - cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)), - NetworkUtils.trimV4AddrZeros( - cursor.getString( - cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))), - NetworkUtils.trimV4AddrZeros( - cursor.getString( - cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)), - cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)), - types, - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)), - cursor.getString(cursor.getColumnIndexOrThrow( - Telephony.Carriers.ROAMING_PROTOCOL)), - cursor.getInt(cursor.getColumnIndexOrThrow( - Telephony.Carriers.CARRIER_ENABLED)) == 1, - cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER))); - result.add(apn); - } while (cursor.moveToNext()); - } - if (DBG) log("createApnList: X result=" + result); - return result; - } - - private boolean dataConnectionNotInUse(DataConnectionAc dcac) { - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getDataConnectionAc() == dcac) return false; - } - return true; - } - - private GsmDataConnection findFreeDataConnection() { - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) { - DataConnection dc = dcac.dataConnection; - if (DBG) { - log("findFreeDataConnection: found free GsmDataConnection=" + - " dcac=" + dcac + " dc=" + dc); - } - return (GsmDataConnection) dc; - } - } - log("findFreeDataConnection: NO free GsmDataConnection"); - return null; - } - - protected GsmDataConnection findReadyDataConnection(ApnSetting apn) { - if (apn == null) { - return null; - } - if (DBG) { - log("findReadyDataConnection: apn string <" + apn + ">" + - " dcacs.size=" + mDataConnectionAsyncChannels.size()); - } - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - ApnSetting apnSetting = dcac.getApnSettingSync(); - if (DBG) { - log("findReadyDataConnection: dc apn string <" + - (apnSetting != null ? (apnSetting.toString()) : "null") + ">"); - } - if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) { - DataConnection dc = dcac.dataConnection; - if (DBG) { - log("findReadyDataConnection: found ready GsmDataConnection=" + - " dcac=" + dcac + " dc=" + dc); - } - return (GsmDataConnection) dc; - } - } - return null; - } - - - private boolean setupData(ApnContext apnContext) { - if (DBG) log("setupData: apnContext=" + apnContext); - ApnSetting apn; - GsmDataConnection dc; - - int profileId = getApnProfileID(apnContext.getApnType()); - apn = apnContext.getNextWaitingApn(); - if (apn == null) { - if (DBG) log("setupData: return for no apn found!"); - return false; - } - - - dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext); - - if (dc == null) { - dc = findReadyDataConnection(apn); - - if (dc == null) { - if (DBG) log("setupData: No ready GsmDataConnection found!"); - // TODO: When allocating you are mapping type to id. If more than 1 free, - // then could findFreeDataConnection get the wrong one?? - dc = findFreeDataConnection(); - } - - if (dc == null) { - dc = createDataConnection(); - } - - if (dc == null) { - if (DBG) log("setupData: No free GsmDataConnection found!"); - return false; - } - } else { - apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync(); - } - - DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()); - dc.setProfileId( profileId ); // assumed no connection sharing on profiled types - - int refCount = dcac.getRefCountSync(); - if (DBG) log("setupData: init dc and apnContext refCount=" + refCount); - - // configure retry count if no other Apn is using the same connection. - if (refCount == 0) { - configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT)); - } - apnContext.setDataConnectionAc(dcac); - apnContext.setDataConnection(dc); - - apnContext.setApnSetting(apn); - apnContext.setState(State.INITING); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - // If reconnect alarm is active on this DataConnection, wait for the alarm being - // fired so that we don't disruppt data retry pattern engaged. - if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) { - if (DBG) log("setupData: data reconnection pending"); - apnContext.setState(State.FAILED); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - return true; - } - - Message msg = obtainMessage(); - msg.what = EVENT_DATA_SETUP_COMPLETE; - msg.obj = apnContext; - dc.bringUp(msg, apn); - - if (DBG) log("setupData: initing!"); - return true; - } - - /** - * Handles changes to the APN database. - */ - private void onApnChanged() { - State overallState = getOverallState(); - boolean isDisconnected = (overallState == State.IDLE || overallState == State.FAILED); - - if (mPhone instanceof GSMPhone) { - // The "current" may no longer be valid. MMS depends on this to send properly. TBD - ((GSMPhone)mPhone).updateCurrentCarrierInProvider(); - } - - // TODO: It'd be nice to only do this if the changed entrie(s) - // match the current operator. - if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections"); - createAllApnList(); - cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED); - if (isDisconnected) { - setupDataOnReadyApns(Phone.REASON_APN_CHANGED); - } - } - - /** - * @param cid Connection id provided from RIL. - * @return DataConnectionAc associated with specified cid. - */ - private DataConnectionAc findDataConnectionAcByCid(int cid) { - for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { - if (dcac.getCidSync() == cid) { - return dcac; - } - } - return null; - } - - /** - * @param dcacs Collection of DataConnectionAc reported from RIL. - * @return List of ApnContext which is connected, but is not present in - * data connection list reported from RIL. - */ - private List findApnContextToClean(Collection dcacs) { - if (dcacs == null) return null; - - if (DBG) log("findApnContextToClean(ar): E dcacs=" + dcacs); - - ArrayList list = new ArrayList(); - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getState() == State.CONNECTED) { - boolean found = false; - for (DataConnectionAc dcac : dcacs) { - if (dcac == apnContext.getDataConnectionAc()) { - // ApnContext holds the ref to dcac present in data call list. - found = true; - break; - } - } - if (!found) { - // ApnContext does not have dcac reported in data call list. - // Fetch all the ApnContexts that map to this dcac which are in - // INITING state too. - if (DBG) log("findApnContextToClean(ar): Connected apn not found in the list (" + - apnContext.toString() + ")"); - if (apnContext.getDataConnectionAc() != null) { - list.addAll(apnContext.getDataConnectionAc().getApnListSync()); - } else { - list.add(apnContext); - } - } - } - } - if (DBG) log("findApnContextToClean(ar): X list=" + list); - return list; - } - - /** - * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST - * or RIL_UNSOL_DATA_CALL_LIST_CHANGED - */ - private void onDataStateChanged (AsyncResult ar) { - ArrayList dataCallStates; - - if (DBG) log("onDataStateChanged(ar): E"); - dataCallStates = (ArrayList)(ar.result); - - 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 - if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore"); - return; - } - if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size()); - - // Create a hash map to store the dataCallState of each DataConnectionAc - HashMap dataCallStateToDcac; - dataCallStateToDcac = new HashMap(); - for (DataCallState dataCallState : dataCallStates) { - DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid); - - if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac); - } - - // A list of apns to cleanup, those that aren't in the list we know we have to cleanup - List apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values()); - - // Find which connections have changed state and send a notification or cleanup - for (DataCallState newState : dataCallStates) { - DataConnectionAc dcac = dataCallStateToDcac.get(newState); - - if (dcac == null) { - loge("onDataStateChanged(ar): No associated DataConnection ignore"); - continue; - } - - // The list of apn's associated with this DataConnection - Collection apns = dcac.getApnListSync(); - - // Find which ApnContexts of this DC are in the "Connected/Connecting" state. - ArrayList connectedApns = new ArrayList(); - for (ApnContext apnContext : apns) { - if (apnContext.getState() == State.CONNECTED || - apnContext.getState() == State.CONNECTING || - apnContext.getState() == State.INITING) { - connectedApns.add(apnContext); - } - } - if (connectedApns.size() == 0) { - if (DBG) log("onDataStateChanged(ar): no connected apns"); - } else { - // Determine if the connection/apnContext should be cleaned up - // or just a notification should be sent out. - if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid - + " newState=" + newState.toString()); - if (newState.active == 0) { - if (DBG) { - log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns); - } - apnsToCleanup.addAll(connectedApns); - } else { - // Its active so update the DataConnections link properties - UpdateLinkPropertyResult result = - dcac.updateLinkPropertiesDataCallStateSync(newState); - if (result.oldLp.equals(result.newLp)) { - if (DBG) log("onDataStateChanged(ar): no change"); - } else { - if (result.oldLp.isIdenticalInterfaceName(result.newLp)) { - if (! result.oldLp.isIdenticalDnses(result.newLp) || - ! result.oldLp.isIdenticalRoutes(result.newLp) || - ! result.oldLp.isIdenticalHttpProxy(result.newLp) || - ! result.oldLp.isIdenticalAddresses(result.newLp)) { - // If the same address type was removed and added we need to cleanup - CompareResult car = - result.oldLp.compareAddresses(result.newLp); - if (DBG) { - log("onDataStateChanged: oldLp=" + result.oldLp + - " newLp=" + result.newLp + " car=" + car); - } - boolean needToClean = false; - for (LinkAddress added : car.added) { - for (LinkAddress removed : car.removed) { - if (NetworkUtils.addressTypeMatches(removed.getAddress(), - added.getAddress())) { - needToClean = true; - break; - } - } - } - if (needToClean) { - if (DBG) { - log("onDataStateChanged(ar): addr change, cleanup apns=" + - connectedApns + " oldLp=" + result.oldLp + - " newLp=" + result.newLp); - } - apnsToCleanup.addAll(connectedApns); - } else { - if (DBG) log("onDataStateChanged(ar): simple change"); - for (ApnContext apnContext : connectedApns) { - mPhone.notifyDataConnection( - Phone.REASON_LINK_PROPERTIES_CHANGED, - apnContext.getApnType()); - } - } - } else { - if (DBG) { - log("onDataStateChanged(ar): no changes"); - } - } - } else { - if (DBG) { - log("onDataStateChanged(ar): interface change, cleanup apns=" - + connectedApns); - } - apnsToCleanup.addAll(connectedApns); - } - } - } - } - } - - if (apnsToCleanup.size() != 0) { - // Add an event log when the network drops PDP - int cid = getCellLocationId(); - EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid, - TelephonyManager.getDefault().getNetworkType()); - } - - // Cleanup those dropped connections - if (DBG) log("onDataStateChange(ar): apnsToCleanup=" + apnsToCleanup); - for (ApnContext apnContext : apnsToCleanup) { - cleanUpConnection(true, apnContext); - } - - if (DBG) log("onDataStateChanged(ar): X"); - } - - private void notifyDefaultData(ApnContext apnContext) { - if (DBG) { - log("notifyDefaultData: type=" + apnContext.getApnType() - + ", reason:" + apnContext.getReason()); - } - apnContext.setState(State.CONNECTED); - // setState(State.CONNECTED); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - startNetStatPoll(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - // reset reconnect timer - apnContext.getDataConnection().resetRetryCount(); - } - - // TODO: For multiple Active APNs not exactly sure how to do this. - protected void gotoIdleAndNotifyDataConnection(String reason) { - if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason); - notifyDataConnection(reason); - mActiveApn = null; - } - - private void resetPollStats() { - mTxPkts = -1; - mRxPkts = -1; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - } - - private void doRecovery() { - if (getOverallState() == State.CONNECTED) { - // Go through a series of recovery steps, each action transitions to the next action - int recoveryAction = getRecoveryAction(); - switch (recoveryAction) { - case RecoveryAction.GET_DATA_CALL_LIST: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST, - mSentSinceLastRecv); - if (DBG) log("doRecovery() get data call list"); - mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED)); - putRecoveryAction(RecoveryAction.CLEANUP); - break; - case RecoveryAction.CLEANUP: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv); - if (DBG) log("doRecovery() cleanup all connections"); - cleanUpAllConnections(true, Phone.REASON_PDP_RESET); - putRecoveryAction(RecoveryAction.REREGISTER); - break; - case RecoveryAction.REREGISTER: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER, - mSentSinceLastRecv); - if (DBG) log("doRecovery() re-register"); - mPhone.getServiceStateTracker().reRegisterNetwork(null); - putRecoveryAction(RecoveryAction.RADIO_RESTART); - break; - case RecoveryAction.RADIO_RESTART: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART, - mSentSinceLastRecv); - if (DBG) log("restarting radio"); - putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP); - restartRadio(); - break; - case RecoveryAction.RADIO_RESTART_WITH_PROP: - // This is in case radio restart has not recovered the data. - // It will set an additional "gsm.radioreset" property to tell - // RIL or system to take further action. - // The implementation of hard reset recovery action is up to OEM product. - // Once gsm.radioreset property is consumed, it is expected to set back - // to false by RIL. - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1); - if (DBG) log("restarting radio with gsm.radioreset to true"); - SystemProperties.set("gsm.radioreset", "true"); - // give 1 sec so property change can be notified. - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - restartRadio(); - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - break; - default: - throw new RuntimeException("doRecovery: Invalid recoveryAction=" + - recoveryAction); - } - } - } - - @Override - protected void startNetStatPoll() { - if (getOverallState() == State.CONNECTED && mNetStatPollEnabled == false) { - if (DBG) log("startNetStatPoll"); - resetPollStats(); - mNetStatPollEnabled = true; - mPollNetStat.run(); - } - } - - @Override - protected void stopNetStatPoll() { - mNetStatPollEnabled = false; - removeCallbacks(mPollNetStat); - if (DBG) log("stopNetStatPoll"); - } - - @Override - protected void restartRadio() { - if (DBG) log("restartRadio: ************TURN OFF RADIO**************"); - cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF); - mPhone.getServiceStateTracker().powerOffRadioSafely(this); - /* 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. - */ - - int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0")); - SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1)); - } - - - private void updateDataStallInfo() { - long sent, received; - - TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum); - mDataStallTxRxSum.updateTxRxSum(); - - if (VDBG) { - log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum + - " preTxRxSum=" + preTxRxSum); - } - - sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts; - received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts; - - if (RADIO_TESTS) { - if (SystemProperties.getBoolean("radio.test.data.stall", false)) { - log("updateDataStallInfo: radio.test.data.stall true received = 0;"); - received = 0; - } - } - if ( sent > 0 && received > 0 ) { - if (VDBG) log("updateDataStallInfo: IN/OUT"); - mSentSinceLastRecv = 0; - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - } else if (sent > 0 && received == 0) { - if (mPhone.getState() == Phone.State.IDLE) { - mSentSinceLastRecv += sent; - } else { - mSentSinceLastRecv = 0; - } - if (DBG) { - log("updateDataStallInfo: OUT sent=" + sent + - " mSentSinceLastRecv=" + mSentSinceLastRecv); - } - } else if (sent == 0 && received > 0) { - if (VDBG) log("updateDataStallInfo: IN"); - mSentSinceLastRecv = 0; - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - } else { - if (VDBG) log("updateDataStallInfo: NONE"); - } - } - - @Override - protected void onDataStallAlarm(int tag) { - if (mDataStallAlarmTag != tag) { - if (DBG) { - log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag); - } - return; - } - updateDataStallInfo(); - - int hangWatchdogTrigger = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, - NUMBER_SENT_PACKETS_OF_HANG); - - boolean suspectedStall = DATA_STALL_NOT_SUSPECTED; - if (mSentSinceLastRecv >= hangWatchdogTrigger) { - if (DBG) { - log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction()); - } - suspectedStall = DATA_STALL_SUSPECTED; - sendMessage(obtainMessage(EVENT_DO_RECOVERY)); - } else { - if (VDBG) { - log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) + - " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger); - } - } - startDataStallAlarm(suspectedStall); - } - - - private void updateDataActivity() { - long sent, received; - - Activity newActivity; - - TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts); - TxRxSum curTxRxSum = new TxRxSum(); - curTxRxSum.updateTxRxSum(); - mTxPkts = curTxRxSum.txPkts; - mRxPkts = curTxRxSum.rxPkts; - - if (VDBG) { - log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum); - } - - if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) { - sent = mTxPkts - preTxRxSum.txPkts; - received = mRxPkts - preTxRxSum.rxPkts; - - if (VDBG) log("updateDataActivity: sent=" + sent + " received=" + received); - if ( sent > 0 && received > 0 ) { - newActivity = Activity.DATAINANDOUT; - } else if (sent > 0 && received == 0) { - newActivity = Activity.DATAOUT; - } else if (sent == 0 && received > 0) { - newActivity = Activity.DATAIN; - } else { - newActivity = Activity.NONE; - } - - if (mActivity != newActivity && mIsScreenOn) { - if (VDBG) log("updateDataActivity: newActivity=" + newActivity); - mActivity = newActivity; - mPhone.notifyDataActivity(); - } - } - } - - private Runnable mPollNetStat = new Runnable() - { - @Override - public void run() { - updateDataActivity(); - - if (mIsScreenOn) { - mNetStatPollPeriod = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS); - } else { - mNetStatPollPeriod = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS, - POLL_NETSTAT_SCREEN_OFF_MILLIS); - } - - if (mNetStatPollEnabled) { - mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod); - } - } - }; - - /** - * Returns true if the last fail cause is something that - * seems like it deserves an error notification. - * Transient errors are ignored - */ - private boolean shouldPostNotification(GsmDataConnection.FailCause cause) { - return (cause != GsmDataConnection.FailCause.UNKNOWN); - } - - /** - * Return true if data connection need to be setup after disconnected due to - * reason. - * - * @param reason the reason why data is disconnected - * @return true if try setup data connection is need for this reason - */ - private boolean retryAfterDisconnected(String reason) { - boolean retry = true; - - if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) { - retry = false; - } - return retry; - } - - private void reconnectAfterFail(FailCause lastFailCauseCode, - ApnContext apnContext, int retryOverride) { - if (apnContext == null) { - loge("reconnectAfterFail: apnContext == null, impossible"); - return; - } - if ((apnContext.getState() == State.FAILED) && - (apnContext.getDataConnection() != null)) { - if (!apnContext.getDataConnection().isRetryNeeded()) { - if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) { - mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType()); - return; - } - if (mReregisterOnReconnectFailure) { - // We've re-registerd once now just retry forever. - apnContext.getDataConnection().retryForeverUsingLastTimeout(); - } else { - // Try to Re-register to the network. - if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network"); - mReregisterOnReconnectFailure = true; - mPhone.getServiceStateTracker().reRegisterNetwork(null); - apnContext.getDataConnection().resetRetryCount(); - return; - } - } - - // If retry needs to be backed off for specific case (determined by RIL/Modem) - // use the specified timer instead of pre-configured retry pattern. - int nextReconnectDelay = retryOverride; - if (nextReconnectDelay < 0) { - nextReconnectDelay = apnContext.getDataConnection().getRetryTimer(); - apnContext.getDataConnection().increaseRetryCount(); - } - startAlarmForReconnect(nextReconnectDelay, apnContext); - - if (!shouldPostNotification(lastFailCauseCode)) { - if (DBG) { - log("reconnectAfterFail: NOT Posting GPRS Unavailable notification " - + "-- likely transient error"); - } - } else { - notifyNoData(lastFailCauseCode, apnContext); - } - } - } - - private void startAlarmForReconnect(int delay, ApnContext apnContext) { - - if (DBG) { - log("Schedule alarm for reconnect: activate failed. Scheduling next attempt for " - + (delay / 1000) + "s"); - } - - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - - if ((dcac == null) || (dcac.dataConnection == null)) { - // should not happen, but just in case. - loge("null dcac or dc."); - return; - } - - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - - Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' + - dcac.dataConnection.getDataConnectionId()); - intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason()); - intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, - dcac.dataConnection.getDataConnectionId()); - - PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0, - intent, 0); - dcac.setReconnectIntentSync(alarmIntent); - am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delay, alarmIntent); - - } - - private void startDataStallAlarm(boolean suspectedStall) { - int nextAction = getRecoveryAction(); - int delayInMs; - - // If screen is on or data stall is currently suspected, set the alarm - // with an aggresive timeout. - if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) { - delayInMs = Settings.Secure.getInt(mResolver, - Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS, - DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT); - } else { - delayInMs = Settings.Secure.getInt(mResolver, - Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS, - DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT); - } - - mDataStallAlarmTag += 1; - if (VDBG) { - log("startDataStallAlarm: tag=" + mDataStallAlarmTag + - " delay=" + (delayInMs / 1000) + "s"); - } - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - - Intent intent = new Intent(INTENT_DATA_STALL_ALARM); - intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag); - mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent); - } - - private void stopDataStallAlarm() { - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - - if (VDBG) { - log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag + - " mDataStallAlarmIntent=" + mDataStallAlarmIntent); - } - mDataStallAlarmTag += 1; - if (mDataStallAlarmIntent != null) { - am.cancel(mDataStallAlarmIntent); - mDataStallAlarmIntent = null; - } - } - - @Override - protected void restartDataStallAlarm() { - if (isConnected() == false) return; - // To be called on screen status change. - // Do not cancel the alarm if it is set with aggressive timeout. - int nextAction = getRecoveryAction(); - - if (RecoveryAction.isAggressiveRecovery(nextAction)) { - if (DBG) log("data stall recovery action is pending. not resetting the alarm."); - return; - } - stopDataStallAlarm(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - } - - private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode, - ApnContext apnContext) { - if (DBG) log( "notifyNoData: type=" + apnContext.getApnType()); - apnContext.setState(State.FAILED); - if (lastFailCauseCode.isPermanentFail() - && (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT))) { - mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType()); - } - } - - private void onRecordsLoaded() { - if (DBG) log("onRecordsLoaded: createAllApnList"); - createAllApnList(); - if (mPhone.mCM.getRadioState().isOn()) { - if (DBG) log("onRecordsLoaded: notifying data availability"); - notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED); - } - setupDataOnReadyApns(Phone.REASON_SIM_LOADED); - } - - @Override - protected void onSetDependencyMet(String apnType, boolean met) { - // don't allow users to tweak hipri to work around default dependency not met - if (Phone.APN_TYPE_HIPRI.equals(apnType)) return; - - ApnContext apnContext = mApnContexts.get(apnType); - if (apnContext == null) { - loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" + - apnType + ", " + met + ")"); - return; - } - applyNewState(apnContext, apnContext.isEnabled(), met); - if (Phone.APN_TYPE_DEFAULT.equals(apnType)) { - // tie actions on default to similar actions on HIPRI regarding dependencyMet - apnContext = mApnContexts.get(Phone.APN_TYPE_HIPRI); - if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met); - } - } - - private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) { - boolean cleanup = false; - boolean trySetup = false; - if (DBG) { - log("applyNewState(" + apnContext.getApnType() + ", " + enabled + - "(" + apnContext.isEnabled() + "), " + met + "(" + - apnContext.getDependencyMet() +"))"); - } - if (apnContext.isReady()) { - if (enabled && met) return; - if (!enabled) { - apnContext.setReason(Phone.REASON_DATA_DISABLED); - } else { - apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET); - } - cleanup = true; - } else { - if (enabled && met) { - if (apnContext.isEnabled()) { - apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET); - } else { - apnContext.setReason(Phone.REASON_DATA_ENABLED); - } - if (apnContext.getState() == State.FAILED) { - apnContext.setState(State.IDLE); - } - trySetup = true; - } - } - apnContext.setEnabled(enabled); - apnContext.setDependencyMet(met); - if (cleanup) cleanUpConnection(true, apnContext); - if (trySetup) trySetupData(apnContext); - } - - private DataConnection checkForConnectionForApnContext(ApnContext apnContext) { - // Loop through all apnContexts looking for one with a conn that satisfies this apnType - String apnType = apnContext.getApnType(); - ApnSetting dunSetting = null; - - if (Phone.APN_TYPE_DUN.equals(apnType)) { - dunSetting = fetchDunApn(); - } - - DataConnection potential = null; - for (ApnContext c : mApnContexts.values()) { - DataConnection conn = c.getDataConnection(); - if (conn != null) { - ApnSetting apnSetting = c.getApnSetting(); - if (dunSetting != null) { - if (dunSetting.equals(apnSetting)) { - switch (c.getState()) { - case CONNECTED: - if (DBG) { - log("checkForConnectionForApnContext: apnContext=" + - apnContext + " found conn=" + conn); - } - return conn; - case CONNECTING: - potential = conn; - } - } - } else if (apnSetting != null && apnSetting.canHandleType(apnType)) { - switch (c.getState()) { - case CONNECTED: - if (DBG) { - log("checkForConnectionForApnContext: apnContext=" + apnContext + - " found conn=" + conn); - } - return conn; - case CONNECTING: - potential = conn; - } - } - } - } - if (potential != null) { - if (DBG) { - log("checkForConnectionForApnContext: apnContext=" + apnContext + - " found conn=" + potential); - } - return potential; - } - - if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn"); - return null; - } - - @Override - protected void onEnableApn(int apnId, int enabled) { - ApnContext apnContext = mApnContexts.get(apnIdToType(apnId)); - if (apnContext == null) { - loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext"); - return; - } - // TODO change our retry manager to use the appropriate numbers for the new APN - if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState"); - applyNewState(apnContext, enabled == ENABLED, apnContext.getDependencyMet()); - } - - @Override - // TODO: We shouldnt need this. - protected boolean onTrySetupData(String reason) { - if (DBG) log("onTrySetupData: reason=" + reason); - setupDataOnReadyApns(reason); - return true; - } - - protected boolean onTrySetupData(ApnContext apnContext) { - if (DBG) log("onTrySetupData: apnContext=" + apnContext); - return trySetupData(apnContext); - } - - @Override - protected void onRoamingOff() { - if (DBG) log("onRoamingOff"); - - if (mUserDataEnabled == false) return; - - if (getDataOnRoamingEnabled() == false) { - notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF); - setupDataOnReadyApns(Phone.REASON_ROAMING_OFF); - } else { - notifyDataConnection(Phone.REASON_ROAMING_OFF); - } - } - - @Override - protected void onRoamingOn() { - if (mUserDataEnabled == false) return; - - if (getDataOnRoamingEnabled()) { - if (DBG) log("onRoamingOn: setup data on roaming"); - setupDataOnReadyApns(Phone.REASON_ROAMING_ON); - notifyDataConnection(Phone.REASON_ROAMING_ON); - } else { - if (DBG) log("onRoamingOn: Tear down data connection on roaming."); - cleanUpAllConnections(true, Phone.REASON_ROAMING_ON); - notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON); - } - } - - @Override - protected void onRadioAvailable() { - if (DBG) log("onRadioAvailable"); - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - // setState(State.CONNECTED); - notifyDataConnection(null); - - log("onRadioAvailable: We're on the simulator; assuming data is connected"); - } - - if (mPhone.mIccRecords.getRecordsLoaded()) { - notifyOffApnsOfAvailability(null); - } - - if (getOverallState() != State.IDLE) { - cleanUpConnection(true, null); - } - } - - @Override - protected void onRadioOffOrNotAvailable() { - // Make sure our reconnect delay starts at the initial value - // next time the radio comes on - - for (DataConnection dc : mDataConnections.values()) { - dc.resetRetryCount(); - } - mReregisterOnReconnectFailure = false; - - if (mPhone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - log("We're on the simulator; assuming radio off is meaningless"); - } else { - if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections"); - cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF); - } - notifyOffApnsOfAvailability(null); - } - - @Override - protected void onDataSetupComplete(AsyncResult ar) { - - DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN; - boolean handleError = false; - ApnContext apnContext = null; - - if(ar.userObj instanceof ApnContext){ - apnContext = (ApnContext)ar.userObj; - } else { - throw new RuntimeException("onDataSetupComplete: No apnContext"); - } - - if (isDataSetupCompleteOk(ar)) { - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - - if (RADIO_TESTS) { - // Note: To change radio.test.onDSC.null.dcac from command line you need to - // adb root and adb remount and from the command line you can only change the - // value to 1 once. To change it a second time you can reboot or execute - // adb shell stop and then adb shell start. The command line to set the value is: - // adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');" - ContentResolver cr = mPhone.getContext().getContentResolver(); - String radioTestProperty = "radio.test.onDSC.null.dcac"; - if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) { - log("onDataSetupComplete: " + radioTestProperty + - " is true, set dcac to null and reset property to false"); - dcac = null; - Settings.System.putInt(cr, radioTestProperty, 0); - log("onDataSetupComplete: " + radioTestProperty + "=" + - Settings.System.getInt(mPhone.getContext().getContentResolver(), - radioTestProperty, -1)); - } - } - if (dcac == null) { - log("onDataSetupComplete: no connection to DC, handle as error"); - cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN; - handleError = true; - } else { - DataConnection dc = apnContext.getDataConnection(); - ApnSetting apn = apnContext.getApnSetting(); - if (DBG) { - log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn)); - } - if (apn != null && apn.proxy != null && apn.proxy.length() != 0) { - try { - String port = apn.port; - if (TextUtils.isEmpty(port)) port = "8080"; - ProxyProperties proxy = new ProxyProperties(apn.proxy, - Integer.parseInt(port), null); - dcac.setLinkPropertiesHttpProxySync(proxy); - } catch (NumberFormatException e) { - loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" + - apn.port + "): " + e); - } - } - - // everything is setup - if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) { - SystemProperties.set("gsm.defaultpdpcontext.active", "true"); - if (canSetPreferApn && mPreferredApn == null) { - if (DBG) log("onDataSetupComplete: PREFERED APN is null"); - mPreferredApn = apn; - if (mPreferredApn != null) { - setPreferredApn(mPreferredApn.id); - } - } - } else { - SystemProperties.set("gsm.defaultpdpcontext.active", "false"); - } - notifyDefaultData(apnContext); - } - } else { - cause = (DataConnection.FailCause) (ar.result); - if (DBG) { - ApnSetting apn = apnContext.getApnSetting(); - log(String.format("onDataSetupComplete: error apn=%s cause=%s", - (apn == null ? "unknown" : apn.apn), cause)); - } - if (cause.isEventLoggable()) { - // Log this failure to the Event Logs. - int cid = getCellLocationId(); - EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL, - cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType()); - } - - // Count permanent failures and remove the APN we just tried - if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount(); - - apnContext.removeWaitingApn(apnContext.getApnSetting()); - if (DBG) { - log(String.format("onDataSetupComplete: WaitingApns.size=%d" + - " WaitingApnsPermFailureCountDown=%d", - apnContext.getWaitingApns().size(), - apnContext.getWaitingApnsPermFailCount())); - } - handleError = true; - } - - if (handleError) { - // See if there are more APN's to try - if (apnContext.getWaitingApns().isEmpty()) { - if (apnContext.getWaitingApnsPermFailCount() == 0) { - if (DBG) { - log("onDataSetupComplete: All APN's had permanent failures, stop retrying"); - } - apnContext.setState(State.FAILED); - mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType()); - - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); - } else { - if (DBG) log("onDataSetupComplete: Not all permanent failures, retry"); - // check to see if retry should be overridden for this failure. - int retryOverride = -1; - if (ar.exception instanceof DataConnection.CallSetupException) { - retryOverride = - ((DataConnection.CallSetupException)ar.exception).getRetryOverride(); - } - if (retryOverride == RILConstants.MAX_INT) { - if (DBG) log("No retry is suggested."); - } else { - startDelayedRetry(cause, apnContext, retryOverride); - } - } - } else { - if (DBG) log("onDataSetupComplete: Try next APN"); - apnContext.setState(State.SCANNING); - // Wait a bit before trying the next APN, so that - // we're not tying up the RIL command channel - startAlarmForReconnect(APN_DELAY_MILLIS, apnContext); - } - } - } - - /** - * Called when EVENT_DISCONNECT_DONE is received. - */ - @Override - protected void onDisconnectDone(int connId, AsyncResult ar) { - ApnContext apnContext = null; - - if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE connId=" + connId); - if (ar.userObj instanceof ApnContext) { - apnContext = (ApnContext) ar.userObj; - } else { - loge("Invalid ar in onDisconnectDone"); - return; - } - - apnContext.setState(State.IDLE); - - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); - - // if all data connection are gone, check whether Airplane mode request was - // pending. - if (isDisconnected()) { - if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) { - // Radio will be turned off. No need to retry data setup - apnContext.setApnSetting(null); - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); - return; - } - } - - // If APN is still enabled, try to bring it back up automatically - if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) { - SystemProperties.set("gsm.defaultpdpcontext.active", "false"); // TODO - what the heck? This shoudld go - // Wait a bit before trying the next APN, so that - // we're not tying up the RIL command channel. - // This also helps in any external dependency to turn off the context. - startAlarmForReconnect(APN_DELAY_MILLIS, apnContext); - } else { - apnContext.setApnSetting(null); - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); - } - } - - protected void onPollPdp() { - if (getOverallState() == State.CONNECTED) { - // only poll when connected - mPhone.mCM.getDataCallList(this.obtainMessage(EVENT_DATA_STATE_CHANGED)); - sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS); - } - } - - @Override - protected void onVoiceCallStarted() { - if (DBG) log("onVoiceCallStarted"); - if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { - if (DBG) log("onVoiceCallStarted stop polling"); - stopNetStatPoll(); - stopDataStallAlarm(); - notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); - } - } - - @Override - protected void onVoiceCallEnded() { - if (DBG) log("onVoiceCallEnded"); - if (isConnected()) { - if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { - startNetStatPoll(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); - } else { - // clean slate after call end. - resetPollStats(); - } - } - // reset reconnect timer - setupDataOnReadyApns(Phone.REASON_VOICE_CALL_ENDED); - } - - @Override - protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) { - if (DBG) log("onCleanUpConnection"); - ApnContext apnContext = mApnContexts.get(apnIdToType(apnId)); - if (apnContext != null) { - apnContext.setReason(reason); - cleanUpConnection(tearDown, apnContext); - } - } - - protected boolean isConnected() { - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getState() == State.CONNECTED) { - // At least one context is connected, return true - return true; - } - } - // There are not any contexts connected, return false - return false; - } - - @Override - public boolean isDisconnected() { - for (ApnContext apnContext : mApnContexts.values()) { - if (!apnContext.isDisconnected()) { - // At least one context was not disconnected return false - return false; - } - } - // All contexts were disconnected so return true - return true; - } - - @Override - protected void notifyDataConnection(String reason) { - if (DBG) log("notifyDataConnection: reason=" + reason); - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.isReady()) { - if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType()); - mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(), - apnContext.getApnType()); - } - } - notifyOffApnsOfAvailability(reason); - } - - /** - * Based on the sim operator numeric, create a list for all possible - * Data Connections and setup the preferredApn. - */ - private void createAllApnList() { - mAllApns = new ArrayList(); - String operator = mPhone.mIccRecords.getOperatorNumeric(); - if (operator != null) { - String selection = "numeric = '" + operator + "'"; - // query only enabled apn. - // carrier_enabled : 1 means enabled apn, 0 disabled apn. - selection += " and carrier_enabled = 1"; - if (DBG) log("createAllApnList: selection=" + selection); - - Cursor cursor = mPhone.getContext().getContentResolver().query( - Telephony.Carriers.CONTENT_URI, null, selection, null, null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - mAllApns = createApnList(cursor); - } - cursor.close(); - } - } - - if (mAllApns.isEmpty()) { - if (DBG) log("createAllApnList: No APN found for carrier: " + operator); - mPreferredApn = null; - // TODO: What is the right behaviour? - //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN); - } else { - mPreferredApn = getPreferredApn(); - if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) { - mPreferredApn = null; - setPreferredApn(-1); - } - if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn); - } - if (DBG) log("createAllApnList: X mAllApns=" + mAllApns); - } - - /** Return the id for a new data connection */ - private GsmDataConnection createDataConnection() { - if (DBG) log("createDataConnection E"); - - RetryManager rm = new RetryManager(); - int id = mUniqueIdGenerator.getAndIncrement(); - GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this); - mDataConnections.put(id, conn); - DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG); - int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler()); - if (status == AsyncChannel.STATUS_SUCCESSFUL) { - mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac); - } else { - loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection + - " status=" + status); - } - - // install reconnect intent filter for this data connection. - IntentFilter filter = new IntentFilter(); - filter.addAction(INTENT_RECONNECT_ALARM + '.' + id); - mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); - - if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn); - return conn; - } - - private void configureRetry(DataConnection dc, boolean forDefault) { - if (dc == null) return; - - if (!dc.configureRetry(getReryConfig(forDefault))) { - if (forDefault) { - if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) { - // Should never happen, log an error and default to a simple linear sequence. - loge("configureRetry: Could not configure using " + - "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG); - dc.configureRetry(20, 2000, 1000); - } - } else { - if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) { - // Should never happen, log an error and default to a simple sequence. - loge("configureRetry: Could note configure using " + - "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG); - dc.configureRetry("max_retries=3, 333, 333, 333"); - } - } - } - } - - private void destroyDataConnections() { - if(mDataConnections != null) { - if (DBG) log("destroyDataConnections: clear mDataConnectionList"); - mDataConnections.clear(); - } else { - if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore"); - } - } - - /** - * Build a list of APNs to be used to create PDP's. - * - * @param requestedApnType - * @return waitingApns list to be used to create PDP - * error when waitingApns.isEmpty() - */ - private ArrayList buildWaitingApns(String requestedApnType) { - ArrayList apnList = new ArrayList(); - - if (requestedApnType.equals(Phone.APN_TYPE_DUN)) { - ApnSetting dun = fetchDunApn(); - if (dun != null) { - apnList.add(dun); - if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList); - return apnList; - } - } - - String operator = mPhone.mIccRecords.getOperatorNumeric(); - int networkType = mPhone.getServiceState().getNetworkType(); - - if (canSetPreferApn && mPreferredApn != null && - mPreferredApn.canHandleType(requestedApnType)) { - if (DBG) { - log("buildWaitingApns: Preferred APN:" + operator + ":" - + mPreferredApn.numeric + ":" + mPreferredApn); - } - if (mPreferredApn.numeric.equals(operator)) { - if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) { - apnList.add(mPreferredApn); - if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList); - return apnList; - } else { - if (DBG) log("buildWaitingApns: no preferred APN"); - setPreferredApn(-1); - mPreferredApn = null; - } - } else { - if (DBG) log("buildWaitingApns: no preferred APN"); - setPreferredApn(-1); - mPreferredApn = null; - } - } - if (mAllApns != null) { - for (ApnSetting apn : mAllApns) { - if (apn.canHandleType(requestedApnType)) { - if (apn.bearer == 0 || apn.bearer == networkType) { - if (DBG) log("apn info : " +apn.toString()); - apnList.add(apn); - } - } - } - } else { - loge("mAllApns is empty!"); - } - if (DBG) log("buildWaitingApns: X apnList=" + apnList); - return apnList; - } - - private String apnListToString (ArrayList apns) { - StringBuilder result = new StringBuilder(); - for (int i = 0, size = apns.size(); i < size; i++) { - result.append('[') - .append(apns.get(i).toString()) - .append(']'); - } - return result.toString(); - } - - private void startDelayedRetry(GsmDataConnection.FailCause cause, - ApnContext apnContext, int retryOverride) { - notifyNoData(cause, apnContext); - reconnectAfterFail(cause, apnContext, retryOverride); - } - - private void setPreferredApn(int pos) { - if (!canSetPreferApn) { - log("setPreferredApn: X !canSEtPreferApn"); - return; - } - - log("setPreferredApn: delete"); - ContentResolver resolver = mPhone.getContext().getContentResolver(); - resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null); - - if (pos >= 0) { - log("setPreferredApn: insert"); - ContentValues values = new ContentValues(); - values.put(APN_ID, pos); - resolver.insert(PREFERAPN_NO_UPDATE_URI, values); - } - } - - private ApnSetting getPreferredApn() { - if (mAllApns.isEmpty()) { - log("getPreferredApn: X not found mAllApns.isEmpty"); - return null; - } - - Cursor cursor = mPhone.getContext().getContentResolver().query( - PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" }, - null, null, Telephony.Carriers.DEFAULT_SORT_ORDER); - - if (cursor != null) { - canSetPreferApn = true; - } else { - canSetPreferApn = false; - } - - if (canSetPreferApn && cursor.getCount() > 0) { - int pos; - cursor.moveToFirst(); - pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)); - for(ApnSetting p:mAllApns) { - if (p.id == pos && p.canHandleType(mRequestedApnType)) { - log("getPreferredApn: X found apnSetting" + p); - cursor.close(); - return p; - } - } - } - - if (cursor != null) { - cursor.close(); - } - - log("getPreferredApn: X not found"); - return null; - } - - @Override - public void handleMessage (Message msg) { - if (DBG) log("handleMessage msg=" + msg); - - if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) { - loge("handleMessage: Ignore GSM msgs since GSM phone is inactive"); - return; - } - - switch (msg.what) { - case EVENT_RECORDS_LOADED: - onRecordsLoaded(); - break; - - case EVENT_DATA_CONNECTION_DETACHED: - onDataConnectionDetached(); - break; - - case EVENT_DATA_CONNECTION_ATTACHED: - onDataConnectionAttached(); - break; - - case EVENT_DATA_STATE_CHANGED: - onDataStateChanged((AsyncResult) msg.obj); - break; - - case EVENT_POLL_PDP: - onPollPdp(); - break; - - case EVENT_DO_RECOVERY: - doRecovery(); - break; - - case EVENT_APN_CHANGED: - onApnChanged(); - break; - - case EVENT_PS_RESTRICT_ENABLED: - /** - * We don't need to explicitly to tear down the PDP context - * when PS restricted is enabled. The base band will deactive - * PDP context and notify us with PDP_CONTEXT_CHANGED. - * But we should stop the network polling and prevent reset PDP. - */ - if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted); - stopNetStatPoll(); - stopDataStallAlarm(); - mIsPsRestricted = true; - break; - - case EVENT_PS_RESTRICT_DISABLED: - /** - * When PS restrict is removed, we need setup PDP connection if - * PDP connection is down. - */ - if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted); - mIsPsRestricted = false; - if (isConnected()) { - startNetStatPoll(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - } else { - // TODO: Should all PDN states be checked to fail? - if (mState == State.FAILED) { - cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED); - resetAllRetryCounts(); - mReregisterOnReconnectFailure = false; - } - trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, Phone.APN_TYPE_DEFAULT); - } - break; - case EVENT_TRY_SETUP_DATA: - if (msg.obj instanceof ApnContext) { - onTrySetupData((ApnContext)msg.obj); - } else if (msg.obj instanceof String) { - onTrySetupData((String)msg.obj); - } else { - loge("EVENT_TRY_SETUP request w/o apnContext or String"); - } - break; - - case EVENT_CLEAN_UP_CONNECTION: - boolean tearDown = (msg.arg1 == 0) ? false : true; - if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown); - if (msg.obj instanceof ApnContext) { - cleanUpConnection(tearDown, (ApnContext)msg.obj); - } else { - loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context"); - } - break; - default: - // handle the message in the super class DataConnectionTracker - super.handleMessage(msg); - break; - } - } - - protected int getApnProfileID(String apnType) { - if (TextUtils.equals(apnType, Phone.APN_TYPE_IMS)) { - return RILConstants.DATA_PROFILE_IMS; - } else if (TextUtils.equals(apnType, Phone.APN_TYPE_FOTA)) { - return RILConstants.DATA_PROFILE_FOTA; - } else if (TextUtils.equals(apnType, Phone.APN_TYPE_CBS)) { - return RILConstants.DATA_PROFILE_CBS; - } else { - return RILConstants.DATA_PROFILE_DEFAULT; - } - } - - private int getCellLocationId() { - int cid = -1; - CellLocation loc = mPhone.getCellLocation(); - - if (loc != null) { - if (loc instanceof GsmCellLocation) { - cid = ((GsmCellLocation)loc).getCid(); - } else if (loc instanceof CdmaCellLocation) { - cid = ((CdmaCellLocation)loc).getBaseStationId(); - } - } - return cid; - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[GsmDCT] "+ s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[GsmDCT] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("GsmDataConnectionTracker extends:"); - super.dump(fd, pw, args); - pw.println(" RADIO_TESTS=" + RADIO_TESTS); - pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure); - pw.println(" mResolver=" + mResolver); - pw.println(" canSetPreferApn=" + canSetPreferApn); - pw.println(" mApnObserver=" + mApnObserver); - pw.println(" getOverallState=" + getOverallState()); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java deleted file mode 100644 index 9b3d5cdacfbf..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.content.Context; -import com.android.internal.telephony.*; - -import android.os.*; -import android.telephony.PhoneNumberUtils; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; -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: - * - * "NOTE: By using the # as a separator, most cases are expected to be unambiguous." - * -- TS 22.030 6.5.2 - * - * {@hide} - * - */ -public final class GsmMmiCode extends Handler implements MmiCode { - static final String LOG_TAG = "GSM"; - - //***** Constants - - // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2) - static final int MAX_LENGTH_SHORT_CODE = 2; - - // TS 22.030 6.5.2 Every Short String USSD command will end with #-key - // (known as #-String) - static final char END_OF_USSD_COMMAND = '#'; - - // 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 codes from TS 22.030 Annex B - - //Called line presentation - static final String SC_CLIP = "30"; - static final String SC_CLIR = "31"; - - // Call Forwarding - static final String SC_CFU = "21"; - static final String SC_CFB = "67"; - static final String SC_CFNRy = "61"; - static final String SC_CFNR = "62"; - - static final String SC_CF_All = "002"; - static final String SC_CF_All_Conditional = "004"; - - // Call Waiting - static final String SC_WAIT = "43"; - - // Call Barring - static final String SC_BAOC = "33"; - static final String SC_BAOIC = "331"; - static final String SC_BAOICxH = "332"; - static final String SC_BAIC = "35"; - static final String SC_BAICr = "351"; - - static final String SC_BA_ALL = "330"; - static final String SC_BA_MO = "333"; - static final String SC_BA_MT = "353"; - - // Supp Service Password registration - static final String SC_PWD = "03"; - - // PIN/PIN2/PUK/PUK2 - static final String SC_PIN = "04"; - static final String SC_PIN2 = "042"; - static final String SC_PUK = "05"; - static final String SC_PUK2 = "052"; - - //***** Event Constants - - static final int EVENT_SET_COMPLETE = 1; - static final int EVENT_GET_CLIR_COMPLETE = 2; - static final int EVENT_QUERY_CF_COMPLETE = 3; - static final int EVENT_USSD_COMPLETE = 4; - static final int EVENT_QUERY_COMPLETE = 5; - static final int EVENT_SET_CFF_COMPLETE = 6; - static final int EVENT_USSD_CANCEL_COMPLETE = 7; - - //***** Instance Variables - - 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 */ - private boolean isPendingUSSD; - - private boolean isUssdRequest; - - State state = State.PENDING; - CharSequence message; - - //***** Class Variables - - - // See TS 22.030 6.5.2 "Structure of the MMI" - - static Pattern sPatternSuppService = Pattern.compile( - "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)"); -/* 1 2 3 4 5 6 7 8 9 10 11 12 - - 1 = Full string up to and including # - 2 = action (activation/interrogation/registration/erasure) - 3 = service code - 5 = SIA - 7 = SIB - 9 = SIC - 10 = dialing number which must not include #, e.g. *SCn*SI#DN format -*/ - - static final int MATCH_GROUP_POUND_STRING = 1; - - static final int MATCH_GROUP_ACTION = 2; - //(activation/interrogation/registration/erasure) - - static final int MATCH_GROUP_SERVICE_CODE = 3; - static final int MATCH_GROUP_SIA = 5; - static final int MATCH_GROUP_SIB = 7; - static final int MATCH_GROUP_SIC = 9; - static final int MATCH_GROUP_PWD_CONFIRM = 11; - static final int MATCH_GROUP_DIALING_NUMBER = 12; - static private String[] sTwoDigitNumberPattern; - - //***** Public Class methods - - /** - * Some dial strings in GSM are defined to do non-call setup - * things, such as modify or query supplementary service settings (eg, call - * forwarding). These are generally referred to as "MMI codes". - * We look to see if the dial string contains a valid MMI code (potentially - * with a dial string at the end as well) and return info here. - * - * If the dial string contains no MMI code, we return an instance with - * only "dialingNumber" set - * - * Please see flow chart in TS 22.030 6.5.3.2 - */ - - static GsmMmiCode - newFromDialString(String dialString, GSMPhone phone) { - Matcher m; - GsmMmiCode ret = null; - - m = sPatternSuppService.matcher(dialString); - - // Is this formatted like a standard supplementary service code? - if (m.matches()) { - ret = new GsmMmiCode(phone); - ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); - ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); - ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); - ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); - ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); - ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); - ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); - ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); - - } 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 - // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND". - - ret = new GsmMmiCode(phone); - ret.poundString = dialString; - } else if (isTwoDigitShortCode(phone.getContext(), dialString)) { - //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2 - ret = null; - } else if (isShortCode(dialString, phone)) { - // this may be a short code, as defined in TS 22.030, 6.5.3.2 - ret = new GsmMmiCode(phone); - ret.dialingNumber = dialString; - } - - return ret; - } - - static GsmMmiCode - newNetworkInitiatedUssd (String ussdMessage, - boolean isUssdRequest, GSMPhone phone) { - GsmMmiCode ret; - - ret = new GsmMmiCode(phone); - - ret.message = ussdMessage; - ret.isUssdRequest = isUssdRequest; - - // If it's a request, set to PENDING so that it's cancelable. - if (isUssdRequest) { - ret.isPendingUSSD = true; - ret.state = State.PENDING; - } else { - ret.state = State.COMPLETE; - } - - return ret; - } - - 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 - */ - 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); - } - - - private static int - scToCallForwardReason(String sc) { - 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)) { - return CommandsInterface.CF_REASON_UNCONDITIONAL; - } else if (sc.equals(SC_CFB)) { - return CommandsInterface.CF_REASON_BUSY; - } else if (sc.equals(SC_CFNR)) { - return CommandsInterface.CF_REASON_NOT_REACHABLE; - } else if (sc.equals(SC_CFNRy)) { - return CommandsInterface.CF_REASON_NO_REPLY; - } else if (sc.equals(SC_CF_All_Conditional)) { - return CommandsInterface.CF_REASON_ALL_CONDITIONAL; - } else { - throw new RuntimeException ("invalid call forward sc"); - } - } - - private static int - siToServiceClass(String si) { - if (si == null || si.length() == 0) { - return SERVICE_CLASS_NONE; - } else { - // NumberFormatException should cause MMI fail - int serviceCode = Integer.parseInt(si, 10); - - switch (serviceCode) { - case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; - case 11: return SERVICE_CLASS_VOICE; - case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX; - case 13: return SERVICE_CLASS_FAX; - - case 16: return SERVICE_CLASS_SMS; - - case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; -/* - Note for code 20: - From TS 22.030 Annex C: - "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 -*/ - case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC; - - case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC; - case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC; - case 24: return SERVICE_CLASS_DATA_SYNC; - case 25: return SERVICE_CLASS_DATA_ASYNC; - case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE; - case 99: return SERVICE_CLASS_PACKET; - - default: - throw new RuntimeException("unsupported MMI service code " + si); - } - } - } - - private static int - siToTime (String si) { - if (si == null || si.length() == 0) { - return 0; - } else { - // NumberFormatException should cause MMI fail - return Integer.parseInt(si, 10); - } - } - - 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) - || sc.equals(SC_CF_All_Conditional)); - } - - static boolean - isServiceCodeCallBarring(String sc) { - return sc != null && - (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)); - } - - static String - scToBarringFacility(String sc) { - if (sc == null) { - throw new RuntimeException ("invalid call barring sc"); - } - - if (sc.equals(SC_BAOC)) { - return CommandsInterface.CB_FACILITY_BAOC; - } else if (sc.equals(SC_BAOIC)) { - return CommandsInterface.CB_FACILITY_BAOIC; - } else if (sc.equals(SC_BAOICxH)) { - return CommandsInterface.CB_FACILITY_BAOICxH; - } else if (sc.equals(SC_BAIC)) { - return CommandsInterface.CB_FACILITY_BAIC; - } else if (sc.equals(SC_BAICr)) { - return CommandsInterface.CB_FACILITY_BAICr; - } else if (sc.equals(SC_BA_ALL)) { - return CommandsInterface.CB_FACILITY_BA_ALL; - } else if (sc.equals(SC_BA_MO)) { - return CommandsInterface.CB_FACILITY_BA_MO; - } else if (sc.equals(SC_BA_MT)) { - return CommandsInterface.CB_FACILITY_BA_MT; - } else { - throw new RuntimeException ("invalid call barring sc"); - } - } - - //***** Constructor - - GsmMmiCode (GSMPhone phone) { - // The telephony unit-test cases may create GsmMmiCode's - // in secondary threads - 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() { - // Complete or failed cannot be cancelled - if (state == State.COMPLETE || state == State.FAILED) { - return; - } - - state = State.CANCELLED; - - if (isPendingUSSD) { - /* - * There can only be one pending USSD session, so tell the radio to - * cancel it. - */ - phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this)); - - /* - * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice - * from RIL. - */ - } else { - // TODO in cases other than USSD, it would be nice to cancel - // the pending radio operation. This requires RIL cancellation - // support, which does not presently exist. - - phone.onMMIDone (this); - } - - } - - public boolean isCancelable() { - /* Can only cancel pending USSD sessions. */ - return isPendingUSSD; - } - - //***** Instance Methods - - /** Does this dial string contain a structured or unstructured MMI code? */ - boolean - isMMI() { - return poundString != null; - } - - /* 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 - && dialingNumber != null && dialingNumber.length() <= 2; - - } - - static private boolean - isTwoDigitShortCode(Context context, String dialString) { - Log.d(LOG_TAG, "isTwoDigitShortCode"); - - if (dialString == null || dialString.length() != 2) return false; - - if (sTwoDigitNumberPattern == null) { - sTwoDigitNumberPattern = context.getResources().getStringArray( - com.android.internal.R.array.config_twoDigitNumberPattern); - } - - for (String dialnumber : sTwoDigitNumberPattern) { - Log.d(LOG_TAG, "Two Digit Number Pattern " + dialnumber); - if (dialString.equals(dialnumber)) { - Log.d(LOG_TAG, "Two Digit Number Pattern -true"); - return true; - } - } - Log.d(LOG_TAG, "Two Digit Number Pattern -false"); - return false; - } - - /** - * Helper function for newFromDialString. Returns true if dialString appears - * to be a short code AND conditions are correct for it to be treated as - * such. - */ - static private boolean isShortCode(String dialString, GSMPhone phone) { - // Refer to TS 22.030 Figure 3.5.3.2: - if (dialString == null) { - return false; - } - - // Illegal dial string characters will give a ZERO length. - // At this point we do not want to crash as any application with - // call privileges may send a non dial string. - // It return false as when the dialString is equal to NULL. - if (dialString.length() == 0) { - return false; - } - - if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) { - return false; - } else { - return isShortCodeUSSD(dialString, phone); - } - } - - /** - * Helper function for isShortCode. Returns true if dialString appears to be - * a short code and it is a USSD structure - * - * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2 - * digit "short code" is treated as USSD if it is entered while on a call or - * does not satisfy the condition (exactly 2 digits && starts with '1'), there - * are however exceptions to this rule (see below) - * - * Exception (1) to Call initiation is: If the user of the device is already in a call - * and enters a Short String without any #-key at the end and the length of the Short String is - * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2] - * - * The phone shall initiate a USSD/SS commands. - * - * Exception (2) to Call initiation is: If the user of the device enters one - * Digit followed by the #-key. This rule defines this String as the - * #-String which is a USSD/SS command. - * - * The phone shall initiate a USSD/SS command. - */ - static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) { - if (dialString != null) { - if (phone.isInCall()) { - // The maximum length of a Short Code (aka Short String) is 2 - if (dialString.length() <= MAX_LENGTH_SHORT_CODE) { - return true; - } - } - - // The maximum length of a Short Code (aka Short String) is 2 - if (dialString.length() <= MAX_LENGTH_SHORT_CODE) { - if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) { - return true; - } - } - } - return false; - } - - /** - * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related - */ - boolean isPinCommand() { - return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2) - || 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: - * " * 31 # [called number] SEND " - * In temporary mode, to invoke CLIR for a single call enter: - * " # 31 # [called number] SEND " - */ - boolean - isTemporaryModeCLIR() { - return sc != null && sc.equals(SC_CLIR) && dialingNumber != null - && (isActivate() || isDeactivate()); - } - - /** - * returns CommandsInterface.CLIR_* - * See also isTemporaryModeCLIR() - */ - int - getCLIRMode() { - if (sc != null && sc.equals(SC_CLIR)) { - if (isActivate()) { - return CommandsInterface.CLIR_SUPPRESSION; - } else if (isDeactivate()) { - return CommandsInterface.CLIR_INVOCATION; - } - } - - return CommandsInterface.CLIR_DEFAULT; - } - - boolean isActivate() { - return action != null && action.equals(ACTION_ACTIVATE); - } - - boolean isDeactivate() { - return action != null && action.equals(ACTION_DEACTIVATE); - } - - boolean isInterrogate() { - return action != null && action.equals(ACTION_INTERROGATE); - } - - boolean isRegister() { - return action != null && action.equals(ACTION_REGISTER); - } - - boolean isErasure() { - 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 - */ - public boolean isPendingUSSD() { - return isPendingUSSD; - } - - public boolean isUssdRequest() { - return isUssdRequest; - } - - /** Process a MMI code or short code...anything that isn't a dialing number */ - void - processCode () { - try { - if (isShortCode()) { - Log.d(LOG_TAG, "isShortCode"); - // These just get treated as USSD. - sendUssd(dialingNumber); - } else if (dialingNumber != null) { - // 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"); - if (isInterrogate()) { - phone.mCM.queryCLIP( - obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (sc != null && sc.equals(SC_CLIR)) { - Log.d(LOG_TAG, "is CLIR"); - if (isActivate()) { - phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isDeactivate()) { - phone.mCM.setCLIR(CommandsInterface.CLIR_SUPPRESSION, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isInterrogate()) { - phone.mCM.getCLIR( - obtainMessage(EVENT_GET_CLIR_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (isServiceCodeCallForwarding(sc)) { - Log.d(LOG_TAG, "is CF"); - - String dialingNumber = sia; - int serviceClass = siToServiceClass(sib); - int reason = scToCallForwardReason(sc); - int time = siToTime(sic); - - if (isInterrogate()) { - phone.mCM.queryCallForwardStatus( - reason, serviceClass, dialingNumber, - obtainMessage(EVENT_QUERY_CF_COMPLETE, this)); - } else { - int cfAction; - - if (isActivate()) { - cfAction = CommandsInterface.CF_ACTION_ENABLE; - } else if (isDeactivate()) { - cfAction = CommandsInterface.CF_ACTION_DISABLE; - } else if (isRegister()) { - cfAction = CommandsInterface.CF_ACTION_REGISTRATION; - } else if (isErasure()) { - cfAction = CommandsInterface.CF_ACTION_ERASURE; - } else { - throw new RuntimeException ("invalid action"); - } - - int isSettingUnconditionalVoice = - (((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) || - (reason == CommandsInterface.CF_REASON_ALL)) && - (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) || - (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0; - - int isEnableDesired = - ((cfAction == CommandsInterface.CF_ACTION_ENABLE) || - (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0; - - Log.d(LOG_TAG, "is CF setCallForward"); - phone.mCM.setCallForward(cfAction, reason, serviceClass, - dialingNumber, time, obtainMessage( - EVENT_SET_CFF_COMPLETE, - isSettingUnconditionalVoice, - isEnableDesired, this)); - } - } else if (isServiceCodeCallBarring(sc)) { - // sia = password - // sib = basic service group - - String password = sia; - int serviceClass = siToServiceClass(sib); - String facility = scToBarringFacility(sc); - - if (isInterrogate()) { - phone.mCM.queryFacilityLock(facility, password, - serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else if (isActivate() || isDeactivate()) { - phone.mCM.setFacilityLock(facility, isActivate(), password, - serviceClass, obtainMessage(EVENT_SET_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - - } else if (sc != null && sc.equals(SC_PWD)) { - // sia = fac - // sib = old pwd - // sic = new pwd - // pwd = new pwd - String facility; - String oldPwd = sib; - String newPwd = sic; - if (isActivate() || isRegister()) { - // Even though ACTIVATE is acceptable, this is really termed a REGISTER - action = ACTION_REGISTER; - - if (sia == null) { - // If sc was not specified, treat it as BA_ALL. - facility = CommandsInterface.CB_FACILITY_BA_ALL; - } else { - facility = scToBarringFacility(sia); - } - if (newPwd.equals(pwd)) { - phone.mCM.changeBarringPassword(facility, oldPwd, - newPwd, obtainMessage(EVENT_SET_COMPLETE, this)); - } else { - // password mismatch; return error - handlePasswordError(com.android.internal.R.string.passwordIncorrect); - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - - } else if (sc != null && sc.equals(SC_WAIT)) { - // sia = basic service group - int serviceClass = siToServiceClass(sia); - - if (isActivate() || isDeactivate()) { - phone.mCM.setCallWaiting(isActivate(), serviceClass, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isInterrogate()) { - phone.mCM.queryCallWaiting(serviceClass, - obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (isPinCommand()) { - // sia = old PIN or PUK - // sib = new PIN - // sic = new PIN - String oldPinOrPuk = sia; - String newPin = sib; - int pinLen = newPin.length(); - if (isRegister()) { - if (!newPin.equals(sic)) { - // password mismatch; return error - handlePasswordError(com.android.internal.R.string.mismatchPin); - } else if (pinLen < 4 || pinLen > 8 ) { - // invalid length - handlePasswordError(com.android.internal.R.string.invalidPin); - } else if (sc.equals(SC_PIN) && - phone.getIccCard().getState() == IccCard.State.PUK_REQUIRED ) { - // Sim is puk-locked - handlePasswordError(com.android.internal.R.string.needPuk); - } else { - // pre-checks OK - if (sc.equals(SC_PIN)) { - phone.mCM.changeIccPin(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PIN2)) { - phone.mCM.changeIccPin2(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PUK)) { - phone.mCM.supplyIccPuk(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PUK2)) { - phone.mCM.supplyIccPuk2(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (poundString != null) { - sendUssd(poundString); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } catch (RuntimeException exc) { - state = State.FAILED; - message = context.getText(com.android.internal.R.string.mmiError); - phone.onMMIDone(this); - } - } - - private void handlePasswordError(int res) { - state = State.FAILED; - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - sb.append(context.getText(res)); - message = sb; - phone.onMMIDone(this); - } - - /** - * Called from GSMPhone - * - * An unsolicited USSD NOTIFY or REQUEST has come in matching - * up with this pending USSD request - * - * Note: If REQUEST, this exchange is complete, but the session remains - * active (ie, the network expects user input). - */ - void - onUssdFinished(String ussdMessage, boolean isUssdRequest) { - if (state == State.PENDING) { - if (ussdMessage == null) { - message = context.getText(com.android.internal.R.string.mmiComplete); - } else { - message = ussdMessage; - } - this.isUssdRequest = isUssdRequest; - // If it's a request, leave it PENDING so that it's cancelable. - if (!isUssdRequest) { - state = State.COMPLETE; - } - - phone.onMMIDone(this); - } - } - - /** - * Called from GSMPhone - * - * The radio has reset, and this is still pending - */ - - void - onUssdFinishedError() { - if (state == State.PENDING) { - state = State.FAILED; - message = context.getText(com.android.internal.R.string.mmiError); - - phone.onMMIDone(this); - } - } - - void sendUssd(String ussdMessage) { - // Treat this as a USSD string - isPendingUSSD = true; - - // 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. - - phone.mCM.sendUSSD(ussdMessage, - obtainMessage(EVENT_USSD_COMPLETE, this)); - } - - /** Called from GSMPhone.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_SET_CFF_COMPLETE: - ar = (AsyncResult) (msg.obj); - - /* - * msg.arg1 = 1 means to set unconditional voice call forwarding - * msg.arg2 = 1 means to enable voice call forwarding - */ - if ((ar.exception == null) && (msg.arg1 == 1)) { - boolean cffEnabled = (msg.arg2 == 1); - phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled); - } - - onSetComplete(ar); - break; - - case EVENT_GET_CLIR_COMPLETE: - ar = (AsyncResult) (msg.obj); - onGetClirComplete(ar); - break; - - case EVENT_QUERY_CF_COMPLETE: - ar = (AsyncResult) (msg.obj); - onQueryCfComplete(ar); - break; - - case EVENT_QUERY_COMPLETE: - ar = (AsyncResult) (msg.obj); - onQueryComplete(ar); - break; - - case EVENT_USSD_COMPLETE: - ar = (AsyncResult) (msg.obj); - - if (ar.exception != null) { - state = State.FAILED; - message = getErrorMessage(ar); - - 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: - phone.onMMIDone(this); - break; - } - } - //***** Private instance methods - - private CharSequence getErrorMessage(AsyncResult ar) { - - if (ar.exception instanceof CommandException) { - CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); - if (err == CommandException.Error.FDN_CHECK_FAILURE) { - Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); - return context.getText(com.android.internal.R.string.mmiFdnError); - } - } - - return context.getText(com.android.internal.R.string.mmiError); - } - - private CharSequence getScString() { - if (sc != null) { - if (isServiceCodeCallBarring(sc)) { - return context.getText(com.android.internal.R.string.BaMmi); - } else if (isServiceCodeCallForwarding(sc)) { - return context.getText(com.android.internal.R.string.CfMmi); - } else if (sc.equals(SC_CLIP)) { - return context.getText(com.android.internal.R.string.ClipMmi); - } else if (sc.equals(SC_CLIR)) { - return context.getText(com.android.internal.R.string.ClirMmi); - } else if (sc.equals(SC_PWD)) { - return context.getText(com.android.internal.R.string.PwdMmi); - } else if (sc.equals(SC_WAIT)) { - return context.getText(com.android.internal.R.string.CwMmi); - } else if (isPinCommand()) { - return context.getText(com.android.internal.R.string.PinMmi); - } - } - - return ""; - } - - private void - onSetComplete(AsyncResult ar){ - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - if (ar.exception instanceof CommandException) { - CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); - if (err == CommandException.Error.PASSWORD_INCORRECT) { - if (isPinCommand()) { - // look specifically for the PUK commands and adjust - // the message accordingly. - if (sc.equals(SC_PUK) || sc.equals(SC_PUK2)) { - sb.append(context.getText( - com.android.internal.R.string.badPuk)); - } else { - sb.append(context.getText( - com.android.internal.R.string.badPin)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.passwordIncorrect)); - } - } else if (err == CommandException.Error.SIM_PUK2) { - sb.append(context.getText( - com.android.internal.R.string.badPin)); - sb.append("\n"); - sb.append(context.getText( - com.android.internal.R.string.needPuk2)); - } else if (err == CommandException.Error.FDN_CHECK_FAILURE) { - Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); - sb.append(context.getText(com.android.internal.R.string.mmiFdnError)); - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else if (isActivate()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceEnabled)); - // Record CLIR setting - if (sc.equals(SC_CLIR)) { - phone.saveClirSetting(CommandsInterface.CLIR_INVOCATION); - } - } else if (isDeactivate()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceDisabled)); - // Record CLIR setting - if (sc.equals(SC_CLIR)) { - phone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION); - } - } else if (isRegister()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceRegistered)); - } else if (isErasure()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceErased)); - } else { - state = State.FAILED; - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - - message = sb; - phone.onMMIDone(this); - } - - private void - onGetClirComplete(AsyncResult ar) { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(getErrorMessage(ar)); - } else { - int clirArgs[]; - - clirArgs = (int[])ar.result; - - // the 'm' parameter from TS 27.007 7.7 - switch (clirArgs[1]) { - case 0: // CLIR not provisioned - sb.append(context.getText( - 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.) - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - state = State.FAILED; - break; - - 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)); - break; - case 1: // CLIR invocation - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOnNextCallOn)); - break; - case 2: // CLIR suppression - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOnNextCallOff)); - break; - } - state = State.COMPLETE; - break; - - case 4: // CLIR temporary mode presentation allowed - // 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.CLIRDefaultOffNextCallOff)); - break; - case 1: // CLIR invocation - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOffNextCallOn)); - break; - case 2: // CLIR suppression - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOffNextCallOff)); - break; - } - - state = State.COMPLETE; - break; - } - } - - message = sb; - phone.onMMIDone(this); - } - - /** - * @param serviceClass 1 bit of the service class bit vectory - * @return String to be used for call forward query MMI response text. - * Returns null if unrecognized - */ - - private CharSequence - serviceClassToCFString (int serviceClass) { - switch (serviceClass) { - case SERVICE_CLASS_VOICE: - return context.getText(com.android.internal.R.string.serviceClassVoice); - case SERVICE_CLASS_DATA: - return context.getText(com.android.internal.R.string.serviceClassData); - case SERVICE_CLASS_FAX: - return context.getText(com.android.internal.R.string.serviceClassFAX); - case SERVICE_CLASS_SMS: - return context.getText(com.android.internal.R.string.serviceClassSMS); - case SERVICE_CLASS_DATA_SYNC: - return context.getText(com.android.internal.R.string.serviceClassDataSync); - case SERVICE_CLASS_DATA_ASYNC: - return context.getText(com.android.internal.R.string.serviceClassDataAsync); - case SERVICE_CLASS_PACKET: - return context.getText(com.android.internal.R.string.serviceClassPacket); - case SERVICE_CLASS_PAD: - return context.getText(com.android.internal.R.string.serviceClassPAD); - default: - return null; - } - } - - - /** one CallForwardInfo + serviceClassMask -> one line of text */ - private CharSequence - makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) { - CharSequence template; - String sources[] = {"{0}", "{1}", "{2}"}; - CharSequence destinations[] = new CharSequence[3]; - boolean needTimeTemplate; - - // CF_REASON_NO_REPLY also has a time value associated with - // it. All others don't. - - needTimeTemplate = - (info.reason == CommandsInterface.CF_REASON_NO_REPLY); - - if (info.status == 1) { - if (needTimeTemplate) { - template = context.getText( - com.android.internal.R.string.cfTemplateForwardedTime); - } else { - template = context.getText( - com.android.internal.R.string.cfTemplateForwarded); - } - } else if (info.status == 0 && isEmptyOrNull(info.number)) { - template = context.getText( - com.android.internal.R.string.cfTemplateNotForwarded); - } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */ - // A call forward record that is not active but contains - // a phone number is considered "registered" - - if (needTimeTemplate) { - template = context.getText( - com.android.internal.R.string.cfTemplateRegisteredTime); - } else { - template = context.getText( - com.android.internal.R.string.cfTemplateRegistered); - } - } - - // In the template (from strings.xmls) - // {0} is one of "bearerServiceCode*" - // {1} is dialing number - // {2} is time in seconds - - destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask); - destinations[1] = PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa); - destinations[2] = Integer.toString(info.timeSeconds); - - if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL && - (info.serviceClass & serviceClassMask) - == CommandsInterface.SERVICE_CLASS_VOICE) { - boolean cffEnabled = (info.status == 1); - phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled); - } - - return TextUtils.replace(template, sources, destinations); - } - - - private void - onQueryCfComplete(AsyncResult ar) { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(getErrorMessage(ar)); - } else { - CallForwardInfo infos[]; - - infos = (CallForwardInfo[]) ar.result; - - if (infos.length == 0) { - // Assume the default is not active - sb.append(context.getText(com.android.internal.R.string.serviceDisabled)); - - // Set unconditional CFF in SIM to false - phone.mIccRecords.setVoiceCallForwardingFlag(1, false); - } else { - - SpannableStringBuilder tb = new SpannableStringBuilder(); - - // Each bit in the service class gets its own result line - // The service classes may be split up over multiple - // CallForwardInfos. So, for each service class, find out - // which CallForwardInfo represents it and then build - // the response text based on that - - for (int serviceClassMask = 1 - ; serviceClassMask <= SERVICE_CLASS_MAX - ; serviceClassMask <<= 1 - ) { - for (int i = 0, s = infos.length; i < s ; i++) { - if ((serviceClassMask & infos[i].serviceClass) != 0) { - tb.append(makeCFQueryResultMessage(infos[i], - serviceClassMask)); - tb.append("\n"); - } - } - } - sb.append(tb); - } - - state = State.COMPLETE; - } - - message = sb; - phone.onMMIDone(this); - - } - - private void - onQueryComplete(AsyncResult ar) { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(getErrorMessage(ar)); - } else { - int[] ints = (int[])ar.result; - - if (ints.length != 0) { - if (ints[0] == 0) { - sb.append(context.getText(com.android.internal.R.string.serviceDisabled)); - } else if (sc.equals(SC_WAIT)) { - // Call Waiting includes additional data in the response. - sb.append(createQueryCallWaitingResultMessage(ints[1])); - } else if (isServiceCodeCallBarring(sc)) { - // ints[0] for Call Barring is a bit vector of services - sb.append(createQueryCallBarringResultMessage(ints[0])); - } else if (ints[0] == 1) { - // for all other services, treat it as a boolean - sb.append(context.getText(com.android.internal.R.string.serviceEnabled)); - } else { - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } - } else { - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } - state = State.COMPLETE; - } - - message = sb; - phone.onMMIDone(this); - } - - private CharSequence - createQueryCallWaitingResultMessage(int serviceClass) { - StringBuilder sb = - new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor)); - - for (int classMask = 1 - ; classMask <= SERVICE_CLASS_MAX - ; classMask <<= 1 - ) { - if ((classMask & serviceClass) != 0) { - sb.append("\n"); - sb.append(serviceClassToCFString(classMask & serviceClass)); - } - } - return sb; - } - private CharSequence - createQueryCallBarringResultMessage(int serviceClass) - { - StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor)); - - for (int classMask = 1 - ; classMask <= SERVICE_CLASS_MAX - ; classMask <<= 1 - ) { - if ((classMask & serviceClass) != 0) { - sb.append("\n"); - sb.append(serviceClassToCFString(classMask & serviceClass)); - } - } - 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. - */ - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("GsmMmiCode {"); - - sb.append("State=" + getState()); - if (action != null) sb.append(" action=" + action); - if (sc != null) sb.append(" sc=" + sc); - if (sia != null) sb.append(" sia=" + sia); - if (sib != null) sb.append(" sib=" + sib); - if (sic != null) sb.append(" sic=" + sic); - if (poundString != null) sb.append(" poundString=" + poundString); - if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber); - if (pwd != null) sb.append(" pwd=" + pwd); - sb.append("}"); - return sb.toString(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java deleted file mode 100644 index bfa2bb1d4b40..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.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.os.SystemProperties; -import android.provider.Telephony.Sms; -import android.provider.Telephony.Sms.Intents; -import android.telephony.PhoneNumberUtils; -import android.telephony.SmsCbLocation; -import android.telephony.SmsCbMessage; -import android.telephony.SmsManager; -import android.telephony.gsm.GsmCellLocation; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.SMSDispatcher; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; -import com.android.internal.telephony.SmsStorageMonitor; -import com.android.internal.telephony.SmsUsageMonitor; -import com.android.internal.telephony.TelephonyProperties; - -import java.util.HashMap; -import java.util.Iterator; - -import static android.telephony.SmsMessage.MessageClass; - -public final class GsmSMSDispatcher extends SMSDispatcher { - private static final String TAG = "GSM"; - - /** Status report received */ - private static final int EVENT_NEW_SMS_STATUS_REPORT = 100; - - /** New broadcast SMS */ - private static final int EVENT_NEW_BROADCAST_SMS = 101; - - /** Result of writing SM to UICC (when SMS-PP service is not available). */ - private static final int EVENT_WRITE_SMS_COMPLETE = 102; - - /** Handler for SMS-PP data download messages to UICC. */ - private final UsimDataDownloadHandler mDataDownloadHandler; - - public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor, - SmsUsageMonitor usageMonitor) { - super(phone, storageMonitor, usageMonitor); - mDataDownloadHandler = new UsimDataDownloadHandler(mCm); - mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null); - mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null); - mCm.setOnNewGsmBroadcastSms(this, EVENT_NEW_BROADCAST_SMS, null); - } - - @Override - public void dispose() { - mCm.unSetOnNewGsmSms(this); - mCm.unSetOnSmsStatus(this); - mCm.unSetOnNewGsmBroadcastSms(this); - } - - @Override - protected String getFormat() { - return android.telephony.SmsMessage.FORMAT_3GPP; - } - - /** - * Handles 3GPP format-specific events coming from the phone stack. - * Other events are handled by {@link SMSDispatcher#handleMessage}. - * - * @param msg the message to handle - */ - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_NEW_SMS_STATUS_REPORT: - handleStatusReport((AsyncResult) msg.obj); - break; - - case EVENT_NEW_BROADCAST_SMS: - handleBroadcastSms((AsyncResult)msg.obj); - break; - - case EVENT_WRITE_SMS_COMPLETE: - AsyncResult ar = (AsyncResult) msg.obj; - if (ar.exception == null) { - Log.d(TAG, "Successfully wrote SMS-PP message to UICC"); - mCm.acknowledgeLastIncomingGsmSms(true, 0, null); - } else { - Log.d(TAG, "Failed to write SMS-PP message to UICC", ar.exception); - mCm.acknowledgeLastIncomingGsmSms(false, - CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR, null); - } - break; - - default: - super.handleMessage(msg); - } - } - - /** - * 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) { - String pduString = (String) ar.result; - SmsMessage sms = SmsMessage.newFromCDS(pduString); - - if (sms != null) { - int tpStatus = sms.getStatus(); - 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. - if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) { - deliveryPendingList.remove(i); - } - PendingIntent intent = tracker.mDeliveryIntent; - Intent fillIn = new Intent(); - fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString)); - fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP); - try { - intent.send(mContext, Activity.RESULT_OK, fillIn); - } catch (CanceledException ex) {} - - // Only expect to see one tracker matching this messageref - break; - } - } - } - acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null); - } - - /** {@inheritDoc} */ - @Override - public int dispatchMessage(SmsMessageBase smsb) { - - // If sms is null, means there was a parsing error. - if (smsb == null) { - Log.e(TAG, "dispatchMessage: message is null"); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - - SmsMessage sms = (SmsMessage) smsb; - - if (sms.isTypeZero()) { - // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be - // Displayed/Stored/Notified. They should only be acknowledged. - Log.d(TAG, "Received short message type 0, Don't display or store it. Send Ack"); - return Intents.RESULT_SMS_HANDLED; - } - - // Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section 7.1.1. - if (sms.isUsimDataDownload()) { - UsimServiceTable ust = mPhone.getUsimServiceTable(); - // If we receive an SMS-PP message before the UsimServiceTable has been loaded, - // assume that the data download service is not present. This is very unlikely to - // happen because the IMS connection will not be established until after the ISIM - // records have been loaded, after the USIM service table has been loaded. - if (ust != null && ust.isAvailable( - UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP)) { - Log.d(TAG, "Received SMS-PP data download, sending to UICC."); - return mDataDownloadHandler.startDataDownload(sms); - } else { - Log.d(TAG, "DATA_DL_VIA_SMS_PP service not available, storing message to UICC."); - String smsc = IccUtils.bytesToHexString( - PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength( - sms.getServiceCenterAddress())); - mCm.writeSmsToSim(SmsManager.STATUS_ON_ICC_UNREAD, smsc, - IccUtils.bytesToHexString(sms.getPdu()), - obtainMessage(EVENT_WRITE_SMS_COMPLETE)); - return Activity.RESULT_OK; // acknowledge after response from write to USIM - } - } - - if (mSmsReceiveDisabled) { - // Device doesn't support SMS service, - Log.d(TAG, "Received short message on device which doesn't support " - + "SMS service. Ignored."); - return Intents.RESULT_SMS_HANDLED; - } - - // Special case the message waiting indicator messages - boolean handled = false; - if (sms.isMWISetMessage()) { - mPhone.setVoiceMessageWaiting(1, -1); // line 1: unknown number of msgs waiting - handled = sms.isMwiDontStore(); - if (false) { - Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); - } - } else if (sms.isMWIClearMessage()) { - mPhone.setVoiceMessageWaiting(1, 0); // line 1: no msgs waiting - handled = sms.isMwiDontStore(); - if (false) { - Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); - } - } - - if (handled) { - return Intents.RESULT_SMS_HANDLED; - } - - if (!mStorageMonitor.isStorageAvailable() && - sms.getMessageClass() != MessageClass.CLASS_0) { - // It's a storable message and there's no storage available. Bail. - // (See TS 23.038 for a description of class 0 messages.) - return Intents.RESULT_SMS_OUT_OF_MEMORY; - } - - return dispatchNormalMessage(smsb); - } - - /** {@inheritDoc} */ - @Override - protected void sendData(String destAddr, String scAddr, int destPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( - scAddr, destAddr, destPort, data, (deliveryIntent != null)); - if (pdu != null) { - sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, - destAddr); - } else { - Log.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null"); - } - } - - /** {@inheritDoc} */ - @Override - protected void sendText(String destAddr, String scAddr, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent) { - SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( - scAddr, destAddr, text, (deliveryIntent != null)); - if (pdu != null) { - sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, - destAddr); - } else { - Log.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null"); - } - } - - /** {@inheritDoc} */ - @Override - protected TextEncodingDetails calculateLength(CharSequence messageBody, - boolean use7bitOnly) { - return SmsMessage.calculateLength(messageBody, use7bitOnly); - } - - /** {@inheritDoc} */ - @Override - protected void sendNewSubmitPdu(String destinationAddress, String scAddress, - String message, SmsHeader smsHeader, int encoding, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { - SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, - message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader), - encoding, smsHeader.languageTable, smsHeader.languageShiftTable); - if (pdu != null) { - sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, - destinationAddress); - } else { - Log.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null"); - } - } - - /** {@inheritDoc} */ - @Override - 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} */ - @Override - protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { - mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response); - } - - private static int resultToCause(int rc) { - switch (rc) { - case Activity.RESULT_OK: - case Intents.RESULT_SMS_HANDLED: - // Cause code is ignored on success. - return 0; - case Intents.RESULT_SMS_OUT_OF_MEMORY: - return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED; - case Intents.RESULT_SMS_GENERIC_ERROR: - default: - return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR; - } - } - - /** - * Holds all info about a message page needed to assemble a complete - * concatenated message - */ - private static final class SmsCbConcatInfo { - - private final SmsCbHeader mHeader; - private final SmsCbLocation mLocation; - - public SmsCbConcatInfo(SmsCbHeader header, SmsCbLocation location) { - mHeader = header; - mLocation = location; - } - - @Override - public int hashCode() { - return (mHeader.getSerialNumber() * 31) + mLocation.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof SmsCbConcatInfo) { - SmsCbConcatInfo other = (SmsCbConcatInfo)obj; - - // Two pages match if they have the same serial number (which includes the - // geographical scope and update number), and both pages belong to the same - // location (PLMN, plus LAC and CID if these are part of the geographical scope). - return mHeader.getSerialNumber() == other.mHeader.getSerialNumber() - && mLocation.equals(other.mLocation); - } - - return false; - } - - /** - * Compare the location code for this message to the current location code. The match is - * relative to the geographical scope of the message, which determines whether the LAC - * and Cell ID are saved in mLocation or set to -1 to match all values. - * - * @param plmn the current PLMN - * @param lac the current Location Area (GSM) or Service Area (UMTS) - * @param cid the current Cell ID - * @return true if this message is valid for the current location; false otherwise - */ - public boolean matchesLocation(String plmn, int lac, int cid) { - return mLocation.isInLocationArea(plmn, lac, cid); - } - } - - // This map holds incomplete concatenated messages waiting for assembly - private final HashMap mSmsCbPageMap = - new HashMap(); - - /** - * Handle 3GPP format SMS-CB message. - * @param ar the AsyncResult containing the received PDUs - */ - private void handleBroadcastSms(AsyncResult ar) { - try { - byte[] receivedPdu = (byte[])ar.result; - - if (false) { - for (int i = 0; i < receivedPdu.length; i += 8) { - StringBuilder sb = new StringBuilder("SMS CB pdu data: "); - for (int j = i; j < i + 8 && j < receivedPdu.length; j++) { - int b = receivedPdu[j] & 0xff; - if (b < 0x10) { - sb.append('0'); - } - sb.append(Integer.toHexString(b)).append(' '); - } - Log.d(TAG, sb.toString()); - } - } - - SmsCbHeader header = new SmsCbHeader(receivedPdu); - String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); - GsmCellLocation cellLocation = (GsmCellLocation) mPhone.getCellLocation(); - int lac = cellLocation.getLac(); - int cid = cellLocation.getCid(); - - SmsCbLocation location; - switch (header.getGeographicalScope()) { - case SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE: - location = new SmsCbLocation(plmn, lac, -1); - break; - - case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE: - case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE: - location = new SmsCbLocation(plmn, lac, cid); - break; - - case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE: - default: - location = new SmsCbLocation(plmn); - break; - } - - byte[][] pdus; - int pageCount = header.getNumberOfPages(); - if (pageCount > 1) { - // Multi-page message - SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, location); - - // Try to find other pages of the same message - pdus = mSmsCbPageMap.get(concatInfo); - - if (pdus == null) { - // This is the first page of this message, make room for all - // pages and keep until complete - pdus = new byte[pageCount][]; - - mSmsCbPageMap.put(concatInfo, pdus); - } - - // Page parameter is one-based - pdus[header.getPageIndex() - 1] = receivedPdu; - - for (int i = 0; i < pdus.length; i++) { - if (pdus[i] == null) { - // Still missing pages, exit - return; - } - } - - // Message complete, remove and dispatch - mSmsCbPageMap.remove(concatInfo); - } else { - // Single page message - pdus = new byte[1][]; - pdus[0] = receivedPdu; - } - - SmsCbMessage message = GsmSmsCbMessage.createSmsCbMessage(header, location, pdus); - dispatchBroadcastMessage(message); - - // Remove messages that are out of scope to prevent the map from - // growing indefinitely, containing incomplete messages that were - // never assembled - Iterator iter = mSmsCbPageMap.keySet().iterator(); - - while (iter.hasNext()) { - SmsCbConcatInfo info = iter.next(); - - if (!info.matchesLocation(plmn, lac, cid)) { - iter.remove(); - } - } - } catch (RuntimeException e) { - Log.e(TAG, "Error in decoding SMS CB pdu", e); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java deleted file mode 100644 index b7569daa84c8..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ /dev/null @@ -1,1727 +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 com.android.internal.telephony.CommandException; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.DataConnectionTracker; -import com.android.internal.telephony.EventLogTags; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccCardStatus; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.RestrictedState; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.ServiceStateTracker; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.TelephonyProperties; - -import android.app.AlarmManager; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.provider.Telephony.Intents; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.gsm.GsmCellLocation; -import android.text.TextUtils; -import android.util.EventLog; -import android.util.Log; -import android.util.TimeUtils; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.TimeZone; - -/** - * {@hide} - */ -final class GsmServiceStateTracker extends ServiceStateTracker { - static final String LOG_TAG = "GSM"; - static final boolean DBG = true; - - GSMPhone phone; - GsmCellLocation cellLoc; - GsmCellLocation newCellLoc; - int mPreferredNetworkType; - - private int gprsState = ServiceState.STATE_OUT_OF_SERVICE; - private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE; - private int mMaxDataCalls = 1; - private int mNewMaxDataCalls = 1; - private int mReasonDataDenied = -1; - private int mNewReasonDataDenied = -1; - - /** - * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by - * handlePollStateResult to store CREG roaming result. - */ - private boolean mGsmRoaming = false; - - /** - * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by - * handlePollStateResult to store CGREG roaming result. - */ - private boolean mDataRoaming = false; - - /** - * Mark when service state is in emergency call only mode - */ - private boolean mEmergencyOnly = false; - - /** - * 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 mNeedFixZoneAfterNitz = false; - private int mZoneOffset; - private boolean mZoneDst; - private long mZoneTime; - private boolean mGotCountryCode = false; - private ContentResolver cr; - - /** Boolean is true is setTimeFromNITZString was called */ - private boolean mNitzUpdatedTime = 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 mNeedToRegForSimLoaded; - - /** Started the recheck process after finding gprs should registered but not. */ - private boolean mStartedGprsRegCheck = false; - - /** Already sent the event-log for no gprs register. */ - private boolean mReportedGprsNoReg = false; - - /** - * The Notification object given to the NotificationManager. - */ - private Notification mNotification; - - /** Wake lock used while setting time of day. */ - private PowerManager.WakeLock mWakeLock; - private static final String WAKELOCK_TAG = "ServiceStateTracker"; - - /** Keep track of SPN display rules, so we only broadcast intent if something changes. */ - private String curSpn = null; - private String curPlmn = null; - private int curSpnRule = 0; - - /** waiting period before recheck gprs and voice registration. */ - static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000; - - /** Notification type. */ - static final int PS_ENABLED = 1001; // Access Control blocks data service - static final int PS_DISABLED = 1002; // Access Control enables data service - static final int CS_ENABLED = 1003; // Access Control blocks all voice/sms service - static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service - static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service - static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service - - /** Notification id. */ - static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted - static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted - - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) { - // update emergency string whenever locale changed - updateSpnDisplay(); - } - } - }; - - private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - Log.i("GsmServiceStateTracker", "Auto time state changed"); - revertToNitzTime(); - } - }; - - private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - Log.i("GsmServiceStateTracker", "Auto time zone state changed"); - revertToNitzTimeZone(); - } - }; - - public GsmServiceStateTracker(GSMPhone phone) { - super(); - - this.phone = phone; - cm = phone.mCM; - ss = new ServiceState(); - newSS = new ServiceState(); - cellLoc = new GsmCellLocation(); - newCellLoc = new GsmCellLocation(); - mSignalStrength = new SignalStrength(); - - PowerManager powerManager = - (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); - - cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); - cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); - - cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null); - cm.setOnNITZTime(this, EVENT_NITZ_TIME, null); - cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); - cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null); - phone.getIccCard().registerForReady(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); - - cr = phone.getContext().getContentResolver(); - cr.registerContentObserver( - Settings.System.getUriFor(Settings.System.AUTO_TIME), true, - mAutoTimeObserver); - cr.registerContentObserver( - Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true, - mAutoTimeZoneObserver); - - setSignalStrengthDefaultValues(); - mNeedToRegForSimLoaded = true; - - // Monitor locale change - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_LOCALE_CHANGED); - phone.getContext().registerReceiver(mIntentReceiver, filter); - - // Gsm doesn't support OTASP so its not needed - phone.notifyOtaspChanged(OTASP_NOT_NEEDED); - } - - public void dispose() { - // Unregister for all events. - cm.unregisterForAvailable(this); - cm.unregisterForRadioStateChanged(this); - cm.unregisterForVoiceNetworkStateChanged(this); - phone.getIccCard().unregisterForReady(this); - phone.mIccRecords.unregisterForRecordsLoaded(this); - cm.unSetOnSignalStrengthUpdate(this); - cm.unSetOnRestrictedStateChanged(this); - cm.unSetOnNITZTime(this); - cr.unregisterContentObserver(this.mAutoTimeObserver); - cr.unregisterContentObserver(this.mAutoTimeZoneObserver); - } - - protected void finalize() { - if(DBG) log("finalize"); - } - - @Override - protected Phone getPhone() { - return phone; - } - - public void handleMessage (Message msg) { - AsyncResult ar; - int[] ints; - String[] strings; - Message message; - - if (!phone.mIsTheCurrentActivePhone) { - Log.e(LOG_TAG, "Received message " + msg + - "[" + msg.what + "] while being destroyed. Ignoring."); - return; - } - switch (msg.what) { - case EVENT_RADIO_AVAILABLE: - //this is unnecessary - //setPowerStateToDesired(); - break; - - case EVENT_SIM_READY: - // Set the network type, in case the radio does not restore it. - cm.setCurrentPreferredNetworkType(); - - // The SIM is now ready i.e if it was locked - // it has been unlocked. At this stage, the radio is already - // powered on. - if (mNeedToRegForSimLoaded) { - phone.mIccRecords.registerForRecordsLoaded(this, - EVENT_SIM_RECORDS_LOADED, null); - mNeedToRegForSimLoaded = false; - } - - boolean skipRestoringSelection = phone.getContext().getResources().getBoolean( - com.android.internal.R.bool.skip_restoring_network_selection); - - if (!skipRestoringSelection) { - // restore the previous network selection. - phone.restoreSavedNetworkSelection(null); - } - pollState(); - // Signal strength polling stops when radio is off - queueNextSignalStrengthPoll(); - break; - - case EVENT_RADIO_STATE_CHANGED: - // This will do nothing in the radio not - // available case - setPowerStateToDesired(); - pollState(); - break; - - case EVENT_NETWORK_STATE_CHANGED: - pollState(); - break; - - 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 - return; - } - ar = (AsyncResult) msg.obj; - onSignalStrengthResult(ar); - queueNextSignalStrengthPoll(); - - break; - - case EVENT_GET_LOC_DONE: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - String states[] = (String[])ar.result; - int lac = -1; - int cid = -1; - if (states.length >= 3) { - try { - if (states[1] != null && states[1].length() > 0) { - lac = Integer.parseInt(states[1], 16); - } - if (states[2] != null && states[2].length() > 0) { - cid = Integer.parseInt(states[2], 16); - } - } catch (NumberFormatException ex) { - Log.w(LOG_TAG, "error parsing location: " + ex); - } - } - cellLoc.setLacAndCid(lac, cid); - phone.notifyLocationChanged(); - } - - // Release any temporary cell lock, which could have been - // acquired to allow a single-shot location update. - disableSingleLocationUpdate(); - break; - - case EVENT_POLL_STATE_REGISTRATION: - case EVENT_POLL_STATE_GPRS: - case EVENT_POLL_STATE_OPERATOR: - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: - ar = (AsyncResult) msg.obj; - - handlePollStateResult(msg.what, ar); - break; - - case EVENT_POLL_SIGNAL_STRENGTH: - // Just poll signal strength...not part of pollState() - - cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); - break; - - case EVENT_NITZ_TIME: - ar = (AsyncResult) msg.obj; - - String nitzString = (String)((Object[])ar.result)[0]; - long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue(); - - setTimeFromNITZString(nitzString, nitzReceiveTime); - break; - - case EVENT_SIGNAL_STRENGTH_UPDATE: - // This is a notification from - // CommandsInterface.setOnSignalStrengthUpdate - - ar = (AsyncResult) msg.obj; - - // The radio is telling us about signal strength changes - // we don't have to ask it - dontPollSignalStrength = true; - - onSignalStrengthResult(ar); - break; - - case EVENT_SIM_RECORDS_LOADED: - updateSpnDisplay(); - break; - - case EVENT_LOCATION_UPDATES_ENABLED: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null)); - } - break; - - case EVENT_SET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - // Don't care the result, only use for dereg network (COPS=2) - message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj); - cm.setPreferredNetworkType(mPreferredNetworkType, message); - break; - - case EVENT_RESET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - - case EVENT_GET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - mPreferredNetworkType = ((int[])ar.result)[0]; - } else { - mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL; - } - - message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj); - int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL; - - cm.setPreferredNetworkType(toggledNetworkType, message); - break; - - case EVENT_CHECK_REPORT_GPRS: - if (ss != null && !isGprsConsistent(gprsState, ss.getState())) { - - // Can't register data service while voice service is ok - // i.e. CREG is ok while CGREG is not - // possible a network or baseband side error - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL, - ss.getOperatorNumeric(), loc != null ? loc.getCid() : -1); - mReportedGprsNoReg = true; - } - mStartedGprsRegCheck = false; - break; - - case EVENT_RESTRICTED_STATE_CHANGED: - // This is a notification from - // CommandsInterface.setOnRestrictedStateChanged - - if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED"); - - ar = (AsyncResult) msg.obj; - - onRestrictedStateChanged(ar); - break; - - default: - super.handleMessage(msg); - break; - } - } - - protected void setPowerStateToDesired() { - // If we want it on and it's off, turn it on - if (mDesiredPowerState - && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) { - cm.setRadioPower(true, null); - } else if (!mDesiredPowerState && cm.getRadioState().isOn()) { - // If it's on and available and we want it off gracefully - DataConnectionTracker dcTracker = phone.mDataConnectionTracker; - powerOffRadioSafely(dcTracker); - } // Otherwise, we're in the desired state - } - - @Override - protected void hangupAndPowerOff() { - // hang up all active voice calls - if (phone.isInCall()) { - phone.mCT.ringingCall.hangupIfAlive(); - phone.mCT.backgroundCall.hangupIfAlive(); - phone.mCT.foregroundCall.hangupIfAlive(); - } - - cm.setRadioPower(false, null); - } - - protected void updateSpnDisplay() { - int rule = phone.mIccRecords.getDisplayRule(ss.getOperatorNumeric()); - String spn = phone.mIccRecords.getServiceProviderName(); - String plmn = ss.getOperatorAlphaLong(); - - // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN - if (mEmergencyOnly && cm.getRadioState().isOn()) { - plmn = Resources.getSystem(). - getText(com.android.internal.R.string.emergency_calls_only).toString(); - if (DBG) log("updateSpnDisplay: emergency only and radio is on plmn='" + plmn + "'"); - } - - if (rule != curSpnRule - || !TextUtils.equals(spn, curSpn) - || !TextUtils.equals(plmn, curPlmn)) { - boolean showSpn = !mEmergencyOnly && !TextUtils.isEmpty(spn) - && (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN; - boolean showPlmn = !TextUtils.isEmpty(plmn) && - (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN; - - if (DBG) { - log(String.format("updateSpnDisplay: changed sending intent" + " rule=" + rule + - " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'", - showPlmn, plmn, showSpn, spn)); - } - Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn); - intent.putExtra(Intents.EXTRA_SPN, spn); - intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); - intent.putExtra(Intents.EXTRA_PLMN, plmn); - phone.getContext().sendStickyBroadcast(intent); - } - - curSpnRule = rule; - curSpn = spn; - curPlmn = plmn; - } - - /** - * Handle the result of one of the pollState()-related requests - */ - protected void handlePollStateResult (int what, AsyncResult ar) { - int ints[]; - String states[]; - - // Ignore stale requests from last poll - if (ar.userObj != pollingContext) return; - - if (ar.exception != null) { - CommandException.Error err=null; - - if (ar.exception instanceof CommandException) { - err = ((CommandException)(ar.exception)).getCommandError(); - } - - if (err == CommandException.Error.RADIO_NOT_AVAILABLE) { - // Radio has crashed or turned off - cancelPollState(); - return; - } - - if (!cm.getRadioState().isOn()) { - // Radio has crashed or turned off - cancelPollState(); - return; - } - - if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) { - loge("RIL implementation has returned an error where it must succeed" + - ar.exception); - } - } else try { - switch (what) { - case EVENT_POLL_STATE_REGISTRATION: - states = (String[])ar.result; - int lac = -1; - int cid = -1; - int regState = -1; - int reasonRegStateDenied = -1; - int psc = -1; - if (states.length > 0) { - try { - regState = Integer.parseInt(states[0]); - if (states.length >= 3) { - if (states[1] != null && states[1].length() > 0) { - lac = Integer.parseInt(states[1], 16); - } - if (states[2] != null && states[2].length() > 0) { - cid = Integer.parseInt(states[2], 16); - } - } - if (states.length > 14) { - if (states[14] != null && states[14].length() > 0) { - psc = Integer.parseInt(states[14], 16); - } - } - } catch (NumberFormatException ex) { - loge("error parsing RegistrationState: " + ex); - } - } - - mGsmRoaming = regCodeIsRoaming(regState); - newSS.setState (regCodeToServiceState(regState)); - - if (regState == 10 || regState == 12 || regState == 13 || regState == 14) { - mEmergencyOnly = true; - } else { - mEmergencyOnly = false; - } - - // LAC and CID are -1 if not avail - newCellLoc.setLacAndCid(lac, cid); - newCellLoc.setPsc(psc); - break; - - case EVENT_POLL_STATE_GPRS: - states = (String[])ar.result; - - int type = 0; - regState = -1; - mNewReasonDataDenied = -1; - mNewMaxDataCalls = 1; - 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]); - } - if ((states.length >= 5 ) && (regState == 3)) { - mNewReasonDataDenied = Integer.parseInt(states[4]); - } - if (states.length >= 6) { - mNewMaxDataCalls = Integer.parseInt(states[5]); - } - } catch (NumberFormatException ex) { - loge("error parsing GprsRegistrationState: " + ex); - } - } - newGPRSState = regCodeToServiceState(regState); - mDataRoaming = regCodeIsRoaming(regState); - mNewRilRadioTechnology = type; - newSS.setRadioTechnology(type); - break; - - case EVENT_POLL_STATE_OPERATOR: - String opNames[] = (String[])ar.result; - - if (opNames != null && opNames.length >= 3) { - newSS.setOperatorName (opNames[0], opNames[1], opNames[2]); - } - break; - - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: - ints = (int[])ar.result; - newSS.setIsManualSelection(ints[0] == 1); - break; - } - - } catch (RuntimeException ex) { - loge("Exception while polling service state. Probably malformed RIL response." + ex); - } - - pollingContext[0]--; - - if (pollingContext[0] == 0) { - /** - * Since the roaming states of gsm service (from +CREG) and - * data service (from +CGREG) could be different, the new SS - * is set roaming while either one is roaming. - * - * There is an exception for the above rule. The new SS is not set - * as roaming while gsm service reports roaming but indeed it is - * not roaming between operators. - */ - boolean roaming = (mGsmRoaming || mDataRoaming); - if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) { - roaming = false; - } - newSS.setRoaming(roaming); - newSS.setEmergencyOnly(mEmergencyOnly); - pollStateDone(); - } - } - - private void setSignalStrengthDefaultValues() { - // TODO Make a constructor only has boolean gsm as parameter - mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, - -1, -1, -1, SignalStrength.INVALID_SNR, -1, true); - } - - /** - * A complete "service state" from our perspective is - * composed of a handful of separate requests to the radio. - * - * We make all of these requests at once, but then abandon them - * and start over again if the radio notifies us that some - * event has changed - */ - private void pollState() { - pollingContext = new int[1]; - pollingContext[0] = 0; - - switch (cm.getRadioState()) { - case RADIO_UNAVAILABLE: - newSS.setStateOutOfService(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - mGotCountryCode = false; - mNitzUpdatedTime = false; - pollStateDone(); - break; - - case RADIO_OFF: - newSS.setStateOff(); - newCellLoc.setStateInvalid(); - setSignalStrengthDefaultValues(); - mGotCountryCode = false; - mNitzUpdatedTime = 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]++; - cm.getOperator( - obtainMessage( - EVENT_POLL_STATE_OPERATOR, pollingContext)); - - pollingContext[0]++; - cm.getDataRegistrationState( - obtainMessage( - EVENT_POLL_STATE_GPRS, pollingContext)); - - pollingContext[0]++; - cm.getVoiceRegistrationState( - obtainMessage( - EVENT_POLL_STATE_REGISTRATION, pollingContext)); - - pollingContext[0]++; - cm.getNetworkSelectionMode( - obtainMessage( - EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext)); - break; - } - } - - private void pollStateDone() { - if (DBG) { - log("Poll ServiceState done: " + - " oldSS=[" + ss + "] newSS=[" + newSS + - "] oldGprs=" + gprsState + " newData=" + newGPRSState + - " oldMaxDataCalls=" + mMaxDataCalls + - " mNewMaxDataCalls=" + mNewMaxDataCalls + - " oldReasonDataDenied=" + mReasonDataDenied + - " mNewReasonDataDenied=" + mNewReasonDataDenied + - " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) + - " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology)); - } - - boolean hasRegistered = - ss.getState() != ServiceState.STATE_IN_SERVICE - && newSS.getState() == ServiceState.STATE_IN_SERVICE; - - boolean hasDeregistered = - ss.getState() == ServiceState.STATE_IN_SERVICE - && newSS.getState() != ServiceState.STATE_IN_SERVICE; - - boolean hasGprsAttached = - gprsState != ServiceState.STATE_IN_SERVICE - && newGPRSState == ServiceState.STATE_IN_SERVICE; - - boolean hasGprsDetached = - gprsState == ServiceState.STATE_IN_SERVICE - && newGPRSState != ServiceState.STATE_IN_SERVICE; - - boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology; - - boolean hasChanged = !newSS.equals(ss); - - boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming(); - - boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming(); - - boolean hasLocationChanged = !newCellLoc.equals(cellLoc); - - // Add an event log when connection state changes - if (ss.getState() != newSS.getState() || gprsState != newGPRSState) { - EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE, - ss.getState(), gprsState, newSS.getState(), newGPRSState); - } - - ServiceState tss; - tss = ss; - ss = newSS; - newSS = tss; - // clean slate for next time - newSS.setStateOutOfService(); - - GsmCellLocation tcl = cellLoc; - cellLoc = newCellLoc; - newCellLoc = tcl; - - // Add an event log when network type switched - // TODO: we may add filtering to reduce the event logged, - // i.e. check preferred network setting, only switch to 2G, etc - if (hasRadioTechnologyChanged) { - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology, - mNewRilRadioTechnology); - if (DBG) { - log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) + - " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) + - " at cell " + cid); - } - } - - gprsState = newGPRSState; - mReasonDataDenied = mNewReasonDataDenied; - mMaxDataCalls = mNewMaxDataCalls; - mRilRadioTechnology = mNewRilRadioTechnology; - // this new state has been applied - forget it until we get a new new state - mNewRilRadioTechnology = 0; - - - newSS.setStateOutOfService(); // clean slate for next time - - if (hasRadioTechnologyChanged) { - phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, - ServiceState.rilRadioTechnologyToString(mRilRadioTechnology)); - } - - if (hasRegistered) { - mNetworkAttachedRegistrants.notifyRegistrants(); - - if (DBG) { - log("pollStateDone: registering current mNitzUpdatedTime=" + - mNitzUpdatedTime + " changing to false"); - } - mNitzUpdatedTime = false; - } - - if (hasChanged) { - String operatorNumeric; - - updateSpnDisplay(); - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA, - ss.getOperatorAlphaLong()); - - String prevOperatorNumeric = - SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, ""); - operatorNumeric = ss.getOperatorNumeric(); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); - - if (operatorNumeric == null) { - if (DBG) log("operatorNumeric is null"); - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); - mGotCountryCode = false; - mNitzUpdatedTime = false; - } else { - String iso = ""; - String mcc = operatorNumeric.substring(0, 3); - try{ - iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc)); - } catch ( NumberFormatException ex){ - loge("pollStateDone: countryCodeForMcc error" + ex); - } catch ( StringIndexOutOfBoundsException ex) { - loge("pollStateDone: countryCodeForMcc error" + ex); - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso); - mGotCountryCode = true; - - TimeZone zone = null; - - if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) && - getAutoTimeZone()) { - - // Test both paths if ignore nitz is true - boolean testOneUniqueOffsetPath = SystemProperties.getBoolean( - TelephonyProperties.PROPERTY_IGNORE_NITZ, false) && - ((SystemClock.uptimeMillis() & 1) == 0); - - ArrayList uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso); - if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) { - zone = uniqueZones.get(0); - if (DBG) { - log("pollStateDone: no nitz but one TZ for iso-cc=" + iso + - " with zone.getID=" + zone.getID() + - " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath); - } - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } else { - if (DBG) { - log("pollStateDone: there are " + uniqueZones.size() + - " unique offsets for iso-cc='" + iso + - " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath + - "', do nothing"); - } - } - } - - if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric, - mNeedFixZoneAfterNitz)) { - // 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 (DBG) { - log("pollStateDone: fix time zone zoneName='" + zoneName + - "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst + - " iso-cc='" + iso + - "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso)); - } - - // "(mZoneOffset == 0) && (mZoneDst == false) && - // (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)" - // means that we received a NITZ string telling - // it is in GMT+0 w/ DST time zone - // BUT iso tells is NOT, e.g, a wrong NITZ reporting - // local time w/ 0 offset. - if ((mZoneOffset == 0) && (mZoneDst == false) && - (zoneName != null) && (zoneName.length() > 0) && - (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) { - zone = TimeZone.getDefault(); - if (mNeedFixZoneAfterNitz) { - // For wrong NITZ reporting local time w/ 0 offset, - // need adjust time to reflect default timezone setting - long ctm = System.currentTimeMillis(); - long tzOffset = zone.getOffset(ctm); - if (DBG) { - log("pollStateDone: tzOffset=" + tzOffset + " ltod=" + - TimeUtils.logTimeOfDay(ctm)); - } - if (getAutoTime()) { - long adj = ctm - tzOffset; - if (DBG) log("pollStateDone: adj ltod=" + - TimeUtils.logTimeOfDay(adj)); - setAndBroadcastNetworkSetTime(adj); - } else { - // Adjust the saved NITZ time to account for tzOffset. - mSavedTime = mSavedTime - tzOffset; - } - } - if (DBG) log("pollStateDone: using default TimeZone"); - } 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); - if (DBG) log("pollStateDone: using NITZ TimeZone"); - } else { - zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso); - if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)"); - } - - mNeedFixZoneAfterNitz = false; - - if (zone != null) { - log("pollStateDone: zone != null zone.getID=" + zone.getID()); - if (getAutoTimeZone()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } - saveNitzTimeZone(zone.getID()); - } else { - log("pollStateDone: zone == null"); - } - } - } - - phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, - ss.getRoaming() ? "true" : "false"); - - phone.notifyServiceStateChanged(ss); - } - - if (hasGprsAttached) { - mAttachedRegistrants.notifyRegistrants(); - } - - if (hasGprsDetached) { - mDetachedRegistrants.notifyRegistrants(); - } - - if (hasRadioTechnologyChanged) { - phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED); - } - - if (hasRoamingOn) { - mRoamingOnRegistrants.notifyRegistrants(); - } - - if (hasRoamingOff) { - mRoamingOffRegistrants.notifyRegistrants(); - } - - if (hasLocationChanged) { - phone.notifyLocationChanged(); - } - - if (! isGprsConsistent(gprsState, ss.getState())) { - if (!mStartedGprsRegCheck && !mReportedGprsNoReg) { - mStartedGprsRegCheck = true; - - int check_period = Settings.Secure.getInt( - phone.getContext().getContentResolver(), - Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS, - DEFAULT_GPRS_CHECK_PERIOD_MILLIS); - sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS), - check_period); - } - } else { - mReportedGprsNoReg = false; - } - } - - /** - * Check if GPRS got registered while voice is registered. - * - * @param gprsState for GPRS registration state, i.e. CGREG in GSM - * @param serviceState for voice registration state, i.e. CREG in GSM - * @return false if device only register to voice but not gprs - */ - private boolean isGprsConsistent(int gprsState, int serviceState) { - return !((serviceState == ServiceState.STATE_IN_SERVICE) && - (gprsState != ServiceState.STATE_IN_SERVICE)); - } - - /** - * Returns a TimeZone object based only on parameters from the NITZ string. - */ - private TimeZone getNitzTimeZone(int offset, boolean dst, long when) { - TimeZone guess = findTimeZone(offset, dst, when); - if (guess == null) { - // Couldn't find a proper timezone. Perhaps the DST data is wrong. - guess = findTimeZone(offset, !dst, when); - } - if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID())); - return guess; - } - - private TimeZone findTimeZone(int offset, boolean dst, long when) { - int rawOffset = offset; - if (dst) { - rawOffset -= 3600000; - } - String[] zones = TimeZone.getAvailableIDs(rawOffset); - TimeZone guess = null; - Date d = new Date(when); - for (String zone : zones) { - TimeZone tz = TimeZone.getTimeZone(zone); - if (tz.getOffset(when) == offset && - tz.inDaylightTime(d) == dst) { - guess = tz; - break; - } - } - - return guess; - } - - private void queueNextSignalStrengthPoll() { - if (dontPollSignalStrength) { - // The radio is telling us about signal strength changes - // we don't have to ask it - return; - } - - Message msg; - - msg = obtainMessage(); - msg.what = EVENT_POLL_SIGNAL_STRENGTH; - - long nextTime; - - // TODO Don't poll signal strength if screen is off - sendMessageDelayed(msg, POLL_PERIOD_MILLIS); - } - - /** - * Send signal-strength-changed notification if changed. - * Called both for solicited and unsolicited signal strength updates. - */ - private void onSignalStrengthResult(AsyncResult ar) { - SignalStrength oldSignalStrength = mSignalStrength; - int rssi = 99; - int lteSignalStrength = -1; - int lteRsrp = -1; - int lteRsrq = -1; - int lteRssnr = SignalStrength.INVALID_SNR; - int lteCqi = -1; - - if (ar.exception != null) { - // -1 = unknown - // most likely radio is resetting/disconnected - setSignalStrengthDefaultValues(); - } else { - int[] ints = (int[])ar.result; - - // bug 658816 seems to be a case where the result is 0-length - if (ints.length != 0) { - rssi = ints[0]; - lteSignalStrength = ints[7]; - lteRsrp = ints[8]; - lteRsrq = ints[9]; - lteRssnr = ints[10]; - lteCqi = ints[11]; - } else { - loge("Bogus signal strength response"); - rssi = 99; - } - } - - mSignalStrength = new SignalStrength(rssi, -1, -1, -1, - -1, -1, -1, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi, true); - - if (!mSignalStrength.equals(oldSignalStrength)) { - try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after - // POLL_PERIOD_MILLIS) during Radio Technology Change) - phone.notifySignalStrength(); - } catch (NullPointerException ex) { - log("onSignalStrengthResult() Phone already destroyed: " + ex - + "SignalStrength not notified"); - } - } - } - - /** - * Set restricted state based on the OnRestrictedStateChanged notification - * If any voice or packet restricted state changes, trigger a UI - * notification and notify registrants when sim is ready. - * - * @param ar an int value of RIL_RESTRICTED_STATE_* - */ - private void onRestrictedStateChanged(AsyncResult ar) { - RestrictedState newRs = new RestrictedState(); - - if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState); - - if (ar.exception == null) { - int[] ints = (int[])ar.result; - int state = ints[0]; - - newRs.setCsEmergencyRestricted( - ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) || - ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); - //ignore the normal call and data restricted state before SIM READY - if (phone.getIccCard().getState() == IccCard.State.READY) { - newRs.setCsNormalRestricted( - ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) || - ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); - newRs.setPsRestricted( - (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0); - } - - if (DBG) log("onRestrictedStateChanged: new rs "+ newRs); - - if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) { - mPsRestrictEnabledRegistrants.notifyRegistrants(); - setNotification(PS_ENABLED); - } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) { - mPsRestrictDisabledRegistrants.notifyRegistrants(); - setNotification(PS_DISABLED); - } - - /** - * There are two kind of cs restriction, normal and emergency. So - * there are 4 x 4 combinations in current and new restricted states - * and we only need to notify when state is changed. - */ - if (mRestrictedState.isCsRestricted()) { - if (!newRs.isCsRestricted()) { - // remove all restriction - setNotification(CS_DISABLED); - } else if (!newRs.isCsNormalRestricted()) { - // remove normal restriction - setNotification(CS_EMERGENCY_ENABLED); - } else if (!newRs.isCsEmergencyRestricted()) { - // remove emergency restriction - setNotification(CS_NORMAL_ENABLED); - } - } else if (mRestrictedState.isCsEmergencyRestricted() && - !mRestrictedState.isCsNormalRestricted()) { - if (!newRs.isCsRestricted()) { - // remove all restriction - setNotification(CS_DISABLED); - } else if (newRs.isCsRestricted()) { - // enable all restriction - setNotification(CS_ENABLED); - } else if (newRs.isCsNormalRestricted()) { - // remove emergency restriction and enable normal restriction - setNotification(CS_NORMAL_ENABLED); - } - } else if (!mRestrictedState.isCsEmergencyRestricted() && - mRestrictedState.isCsNormalRestricted()) { - if (!newRs.isCsRestricted()) { - // remove all restriction - setNotification(CS_DISABLED); - } else if (newRs.isCsRestricted()) { - // enable all restriction - setNotification(CS_ENABLED); - } else if (newRs.isCsEmergencyRestricted()) { - // remove normal restriction and enable emergency restriction - setNotification(CS_EMERGENCY_ENABLED); - } - } else { - if (newRs.isCsRestricted()) { - // enable all restriction - setNotification(CS_ENABLED); - } else if (newRs.isCsEmergencyRestricted()) { - // enable emergency restriction - setNotification(CS_EMERGENCY_ENABLED); - } else if (newRs.isCsNormalRestricted()) { - // enable normal restriction - setNotification(CS_NORMAL_ENABLED); - } - } - - mRestrictedState = newRs; - } - log("onRestrictedStateChanged: X rs "+ mRestrictedState); - } - - /** code is registration state 0-5 from TS 27.007 7.2 */ - private int regCodeToServiceState(int code) { - switch (code) { - case 0: - case 2: // 2 is "searching" - case 3: // 3 is "registration denied" - case 4: // 4 is "unknown" no vaild in current baseband - case 10:// same as 0, but indicates that emergency call is possible. - case 12:// same as 2, but indicates that emergency call is possible. - case 13:// same as 3, but indicates that emergency call is possible. - case 14:// same as 4, but indicates that emergency call is possible. - return ServiceState.STATE_OUT_OF_SERVICE; - - case 1: - return ServiceState.STATE_IN_SERVICE; - - case 5: - // in service, roam - return ServiceState.STATE_IN_SERVICE; - - default: - loge("regCodeToServiceState: unexpected service state " + code); - return ServiceState.STATE_OUT_OF_SERVICE; - } - } - - - /** - * code is registration state 0-5 from TS 27.007 7.2 - * returns true if registered roam, false otherwise - */ - private boolean regCodeIsRoaming (int code) { - // 5 is "in service -- roam" - return 5 == code; - } - - /** - * Set roaming state when gsmRoaming is true and, if operator mcc is the - * same as sim mcc, ons is different from spn - * @param gsmRoaming TS 27.007 7.2 CREG registered roaming - * @param s ServiceState hold current ons - * @return true for roaming state set - */ - private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) { - String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty"); - - String onsl = s.getOperatorAlphaLong(); - String onss = s.getOperatorAlphaShort(); - - boolean equalsOnsl = onsl != null && spn.equals(onsl); - boolean equalsOnss = onss != null && spn.equals(onss); - - String simNumeric = SystemProperties.get( - TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, ""); - String operatorNumeric = s.getOperatorNumeric(); - - boolean equalsMcc = true; - try { - equalsMcc = simNumeric.substring(0, 3). - equals(operatorNumeric.substring(0, 3)); - } catch (Exception e){ - } - - return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss)); - } - - 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; - } - - /** - * @return The current GPRS state. IN_SERVICE is the same as "attached" - * and OUT_OF_SERVICE is the same as detached. - */ - int getCurrentGprsState() { - return gprsState; - } - - public int getCurrentDataConnectionState() { - return gprsState; - } - - /** - * @return true if phone is camping on a technology (eg UMTS) - * that could support voice and data simultaneously. - */ - public boolean isConcurrentVoiceAndDataAllowed() { - return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS); - } - - /** - * 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); - } - - /** - * nitzReceiveTime is time_t that the NITZ time was posted - */ - private void setTimeFromNITZString (String nitz, long nitzReceiveTime) { - // "yy/mm/dd,hh:mm:ss(+/-)tz" - // tz is in number of quarter-hours - - long start = SystemClock.elapsedRealtime(); - if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime + - " start=" + start + " delay=" + (start - nitzReceiveTime)); - } - - try { - /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone - * offset as well (which we won't worry about until later) */ - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - - c.clear(); - c.set(Calendar.DST_OFFSET, 0); - - String[] nitzSubs = nitz.split("[/:,+-]"); - - int year = 2000 + Integer.parseInt(nitzSubs[0]); - c.set(Calendar.YEAR, year); - - // month is 0 based! - int month = Integer.parseInt(nitzSubs[1]) - 1; - c.set(Calendar.MONTH, month); - - int date = Integer.parseInt(nitzSubs[2]); - c.set(Calendar.DATE, date); - - int hour = Integer.parseInt(nitzSubs[3]); - c.set(Calendar.HOUR, hour); - - int minute = Integer.parseInt(nitzSubs[4]); - c.set(Calendar.MINUTE, minute); - - int second = Integer.parseInt(nitzSubs[5]); - c.set(Calendar.SECOND, second); - - boolean sign = (nitz.indexOf('-') == -1); - - int tzOffset = Integer.parseInt(nitzSubs[6]); - - int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7]) - : 0; - - // The zone offset received from NITZ is for current local time, - // so DST correction is already applied. Don't add it again. - // - // tzOffset += dst * 4; - // - // We could unapply it if we wanted the raw offset. - - tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000; - - TimeZone zone = null; - - // As a special extension, the Android emulator appends the name of - // the host computer's timezone to the nitz string. this is zoneinfo - // timezone name of the form Area!Location or Area!Location!SubLocation - // so we need to convert the ! into / - if (nitzSubs.length >= 9) { - String tzname = nitzSubs[8].replace('!','/'); - zone = TimeZone.getTimeZone( tzname ); - } - - String iso = SystemProperties.get(TelephonyProperties.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) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){ - // We got the time before the country or the zone has changed - // so we don't know how to identify the DST rules yet. Save - // the information and hope to fix it up later. - - mNeedFixZoneAfterNitz = true; - mZoneOffset = tzOffset; - mZoneDst = dst != 0; - mZoneTime = c.getTimeInMillis(); - } - - if (zone != null) { - if (getAutoTimeZone()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } - saveNitzTimeZone(zone.getID()); - } - - String ignore = SystemProperties.get("gsm.ignore-nitz"); - if (ignore != null && ignore.equals("yes")) { - log("NITZ: Not setting clock because gsm.ignore-nitz is set"); - return; - } - - try { - mWakeLock.acquire(); - - if (getAutoTime()) { - long millisSinceNitzReceived - = SystemClock.elapsedRealtime() - nitzReceiveTime; - - if (millisSinceNitzReceived < 0) { - // Sanity check: something is wrong - if (DBG) { - log("NITZ: not setting time, clock has rolled " - + "backwards since NITZ time was received, " - + nitz); - } - return; - } - - if (millisSinceNitzReceived > Integer.MAX_VALUE) { - // If the time is this far off, something is wrong > 24 days! - if (DBG) { - log("NITZ: not setting time, processing has taken " - + (millisSinceNitzReceived / (1000 * 60 * 60 * 24)) - + " days"); - } - return; - } - - // Note: with range checks above, cast to int is safe - c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived); - - if (DBG) { - log("NITZ: Setting time of day to " + c.getTime() - + " NITZ receive delay(ms): " + millisSinceNitzReceived - + " gained(ms): " - + (c.getTimeInMillis() - System.currentTimeMillis()) - + " from " + nitz); - } - - setAndBroadcastNetworkSetTime(c.getTimeInMillis()); - Log.i(LOG_TAG, "NITZ: after Setting time of day"); - } - SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis())); - saveNitzTime(c.getTimeInMillis()); - if (false) { - long end = SystemClock.elapsedRealtime(); - log("NITZ: end=" + end + " dur=" + (end - start)); - } - mNitzUpdatedTime = true; - } finally { - mWakeLock.release(); - } - } catch (RuntimeException ex) { - loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex); - } - } - - private boolean getAutoTime() { - try { - return Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME) > 0; - } catch (SettingNotFoundException snfe) { - return true; - } - } - - private boolean getAutoTimeZone() { - try { - return Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME_ZONE) > 0; - } catch (SettingNotFoundException snfe) { - return true; - } - } - - private void saveNitzTimeZone(String zoneId) { - mSavedTimeZone = zoneId; - } - - private void saveNitzTime(long time) { - mSavedTime = time; - mSavedAtTime = SystemClock.elapsedRealtime(); - } - - /** - * Set the timezone and send out a sticky broadcast so the system can - * determine if the timezone was set by the carrier. - * - * @param zoneId timezone set by carrier - */ - private void setAndBroadcastNetworkSetTimeZone(String zoneId) { - if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId); - AlarmManager alarm = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - alarm.setTimeZone(zoneId); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time-zone", zoneId); - phone.getContext().sendStickyBroadcast(intent); - if (DBG) { - log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" + - zoneId); - } - } - - /** - * Set the time and Send out a sticky broadcast so the system can determine - * if the time was set by the carrier. - * - * @param time time set by network - */ - private void setAndBroadcastNetworkSetTime(long time) { - if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms"); - SystemClock.setCurrentTimeMillis(time); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time", time); - phone.getContext().sendStickyBroadcast(intent); - } - - private void revertToNitzTime() { - if (Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME, 0) == 0) { - return; - } - if (DBG) { - log("Reverting to NITZ Time: mSavedTime=" + mSavedTime - + " mSavedAtTime=" + mSavedAtTime); - } - if (mSavedTime != 0 && mSavedAtTime != 0) { - setAndBroadcastNetworkSetTime(mSavedTime - + (SystemClock.elapsedRealtime() - mSavedAtTime)); - } - } - - private void revertToNitzTimeZone() { - if (Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME_ZONE, 0) == 0) { - return; - } - if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone); - if (mSavedTimeZone != null) { - setAndBroadcastNetworkSetTimeZone(mSavedTimeZone); - } - } - - /** - * Post a notification to NotificationManager for restricted state - * - * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE - */ - private void setNotification(int notifyType) { - - if (DBG) log("setNotification: create notification " + notifyType); - Context context = phone.getContext(); - - mNotification = new Notification(); - mNotification.when = System.currentTimeMillis(); - mNotification.flags = Notification.FLAG_AUTO_CANCEL; - mNotification.icon = com.android.internal.R.drawable.stat_sys_warning; - Intent intent = new Intent(); - mNotification.contentIntent = PendingIntent - .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - - CharSequence details = ""; - CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle); - int notificationId = CS_NOTIFICATION; - - switch (notifyType) { - case PS_ENABLED: - notificationId = PS_NOTIFICATION; - details = context.getText(com.android.internal.R.string.RestrictedOnData);; - break; - case PS_DISABLED: - notificationId = PS_NOTIFICATION; - break; - case CS_ENABLED: - details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);; - break; - case CS_NORMAL_ENABLED: - details = context.getText(com.android.internal.R.string.RestrictedOnNormal);; - break; - case CS_EMERGENCY_ENABLED: - details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);; - break; - case CS_DISABLED: - // do nothing and cancel the notification later - break; - } - - if (DBG) log("setNotification: put notification " + title + " / " +details); - mNotification.tickerText = title; - mNotification.setLatestEventInfo(context, title, details, - mNotification.contentIntent); - - NotificationManager notificationManager = (NotificationManager) - context.getSystemService(Context.NOTIFICATION_SERVICE); - - if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) { - // cancel previous post notification - notificationManager.cancel(notificationId); - } else { - // update restricted state notification - notificationManager.notify(notificationId, mNotification); - } - } - - @Override - protected void log(String s) { - Log.d(LOG_TAG, "[GsmSST] " + s); - } - - @Override - protected void loge(String s) { - Log.e(LOG_TAG, "[GsmSST] " + s); - } - - private static void sloge(String s) { - Log.e(LOG_TAG, "[GsmSST] " + s); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("GsmServiceStateTracker extends:"); - super.dump(fd, pw, args); - pw.println(" phone=" + phone); - pw.println(" cellLoc=" + cellLoc); - pw.println(" newCellLoc=" + newCellLoc); - pw.println(" mPreferredNetworkType=" + mPreferredNetworkType); - pw.println(" gprsState=" + gprsState); - pw.println(" newGPRSState=" + newGPRSState); - pw.println(" mMaxDataCalls=" + mMaxDataCalls); - pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls); - pw.println(" mReasonDataDenied=" + mReasonDataDenied); - pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied); - pw.println(" mGsmRoaming=" + mGsmRoaming); - pw.println(" mDataRoaming=" + mDataRoaming); - pw.println(" mEmergencyOnly=" + mEmergencyOnly); - pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz); - pw.println(" mZoneOffset=" + mZoneOffset); - pw.println(" mZoneDst=" + mZoneDst); - pw.println(" mZoneTime=" + mZoneTime); - pw.println(" mGotCountryCode=" + mGotCountryCode); - pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime); - pw.println(" mSavedTimeZone=" + mSavedTimeZone); - pw.println(" mSavedTime=" + mSavedTime); - pw.println(" mSavedAtTime=" + mSavedAtTime); - pw.println(" mNeedToRegForSimLoaded=" + mNeedToRegForSimLoaded); - pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck); - pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg); - pw.println(" mNotification=" + mNotification); - pw.println(" mWakeLock=" + mWakeLock); - pw.println(" curSpn=" + curSpn); - pw.println(" curPlmn=" + curPlmn); - pw.println(" curSpnRule=" + curSpnRule); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java deleted file mode 100644 index c163803a6ff0..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.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/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java deleted file mode 100644 index dc9554a56d80..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2012 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.SmsCbLocation; -import android.telephony.SmsCbMessage; -import android.util.Pair; - -import com.android.internal.telephony.GsmAlphabet; - -import java.io.UnsupportedEncodingException; - -/** - * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is - * public because {@link #createSmsCbMessage(SmsCbLocation, byte[][])} is used by some test cases. - */ -public class GsmSmsCbMessage { - - /** - * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5. - */ - private static final String[] LANGUAGE_CODES_GROUP_0 = { - "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu", - "pl", null - }; - - /** - * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5. - */ - private static final String[] LANGUAGE_CODES_GROUP_2 = { - "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null, - null, null - }; - - private static final char CARRIAGE_RETURN = 0x0d; - - private static final int PDU_BODY_PAGE_LENGTH = 82; - - /** Utility class with only static methods. */ - private GsmSmsCbMessage() { } - - /** - * Create a new SmsCbMessage object from a header object plus one or more received PDUs. - * - * @param pdus PDU bytes - */ - static SmsCbMessage createSmsCbMessage(SmsCbHeader header, SmsCbLocation location, - byte[][] pdus) throws IllegalArgumentException { - if (header.isEtwsPrimaryNotification()) { - return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, - header.getGeographicalScope(), header.getSerialNumber(), - location, header.getServiceCategory(), - null, "ETWS", SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, - header.getEtwsInfo(), header.getCmasInfo()); - } else { - String language = null; - StringBuilder sb = new StringBuilder(); - for (byte[] pdu : pdus) { - Pair p = parseBody(header, pdu); - language = p.first; - sb.append(p.second); - } - int priority = header.isEmergencyMessage() ? SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY - : SmsCbMessage.MESSAGE_PRIORITY_NORMAL; - - return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, - header.getGeographicalScope(), header.getSerialNumber(), location, - header.getServiceCategory(), language, sb.toString(), priority, - header.getEtwsInfo(), header.getCmasInfo()); - } - } - - /** - * Create a new SmsCbMessage object from one or more received PDUs. This is used by some - * CellBroadcastReceiver test cases, because SmsCbHeader is now package local. - * - * @param location the location (geographical scope) for the message - * @param pdus PDU bytes - */ - public static SmsCbMessage createSmsCbMessage(SmsCbLocation location, byte[][] pdus) - throws IllegalArgumentException { - SmsCbHeader header = new SmsCbHeader(pdus[0]); - return createSmsCbMessage(header, location, pdus); - } - - /** - * Parse and unpack the body text according to the encoding in the DCS. - * After completing successfully this method will have assigned the body - * text into mBody, and optionally the language code into mLanguage - * - * @param header the message header to use - * @param pdu the PDU to decode - * @return a Pair of Strings containing the language and body of the message - */ - private static Pair parseBody(SmsCbHeader header, byte[] pdu) { - int encoding; - String language = null; - boolean hasLanguageIndicator = false; - int dataCodingScheme = header.getDataCodingScheme(); - - // Extract encoding and language from DCS, as defined in 3gpp TS 23.038, - // section 5. - switch ((dataCodingScheme & 0xf0) >> 4) { - case 0x00: - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f]; - break; - - case 0x01: - hasLanguageIndicator = true; - if ((dataCodingScheme & 0x0f) == 0x01) { - encoding = android.telephony.SmsMessage.ENCODING_16BIT; - } else { - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - } - break; - - case 0x02: - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f]; - break; - - case 0x03: - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - break; - - case 0x04: - case 0x05: - switch ((dataCodingScheme & 0x0c) >> 2) { - case 0x01: - encoding = android.telephony.SmsMessage.ENCODING_8BIT; - break; - - case 0x02: - encoding = android.telephony.SmsMessage.ENCODING_16BIT; - break; - - case 0x00: - default: - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - break; - } - break; - - case 0x06: - case 0x07: - // Compression not supported - case 0x09: - // UDH structure not supported - case 0x0e: - // Defined by the WAP forum not supported - throw new IllegalArgumentException("Unsupported GSM dataCodingScheme " - + dataCodingScheme); - - case 0x0f: - if (((dataCodingScheme & 0x04) >> 2) == 0x01) { - encoding = android.telephony.SmsMessage.ENCODING_8BIT; - } else { - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - } - break; - - default: - // Reserved values are to be treated as 7-bit - encoding = android.telephony.SmsMessage.ENCODING_7BIT; - break; - } - - if (header.isUmtsFormat()) { - // Payload may contain multiple pages - int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH]; - - if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) - * nrPages) { - throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match " - + nrPages + " pages"); - } - - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < nrPages; i++) { - // Each page is 82 bytes followed by a length octet indicating - // the number of useful octets within those 82 - int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i; - int length = pdu[offset + PDU_BODY_PAGE_LENGTH]; - - if (length > PDU_BODY_PAGE_LENGTH) { - throw new IllegalArgumentException("Page length " + length - + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH); - } - - Pair p = unpackBody(pdu, encoding, offset, length, - hasLanguageIndicator, language); - language = p.first; - sb.append(p.second); - } - return new Pair(language, sb.toString()); - } else { - // Payload is one single page - int offset = SmsCbHeader.PDU_HEADER_LENGTH; - int length = pdu.length - offset; - - return unpackBody(pdu, encoding, offset, length, hasLanguageIndicator, language); - } - } - - /** - * Unpack body text from the pdu using the given encoding, position and - * length within the pdu - * - * @param pdu The pdu - * @param encoding The encoding, as derived from the DCS - * @param offset Position of the first byte to unpack - * @param length Number of bytes to unpack - * @param hasLanguageIndicator true if the body text is preceded by a - * language indicator. If so, this method will as a side-effect - * assign the extracted language code into mLanguage - * @param language the language to return if hasLanguageIndicator is false - * @return a Pair of Strings containing the language and body of the message - */ - private static Pair unpackBody(byte[] pdu, int encoding, int offset, int length, - boolean hasLanguageIndicator, String language) { - String body = null; - - switch (encoding) { - case android.telephony.SmsMessage.ENCODING_7BIT: - body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7); - - if (hasLanguageIndicator && body != null && body.length() > 2) { - // Language is two GSM characters followed by a CR. - // The actual body text is offset by 3 characters. - language = body.substring(0, 2); - body = body.substring(3); - } - break; - - case android.telephony.SmsMessage.ENCODING_16BIT: - if (hasLanguageIndicator && pdu.length >= offset + 2) { - // Language is two GSM characters. - // The actual body text is offset by 2 bytes. - language = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2); - offset += 2; - length -= 2; - } - - try { - body = new String(pdu, offset, (length & 0xfffe), "utf-16"); - } catch (UnsupportedEncodingException e) { - // Apparently it wasn't valid UTF-16. - throw new IllegalArgumentException("Error decoding UTF-16 message", e); - } - break; - - default: - break; - } - - if (body != null) { - // Remove trailing carriage return - for (int i = body.length() - 1; i >= 0; i--) { - if (body.charAt(i) != CARRIAGE_RETURN) { - body = body.substring(0, i + 1); - break; - } - } - } else { - body = ""; - } - - return new Pair(language, body); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java deleted file mode 100644 index dcc9cfdd6a75..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccCardApplication; -import com.android.internal.telephony.IccConstants; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.PhoneBase; - -/** - * {@hide} - */ -public final class SIMFileHandler extends IccFileHandler implements IccConstants { - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - //***** Constructor - - public SIMFileHandler(IccCard card, String aid, CommandsInterface ci) { - super(card, aid, ci); - } - - protected void finalize() { - Log.d(LOG_TAG, "SIMFileHandler finalized"); - } - - //***** Overridden from IccFileHandler - - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - } - - protected String getEFPath(int efid) { - // TODO(): DF_GSM can be 7F20 or 7F21 to handle backward compatibility. - // Implement this after discussion with OEMs. - switch(efid) { - case EF_SMS: - return MF_SIM + DF_TELECOM; - - case EF_EXT6: - case EF_MWIS: - case EF_MBI: - case EF_SPN: - case EF_AD: - case EF_MBDN: - case EF_PNN: - case EF_SPDI: - case EF_SST: - case EF_CFIS: - return MF_SIM + DF_GSM; - - case EF_MAILBOX_CPHS: - case EF_VOICE_MAIL_INDICATOR_CPHS: - case EF_CFF_CPHS: - case EF_SPN_CPHS: - case EF_SPN_SHORT_CPHS: - case EF_INFO_CPHS: - case EF_CSP_CPHS: - return MF_SIM + DF_GSM; - - case EF_PBR: - // we only support global phonebook. - return MF_SIM + DF_TELECOM + DF_PHONEBOOK; - } - String path = getCommonIccEFPath(efid); - if (path == null) { - // The EFids in USIM phone book entries are decided by the card manufacturer. - // So if we don't match any of the cases above and if its a USIM return - // the phone book path. - if (mParentCard != null - && mParentCard.isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) { - return MF_SIM + DF_TELECOM + DF_PHONEBOOK; - } - Log.e(LOG_TAG, "Error: EF Path being returned in null"); - } - return path; - } - - protected void logd(String msg) { - Log.d(LOG_TAG, "[SIMFileHandler] " + msg); - } - - 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 deleted file mode 100755 index 52e2cafe2b73..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java +++ /dev/null @@ -1,1674 +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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; -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.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.util.Log; - -import com.android.internal.telephony.AdnRecord; -import com.android.internal.telephony.AdnRecordCache; -import com.android.internal.telephony.AdnRecordLoader; -import com.android.internal.telephony.BaseCommands; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccRecords; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.IccVmFixedException; -import com.android.internal.telephony.IccVmNotSupportedException; -import com.android.internal.telephony.MccTable; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.SmsMessageBase; -import com.android.internal.telephony.IccRefreshResponse; - -import java.util.ArrayList; - - -/** - * {@hide} - */ -public class SIMRecords extends IccRecords { - protected static final String LOG_TAG = "GSM"; - - private static final boolean CRASH_RIL = false; - - protected static final boolean DBG = true; - - // ***** Instance Variables - - VoiceMailConstants mVmConfig; - - - SpnOverride mSpnOverride; - - // ***** Cached SIM State; cleared on channel close - - private String imsi; - private boolean callForwardingEnabled; - - - /** - * States only used by getSpnFsm FSM - */ - private Get_Spn_Fsm_State spnState; - - /** CPHS service information (See CPHS 4.2 B.3.1.1) - * It will be set in onSimReady if reading GET_CPHS_INFO successfully - * mCphsInfo[0] is CPHS Phase - * mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table - */ - private byte[] mCphsInfo = null; - boolean mCspPlmnEnabled = true; - - byte[] efMWIS = null; - byte[] efCPHS_MWI =null; - byte[] mEfCff = null; - byte[] mEfCfis = null; - - - int spnDisplayCondition; - // Numeric network codes listed in TS 51.011 EF[SPDI] - ArrayList spdiNetworks = null; - - String pnnHomeName = null; - - UsimServiceTable mUsimServiceTable; - - // ***** 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 = 0xA3; - 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; - - // CPHS Service Table (See CPHS 4.2 B.3.1) - private static final int CPHS_SST_MBN_MASK = 0x30; - private static final int CPHS_SST_MBN_ENABLED = 0x30; - - // ***** Event Constants - - private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; - protected static final int EVENT_GET_IMSI_DONE = 3; - protected static final int EVENT_GET_ICCID_DONE = 4; - private static final int EVENT_GET_MBI_DONE = 5; - private static final int EVENT_GET_MBDN_DONE = 6; - private static final int EVENT_GET_MWIS_DONE = 7; - private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8; - protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM - protected static final int EVENT_GET_MSISDN_DONE = 10; - private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11; - private static final int EVENT_GET_SPN_DONE = 12; - private static final int EVENT_GET_SPDI_DONE = 13; - private static final int EVENT_UPDATE_DONE = 14; - private static final int EVENT_GET_PNN_DONE = 15; - protected 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; - private static final int EVENT_SET_MBDN_DONE = 20; - private static final int EVENT_SMS_ON_SIM = 21; - private static final int EVENT_GET_SMS_DONE = 22; - private static final int EVENT_GET_CFF_DONE = 24; - private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25; - private static final int EVENT_GET_INFO_CPHS_DONE = 26; - private static final int EVENT_SET_MSISDN_DONE = 30; - private static final int EVENT_SIM_REFRESH = 31; - private static final int EVENT_GET_CFIS_DONE = 32; - private static final int EVENT_GET_CSP_CPHS_DONE = 33; - - // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length. - - private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = { - "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032", - "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040", - "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750", - "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800", - "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808", - "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816", - "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824", - "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832", - "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840", - "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848", - "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877", - "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885", - "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914", - "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922", - "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930", - "405931", "405932" - }; - - // ***** Constructor - - public SIMRecords(IccCard card, Context c, CommandsInterface ci) { - super(card, c, ci); - - adnCache = new AdnRecordCache(mFh); - - mVmConfig = new VoiceMailConstants(); - mSpnOverride = new SpnOverride(); - - recordsRequested = false; // No load request is made till SIM ready - - // recordsToLoad is set to 0 because no requests are made yet - recordsToLoad = 0; - - mCi.registerForOffOrNotAvailable( - this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null); - mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null); - - // Start off by setting empty state - onRadioOffOrNotAvailable(); - - } - - @Override - public void dispose() { - if (DBG) log("Disposing SIMRecords " + this); - //Unregister for all events - mCi.unregisterForOffOrNotAvailable( this); - mCi.unregisterForIccRefresh(this); - mCi.unSetOnSmsOnSim(this); - super.dispose(); - } - - protected void finalize() { - if(DBG) log("finalized"); - } - - protected void onRadioOffOrNotAvailable() { - imsi = null; - msisdn = null; - voiceMailNum = null; - countVoiceMessages = 0; - mncLength = UNINITIALIZED; - iccid = null; - // -1 means no EF_SPN found; treat accordingly. - spnDisplayCondition = -1; - efMWIS = null; - efCPHS_MWI = null; - spdiNetworks = null; - pnnHomeName = null; - - adnCache.reset(); - - log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null"); - SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, null); - SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, null); - SystemProperties.set(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 - - /** - * {@inheritDoc} - */ - @Override - public String getIMSI() { - return imsi; - } - - public String getMsisdnNumber() { - return msisdn; - } - - @Override - public UsimServiceTable getUsimServiceTable() { - return mUsimServiceTable; - } - - /** - * Set subscriber number to SIM record - * - * The subscriber number is stored in EF_MSISDN (TS 51.011) - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters) - * @param number dailing nubmer (up to 20 digits) - * if the number starts with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setMsisdnNumber(String alphaTag, String number, - Message onComplete) { - - msisdn = number; - msisdnTag = alphaTag; - - if(DBG) log("Set MSISDN: " + msisdnTag + " " + /*msisdn*/ "xxxxxxx"); - - - AdnRecord adn = new AdnRecord(msisdnTag, msisdn); - - new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null, - obtainMessage(EVENT_SET_MSISDN_DONE, onComplete)); - } - - public String getMsisdnAlphaTag() { - return msisdnTag; - } - - public String getVoiceMailNumber() { - return voiceMailNum; - } - - /** - * 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 - * - * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail. - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters) - * @param voiceNumber dailing nubmer (upto 20 digits) - * if the number is start with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setVoiceMailNumber(String alphaTag, String voiceNumber, - Message onComplete) { - if (isVoiceMailFixed) { - AsyncResult.forMessage((onComplete)).exception = - new IccVmFixedException("Voicemail number is fixed by operator"); - onComplete.sendToTarget(); - return; - } - - newVoiceMailNum = voiceNumber; - newVoiceMailTag = alphaTag; - - AdnRecord adn = new AdnRecord(newVoiceMailTag, newVoiceMailNum); - - if (mailboxIndex != 0 && mailboxIndex != 0xff) { - - new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6, - mailboxIndex, null, - obtainMessage(EVENT_SET_MBDN_DONE, onComplete)); - - } else if (isCphsMailboxEnabled()) { - - new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS, - EF_EXT1, 1, null, - obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete)); - - } else { - AsyncResult.forMessage((onComplete)).exception = - new IccVmNotSupportedException("Update SIM voice mailbox error"); - onComplete.sendToTarget(); - } - } - - public String getVoiceMailAlphaTag() - { - return voiceMailTag; - } - - /** - * 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 - * messages are waiting - */ - public void - setVoiceMessageWaiting(int line, int countWaiting) { - if (line != 1) { - // only profile 1 is supported - return; - } - - // range check - if (countWaiting < 0) { - countWaiting = -1; - } else if (countWaiting > 0xff) { - // TS 23.040 9.2.3.24.2 - // "The value 255 shall be taken to mean 255 or greater" - countWaiting = 0xff; - } - - countVoiceMessages = countWaiting; - - mRecordsEventsRegistrants.notifyResult(EVENT_MWI); - - try { - if (efMWIS != null) { - // TS 51.011 10.3.45 - - // lsb of byte 0 is 'voicemail' status - efMWIS[0] = (byte)((efMWIS[0] & 0xfe) - | (countVoiceMessages == 0 ? 0 : 1)); - - // byte 1 is the number of voice messages waiting - if (countWaiting < 0) { - // The spec does not define what this should be - // if we don't know the count - efMWIS[1] = 0; - } else { - efMWIS[1] = (byte) countWaiting; - } - - mFh.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) - | (countVoiceMessages == 0 ? 0x5 : 0xa)); - - mFh.updateEFTransparent( - EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI, - obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS)); - } - } catch (ArrayIndexOutOfBoundsException ex) { - logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean getVoiceCallForwardingFlag() { - return callForwardingEnabled; - } - - /** - * {@inheritDoc} - */ - @Override - public void setVoiceCallForwardingFlag(int line, boolean enable) { - - if (line != 1) return; // only line 1 is supported - - callForwardingEnabled = enable; - - mRecordsEventsRegistrants.notifyResult(EVENT_CFI); - - try { - if (mEfCfis != null) { - // lsb is of byte 1 is voice status - if (enable) { - mEfCfis[1] |= 1; - } else { - mEfCfis[1] &= 0xfe; - } - - // TODO: Should really update other fields in EF_CFIS, eg, - // dialing number. We don't read or use it right now. - - mFh.updateEFLinearFixed( - EF_CFIS, 1, mEfCfis, null, - obtainMessage (EVENT_UPDATE_DONE, EF_CFIS)); - } - - if (mEfCff != null) { - if (enable) { - mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET) - | CFF_UNCONDITIONAL_ACTIVE); - } else { - mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET) - | CFF_UNCONDITIONAL_DEACTIVE); - } - - mFh.updateEFTransparent( - EF_CFF_CPHS, mEfCff, - obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS)); - } - } catch (ArrayIndexOutOfBoundsException ex) { - logw("Error saving call fowarding flag to SIM. " - + "Probably malformed SIM record", ex); - - } - } - - /** - * Called by STK Service when REFRESH is received. - * @param fileChanged indicates whether any files changed - * @param fileList if non-null, a list of EF files that changed - */ - public void onRefresh(boolean fileChanged, int[] fileList) { - if (fileChanged) { - // A future optimization would be to inspect fileList and - // only reload those files that we care about. For now, - // just re-fetch all SIM records that we cache. - fetchSimRecords(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public String getOperatorNumeric() { - if (imsi == null) { - log("getOperatorNumeric: IMSI == null"); - return null; - } - if (mncLength == UNINITIALIZED || mncLength == UNKNOWN) { - log("getSIMOperatorNumeric: bad mncLength"); - return null; - } - - // Length = length of MCC + length of MNC - // length of mcc = 3 (TS 23.003 Section 2.2) - return imsi.substring(0, 3 + mncLength); - } - - // ***** Overridden from Handler - public void handleMessage(Message msg) { - AsyncResult ar; - AdnRecord adn; - - byte data[]; - - boolean isRecordLoadResponse = false; - - if (mDestroyed) { - loge("Received message " + msg + "[" + msg.what + "] " + - " while being destroyed. Ignoring."); - return; - } - - try { switch (msg.what) { - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - onRadioOffOrNotAvailable(); - break; - - /* IO events */ - case EVENT_GET_IMSI_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - loge("Exception querying IMSI, Exception:" + ar.exception); - break; - } - - imsi = (String) ar.result; - - // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more - // than 15 (and usually 15). - if (imsi != null && (imsi.length() < 6 || imsi.length() > 15)) { - loge("invalid IMSI " + imsi); - imsi = null; - } - - log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx"); - - if (((mncLength == UNKNOWN) || (mncLength == 2)) && - ((imsi != null) && (imsi.length() >= 6))) { - String mccmncCode = imsi.substring(0, 6); - for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) { - if (mccmnc.equals(mccmncCode)) { - mncLength = 3; - break; - } - } - } - - if (mncLength == UNKNOWN) { - // the SIM has told us all it knows, but it didn't know the mnc length. - // guess using the mcc - try { - int mcc = Integer.parseInt(imsi.substring(0,3)); - mncLength = MccTable.smallestDigitsMccForMnc(mcc); - } catch (NumberFormatException e) { - mncLength = UNKNOWN; - loge("Corrupt IMSI!"); - } - } - - if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) { - // finally have both the imsi and the mncLength and can parse the imsi properly - MccTable.updateMccMncConfiguration(mContext, imsi.substring(0, 3 + mncLength)); - } - mParentCard.broadcastIccStateChangedIntent( - IccCard.INTENT_VALUE_ICC_IMSI, null); - break; - - case EVENT_GET_MBI_DONE: - boolean isValidMbdn; - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[]) ar.result; - - isValidMbdn = false; - if (ar.exception == null) { - // Refer TS 51.011 Section 10.3.44 for content details - log("EF_MBI: " + IccUtils.bytesToHexString(data)); - - // Voice mail record number stored first - mailboxIndex = (int)data[0] & 0xff; - - // check if dailing numbe id valid - if (mailboxIndex != 0 && mailboxIndex != 0xff) { - log("Got valid mailbox number for MBDN"); - isValidMbdn = true; - } - } - - // one more record to load - recordsToLoad += 1; - - if (isValidMbdn) { - // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED - new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6, - mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE)); - } else { - // If this EF not present, try mailbox as in CPHS standard - // CPHS (CPHS4_2.WW6) is a european standard. - new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, - EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - } - - break; - case EVENT_GET_CPHS_MAILBOX_DONE: - case EVENT_GET_MBDN_DONE: - //Resetting the voice mail number and voice mail tag to null - //as these should be updated from the data read from EF_MBDN. - //If they are not reset, incase of invalid data/exception these - //variables are retaining their previous values and are - //causing invalid voice mailbox info display to user. - voiceMailNum = null; - voiceMailTag = null; - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - - log("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... - // FIXME right now, only load line1's CPHS voice mail entry - - recordsToLoad += 1; - new AdnRecordLoader(mFh).loadFromEF( - EF_MAILBOX_CPHS, EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - } - break; - } - - adn = (AdnRecord)ar.result; - - log("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 - // FIXME should use SST to decide - // FIXME right now, only load line1's CPHS voice mail entry - recordsToLoad += 1; - new AdnRecordLoader(mFh).loadFromEF( - EF_MAILBOX_CPHS, EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - - break; - } - - voiceMailNum = adn.getNumber(); - voiceMailTag = adn.getAlphaTag(); - break; - - case EVENT_GET_MSISDN_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - log("Invalid or missing EF[MSISDN]"); - break; - } - - adn = (AdnRecord)ar.result; - - msisdn = adn.getNumber(); - msisdnTag = adn.getAlphaTag(); - - log("MSISDN: " + /*msisdn*/ "xxxxxxx"); - break; - - case EVENT_SET_MSISDN_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - - case EVENT_GET_MWIS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - log("EF_MWIS: " + IccUtils.bytesToHexString(data)); - - efMWIS = data; - - if ((data[0] & 0xff) == 0xff) { - log("Uninitialized record MWIS"); - break; - } - - // Refer TS 51.011 Section 10.3.45 for the content description - boolean voiceMailWaiting = ((data[0] & 0x01) != 0); - countVoiceMessages = data[1] & 0xff; - - if (voiceMailWaiting && countVoiceMessages == 0) { - // Unknown count = -1 - countVoiceMessages = -1; - } - - mRecordsEventsRegistrants.notifyResult(EVENT_MWI); - break; - - case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - efCPHS_MWI = data; - - // Use this data if the EF[MWIS] exists and - // has been loaded - - if (efMWIS == null) { - int indicator = (int)(data[0] & 0xf); - - // Refer CPHS4_2.WW6 B4.2.3 - if (indicator == 0xA) { - // Unknown count = -1 - countVoiceMessages = -1; - } else if (indicator == 0x5) { - countVoiceMessages = 0; - } - - mRecordsEventsRegistrants.notifyResult(EVENT_MWI); - } - break; - - case EVENT_GET_ICCID_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - iccid = IccUtils.bcdToString(data, 0, data.length); - - log("iccid: " + iccid); - - break; - - - case EVENT_GET_AD_DONE: - try { - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - log("EF_AD: " + IccUtils.bytesToHexString(data)); - - if (data.length < 3) { - log("Corrupt AD data on SIM"); - break; - } - - if (data.length == 3) { - log("MNC length not present in EF_AD"); - break; - } - - mncLength = (int)data[3] & 0xf; - - if (mncLength == 0xf) { - mncLength = UNKNOWN; - } - } finally { - if (((mncLength == UNINITIALIZED) || (mncLength == UNKNOWN) || - (mncLength == 2)) && ((imsi != null) && (imsi.length() >= 6))) { - String mccmncCode = imsi.substring(0, 6); - for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) { - if (mccmnc.equals(mccmncCode)) { - mncLength = 3; - break; - } - } - } - - if (mncLength == UNKNOWN || mncLength == UNINITIALIZED) { - if (imsi != null) { - try { - int mcc = Integer.parseInt(imsi.substring(0,3)); - - mncLength = MccTable.smallestDigitsMccForMnc(mcc); - } catch (NumberFormatException e) { - mncLength = UNKNOWN; - loge("Corrupt IMSI!"); - } - } else { - // Indicate we got this info, but it didn't contain the length. - mncLength = UNKNOWN; - - log("MNC length not present in EF_AD"); - } - } - if (imsi != null && mncLength != UNKNOWN) { - // finally have both imsi and the length of the mnc and can parse - // the imsi properly - MccTable.updateMccMncConfiguration(mContext, - imsi.substring(0, 3 + mncLength)); - } - } - break; - - case EVENT_GET_SPN_DONE: - isRecordLoadResponse = true; - ar = (AsyncResult) msg.obj; - getSpnFsm(false, ar); - break; - - case EVENT_GET_CFF_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult) msg.obj; - data = (byte[]) ar.result; - - if (ar.exception != null) { - break; - } - - log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data)); - mEfCff = data; - - if (mEfCfis == null) { - callForwardingEnabled = - ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE); - - mRecordsEventsRegistrants.notifyResult(EVENT_CFI); - } - break; - - case EVENT_GET_SPDI_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - parseEfSpdi(data); - break; - - case EVENT_UPDATE_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - logw("update failed. ", ar.exception); - } - break; - - case EVENT_GET_PNN_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - SimTlv tlv = new SimTlv(data, 0, data.length); - - for ( ; tlv.isValidObject() ; tlv.nextObject()) { - if (tlv.getTag() == TAG_FULL_NETWORK_NAME) { - pnnHomeName - = IccUtils.networkNameToString( - tlv.getData(), 0, tlv.getData().length); - break; - } - } - break; - - 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) { - loge("Error on SMS_ON_SIM with exp " - + ar.exception + " length " + index.length); - } else { - log("READ EF_SMS RECORD index=" + index[0]); - mFh.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 { - loge("Error on GET_SMS with exp " + ar.exception); - } - break; - case EVENT_GET_SST_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - mUsimServiceTable = new UsimServiceTable(data); - if (DBG) log("SST: " + mUsimServiceTable); - break; - - case EVENT_GET_INFO_CPHS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mCphsInfo = (byte[])ar.result; - - if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo)); - break; - - case EVENT_SET_MBDN_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - - if (ar.exception == null) { - voiceMailNum = newVoiceMailNum; - voiceMailTag = newVoiceMailTag; - } - - if (isCphsMailboxEnabled()) { - adn = new AdnRecord(voiceMailTag, voiceMailNum); - Message onCphsCompleted = (Message) ar.userObj; - - /* write to cphs mailbox whenever it is available but - * we only need notify caller once if both updating are - * successful. - * - * so if set_mbdn successful, notify caller here and set - * onCphsCompleted to null - */ - if (ar.exception == null && ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = null; - ((Message) ar.userObj).sendToTarget(); - - if (DBG) log("Callback with MBDN successful."); - - onCphsCompleted = null; - } - - new AdnRecordLoader(mFh). - updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null, - obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, - onCphsCompleted)); - } else { - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - } - break; - case EVENT_SET_CPHS_MAILBOX_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if(ar.exception == null) { - voiceMailNum = newVoiceMailNum; - voiceMailTag = newVoiceMailTag; - } else { - if (DBG) log("Set CPHS MailBox with exception: " - + ar.exception); - } - if (ar.userObj != null) { - if (DBG) log("Callback with CPHS MB successful."); - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - case EVENT_SIM_REFRESH: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if (DBG) log("Sim REFRESH with exception: " + ar.exception); - if (ar.exception == null) { - handleSimRefresh((IccRefreshResponse)ar.result); - } - break; - case EVENT_GET_CFIS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - log("EF_CFIS: " + IccUtils.bytesToHexString(data)); - - mEfCfis = data; - - // Refer TS 51.011 Section 10.3.46 for the content description - callForwardingEnabled = ((data[1] & 0x01) != 0); - - mRecordsEventsRegistrants.notifyResult(EVENT_CFI); - break; - - case EVENT_GET_CSP_CPHS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - loge("Exception in fetching EF_CSP data " + ar.exception); - break; - } - - data = (byte[])ar.result; - - log("EF_CSP: " + IccUtils.bytesToHexString(data)); - handleEfCspData(data); - break; - - default: - super.handleMessage(msg); // IccRecords handles generic record load responses - - }}catch (RuntimeException exc) { - // I don't want these exceptions to be fatal - logw("Exception parsing SIM record", exc); - } finally { - // Count up record load responses even if they are fails - if (isRecordLoadResponse) { - onRecordLoaded(); - } - } - } - - private void handleFileUpdate(int efid) { - switch(efid) { - case EF_MBDN: - recordsToLoad++; - new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6, - mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE)); - break; - case EF_MAILBOX_CPHS: - recordsToLoad++; - new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1, - 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - break; - case EF_CSP_CPHS: - recordsToLoad++; - log("[CSP] SIM Refresh for EF_CSP_CPHS"); - mFh.loadEFTransparent(EF_CSP_CPHS, - obtainMessage(EVENT_GET_CSP_CPHS_DONE)); - break; - default: - // For now, fetch all records if this is not a - // voicemail number. - // TODO: Handle other cases, instead of fetching all. - adnCache.reset(); - fetchSimRecords(); - break; - } - } - - private void handleSimRefresh(IccRefreshResponse refreshResponse){ - if (refreshResponse == null) { - if (DBG) log("handleSimRefresh received without input"); - return; - } - - if (refreshResponse.aid != null && - !refreshResponse.aid.equals(mParentCard.getAid())) { - // This is for different app. Ignore. - return; - } - - switch (refreshResponse.refreshResult) { - case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE: - if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED"); - handleFileUpdate(refreshResponse.efId); - break; - case IccRefreshResponse.REFRESH_RESULT_INIT: - if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT"); - // need to reload all files (that we care about) - adnCache.reset(); - fetchSimRecords(); - break; - case IccRefreshResponse.REFRESH_RESULT_RESET: - if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET"); - mCi.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 - if (DBG) log("handleSimRefresh with unknown operation"); - break; - } - } - - /** - * Dispatch 3GPP format message. Overridden for CDMA/LTE phones by - * {@link com.android.internal.telephony.cdma.CdmaLteUiccRecords} - * to send messages to the secondary 3GPP format SMS dispatcher. - */ - protected int dispatchGsmMessage(SmsMessageBase message) { - mNewSmsRegistrants.notifyResult(message); - return 0; - } - - private void handleSms(byte[] ba) { - if (ba[0] != 0) - Log.d("ENF", "status : " + ba[0]); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 3 == "received by MS from network; message to be read" - if (ba[0] == 3) { - int n = ba.length; - - // Note: Data may include trailing FF's. That's OK; message - // should still parse correctly. - byte[] pdu = new byte[n - 1]; - System.arraycopy(ba, 1, pdu, 0, n - 1); - SmsMessage message = SmsMessage.createFromPdu(pdu); - - dispatchGsmMessage(message); - } - } - - - private void handleSmses(ArrayList messages) { - int count = messages.size(); - - for (int i = 0; i < count; i++) { - byte[] ba = (byte[]) messages.get(i); - - if (ba[0] != 0) - Log.i("ENF", "status " + i + ": " + ba[0]); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 3 == "received by MS from network; message to be read" - - if (ba[0] == 3) { - int n = ba.length; - - // Note: Data may include trailing FF's. That's OK; message - // should still parse correctly. - byte[] pdu = new byte[n - 1]; - System.arraycopy(ba, 1, pdu, 0, n - 1); - SmsMessage message = SmsMessage.createFromPdu(pdu); - - dispatchGsmMessage(message); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 1 == "received by MS from network; message read" - - ba[0] = 1; - - if (false) { // XXX writing seems to crash RdoServD - mFh.updateEFLinearFixed(EF_SMS, - i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i)); - } - } - } - } - - protected void onRecordLoaded() { - // One record loaded successfully or failed, In either case - // we need to update the recordsToLoad count - recordsToLoad -= 1; - if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested); - - if (recordsToLoad == 0 && recordsRequested == true) { - onAllRecordsLoaded(); - } else if (recordsToLoad < 0) { - loge("recordsToLoad <0, programmer error suspected"); - recordsToLoad = 0; - } - } - - protected void onAllRecordsLoaded() { - String operator = getOperatorNumeric(); - - // Some fields require more than one SIM record to set - - log("SIMRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" + - operator + "'"); - SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator); - - if (imsi != null) { - SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, - MccTable.countryCodeForMcc(Integer.parseInt(imsi.substring(0,3)))); - } - else { - loge("onAllRecordsLoaded: imsi is NULL!"); - } - - setVoiceMailByCountry(operator); - setSpnFromConfig(operator); - - recordsLoadedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - mParentCard.broadcastIccStateChangedIntent( - IccCard.INTENT_VALUE_ICC_LOADED, null); - } - - //***** Private methods - - private void setSpnFromConfig(String carrier) { - if (mSpnOverride.containsCarrier(carrier)) { - spn = mSpnOverride.getSpn(carrier); - } - } - - - private void setVoiceMailByCountry (String spn) { - if (mVmConfig.containsCarrier(spn)) { - isVoiceMailFixed = true; - voiceMailNum = mVmConfig.getVoiceMailNumber(spn); - voiceMailTag = mVmConfig.getVoiceMailTag(spn); - } - } - - @Override - public void onReady() { - /* broadcast intent SIM_READY here so that we can make sure - READY is sent before IMSI ready - */ - mParentCard.broadcastIccStateChangedIntent( - IccCard.INTENT_VALUE_ICC_READY, null); - - fetchSimRecords(); - } - - protected void fetchSimRecords() { - recordsRequested = true; - - if (DBG) log("fetchSimRecords " + recordsToLoad); - - mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE)); - recordsToLoad++; - - // FIXME should examine EF[MSISDN]'s capability configuration - // to determine which is the voice/data/fax line - new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1, - obtainMessage(EVENT_GET_MSISDN_DONE)); - recordsToLoad++; - - // Record number is subscriber profile - mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE)); - recordsToLoad++; - - // Record number is subscriber profile - mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE)); - recordsToLoad++; - - - // Also load CPHS-style voice mail indicator, which stores - // 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] - mFh.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. - mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE)); - recordsToLoad++; - mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE)); - recordsToLoad++; - - - getSpnFsm(true, null); - - mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE)); - recordsToLoad++; - - mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE)); - recordsToLoad++; - - mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE)); - recordsToLoad++; - - // XXX should seek instead of examining them all - if (false) { // XXX - mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE)); - recordsToLoad++; - } - - if (CRASH_RIL) { - String sms = "0107912160130310f20404d0110041007030208054832b0120" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "ffffffffffffffffffffffffffffff"; - byte[] ba = IccUtils.hexStringToBytes(sms); - - mFh.updateEFLinearFixed(EF_SMS, 1, ba, null, - obtainMessage(EVENT_MARK_SMS_READ_DONE, 1)); - } - if (DBG) log("fetchSimRecords " + recordsToLoad + " requested: " + recordsRequested); - } - - /** - * Returns the SpnDisplayRule based on settings on the SIM and the - * specified plmn (currently-registered PLMN). See TS 22.101 Annex A - * and TS 51.011 10.3.11 for details. - * - * If the SPN is not found on the SIM, the rule is always PLMN_ONLY. - */ - @Override - public int getDisplayRule(String plmn) { - int rule; - if (spn == null || spnDisplayCondition == -1) { - // EF_SPN was not found on the SIM, or not yet loaded. Just show ONS. - rule = SPN_RULE_SHOW_PLMN; - } else if (isOnMatchingPlmn(plmn)) { - rule = SPN_RULE_SHOW_SPN; - if ((spnDisplayCondition & 0x01) == 0x01) { - // ONS required when registered to HPLMN or PLMN in EF_SPDI - rule |= SPN_RULE_SHOW_PLMN; - } - } else { - rule = SPN_RULE_SHOW_PLMN; - if ((spnDisplayCondition & 0x02) == 0x00) { - // SPN required if not registered to HPLMN or PLMN in EF_SPDI - rule |= SPN_RULE_SHOW_SPN; - } - } - return rule; - } - - /** - * Checks if plmn is HPLMN or on the spdiNetworks list. - */ - private boolean isOnMatchingPlmn(String plmn) { - if (plmn == null) return false; - - if (plmn.equals(getOperatorNumeric())) { - return true; - } - - if (spdiNetworks != null) { - for (String spdiNet : spdiNetworks) { - if (plmn.equals(spdiNet)) { - return true; - } - } - } - return false; - } - - /** - * States of Get SPN Finite State Machine which only used by getSpnFsm() - */ - private enum Get_Spn_Fsm_State { - IDLE, // No initialized - INIT, // Start FSM - READ_SPN_3GPP, // Load EF_SPN firstly - READ_SPN_CPHS, // Load EF_SPN_CPHS secondly - READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last - } - - /** - * Finite State Machine to load Service Provider Name , which can be stored - * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2) - * - * After starting, FSM will search SPN EFs in order and stop after finding - * the first valid SPN - * - * If the FSM gets restart while waiting for one of - * SPN EFs results (i.e. a SIM refresh occurs after issuing - * read EF_CPHS_SPN), it will re-initialize only after - * receiving and discarding the unfinished SPN EF result. - * - * @param start set true only for initialize loading - * @param ar the AsyncResult from loadEFTransparent - * ar.exception holds exception in error - * ar.result is byte[] for data in success - */ - private void getSpnFsm(boolean start, AsyncResult ar) { - byte[] data; - - if (start) { - // Check previous state to see if there is outstanding - // SPN read - if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP || - spnState == Get_Spn_Fsm_State.READ_SPN_CPHS || - spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS || - spnState == Get_Spn_Fsm_State.INIT) { - // Set INIT then return so the INIT code - // will run when the outstanding read done. - spnState = Get_Spn_Fsm_State.INIT; - return; - } else { - spnState = Get_Spn_Fsm_State.INIT; - } - } - - switch(spnState){ - case INIT: - spn = null; - - mFh.loadEFTransparent(EF_SPN, - obtainMessage(EVENT_GET_SPN_DONE)); - recordsToLoad++; - - spnState = Get_Spn_Fsm_State.READ_SPN_3GPP; - break; - case READ_SPN_3GPP: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spnDisplayCondition = 0xff & data[0]; - spn = IccUtils.adnStringFieldToString(data, 1, data.length - 1); - - if (DBG) log("Load EF_SPN: " + spn - + " spnDisplayCondition: " + spnDisplayCondition); - SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn); - - spnState = Get_Spn_Fsm_State.IDLE; - } else { - mFh.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; - } - break; - case READ_SPN_CPHS: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spn = IccUtils.adnStringFieldToString( - data, 0, data.length - 1 ); - - if (DBG) log("Load EF_SPN_CPHS: " + spn); - SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn); - - spnState = Get_Spn_Fsm_State.IDLE; - } else { - mFh.loadEFTransparent( - EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE)); - recordsToLoad++; - - spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS; - } - break; - case READ_SPN_SHORT_CPHS: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spn = IccUtils.adnStringFieldToString( - data, 0, data.length - 1); - - if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn); - SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn); - }else { - if (DBG) log("No SPN loaded in either CHPS or 3GPP"); - } - - spnState = Get_Spn_Fsm_State.IDLE; - break; - default: - spnState = Get_Spn_Fsm_State.IDLE; - } - } - - /** - * Parse TS 51.011 EF[SPDI] record - * This record contains the list of numeric network IDs that - * are treated specially when determining SPN display - */ - private void - parseEfSpdi(byte[] data) { - SimTlv tlv = new SimTlv(data, 0, data.length); - - byte[] plmnEntries = null; - - for ( ; tlv.isValidObject() ; tlv.nextObject()) { - // Skip SPDI tag, if existant - if (tlv.getTag() == TAG_SPDI) { - tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length); - } - // There should only be one TAG_SPDI_PLMN_LIST - if (tlv.getTag() == TAG_SPDI_PLMN_LIST) { - plmnEntries = tlv.getData(); - break; - } - } - - if (plmnEntries == null) { - return; - } - - spdiNetworks = new ArrayList(plmnEntries.length / 3); - - for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) { - String plmnCode; - plmnCode = IccUtils.bcdToString(plmnEntries, i, 3); - - // Valid operator codes are 5 or 6 digits - if (plmnCode.length() >= 5) { - log("EF_SPDI network: " + plmnCode); - spdiNetworks.add(plmnCode); - } - } - } - - /** - * check to see if Mailbox Number is allocated and activated in CPHS SST - */ - private boolean isCphsMailboxEnabled() { - if (mCphsInfo == null) return false; - return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED ); - } - - protected void log(String s) { - Log.d(LOG_TAG, "[SIMRecords] " + s); - } - - protected void loge(String s) { - Log.e(LOG_TAG, "[SIMRecords] " + s); - } - - protected void logw(String s, Throwable tr) { - Log.w(LOG_TAG, "[SIMRecords] " + s, tr); - } - - protected void logv(String s) { - Log.v(LOG_TAG, "[SIMRecords] " + s); - } - - /** - * Return true if "Restriction of menu options for manual PLMN selection" - * bit is set or EF_CSP data is unavailable, return false otherwise. - */ - public boolean isCspPlmnEnabled() { - return mCspPlmnEnabled; - } - - /** - * Parse EF_CSP data and check if - * "Restriction of menu options for manual PLMN selection" is - * Enabled/Disabled - * - * @param data EF_CSP hex data. - */ - private void handleEfCspData(byte[] data) { - // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined - // 18 bytes (i.e 9 service groups info) and additional data specific to - // operator. The valueAddedServicesGroup is not part of standard - // services. This is operator specific and can be programmed any where. - // Normally this is programmed as 10th service after the standard - // services. - int usedCspGroups = data.length / 2; - // This is the "Servive Group Number" of "Value Added Services Group". - byte valueAddedServicesGroup = (byte)0xC0; - - mCspPlmnEnabled = true; - for (int i = 0; i < usedCspGroups; i++) { - if (data[2 * i] == valueAddedServicesGroup) { - log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]); - if ((data[(2 * i) + 1] & 0x80) == 0x80) { - // Bit 8 is for - // "Restriction of menu options for manual PLMN selection". - // Operator Selection menu should be enabled. - mCspPlmnEnabled = true; - } else { - mCspPlmnEnabled = false; - // Operator Selection menu should be disabled. - // Operator Selection Mode should be set to Automatic. - log("[CSP] Set Automatic Network Selection"); - mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants(); - } - return; - } - } - - log("[CSP] Value Added Service Group (0xC0), not found!"); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java deleted file mode 100644 index 35ba0d112e1e..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -** 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.gsm; - -import java.util.concurrent.atomic.AtomicBoolean; - -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.IccPhoneBookInterfaceManager; - -/** - * SimPhoneBookInterfaceManager to provide an inter-process communication to - * access ADN-like SIM records. - */ - - -public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager { - static final String LOG_TAG = "GSM"; - - public SimPhoneBookInterfaceManager(GSMPhone phone) { - super(phone); - adnCache = phone.mIccRecords.getAdnCache(); - //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy - } - - public void dispose() { - super.dispose(); - } - - protected void finalize() { - try { - super.finalize(); - } catch (Throwable throwable) { - Log.e(LOG_TAG, "Error while finalizing:", throwable); - } - if(DBG) Log.d(LOG_TAG, "SimPhoneBookInterfaceManager finalized"); - } - - public int[] getAdnRecordsSize(int efid) { - if (DBG) logd("getAdnRecordsSize: efid=" + efid); - synchronized(mLock) { - checkThread(); - recordSize = new int[3]; - - //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling - AtomicBoolean status = new AtomicBoolean(false); - Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status); - - phone.getIccFileHandler().getEFLinearRecordSize(efid, response); - waitForResult(status); - } - - return recordSize; - } - - 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 deleted file mode 100644 index 92bf390361a6..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java +++ /dev/null @@ -1,365 +0,0 @@ -/* -** 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.gsm; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.AsyncResult; -import android.os.Binder; -import android.os.Handler; -import android.os.Message; -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.IntRangeManager; -import com.android.internal.telephony.SMSDispatcher; -import com.android.internal.telephony.SmsRawData; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; - -/** - * SimSmsInterfaceManager to provide an inter-process communication to - * access Sms in Sim. - */ -public class SimSmsInterfaceManager extends IccSmsInterfaceManager { - static final String LOG_TAG = "GSM"; - static final boolean DBG = true; - - private final Object mLock = new Object(); - private boolean mSuccess; - private List mSms; - private HashMap> mCellBroadcastSubscriptions = - new HashMap>(); - - private CellBroadcastRangeManager mCellBroadcastRangeManager = - new CellBroadcastRangeManager(); - - private static final int EVENT_LOAD_DONE = 1; - private static final int EVENT_UPDATE_DONE = 2; - private static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3; - private static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4; - private static final int SMS_CB_CODE_SCHEME_MIN = 0; - private static final int SMS_CB_CODE_SCHEME_MAX = 255; - - Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_UPDATE_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - mSuccess = (ar.exception == null); - mLock.notifyAll(); - } - break; - case EVENT_LOAD_DONE: - ar = (AsyncResult)msg.obj; - synchronized (mLock) { - if (ar.exception == null) { - mSms = buildValidRawData((ArrayList) ar.result); - } else { - if(DBG) log("Cannot load Sms records"); - if (mSms != null) - mSms.clear(); - } - mLock.notifyAll(); - } - break; - case EVENT_SET_BROADCAST_ACTIVATION_DONE: - case EVENT_SET_BROADCAST_CONFIG_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - mSuccess = (ar.exception == null); - mLock.notifyAll(); - } - break; - } - } - }; - - public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) { - super(phone); - mDispatcher = dispatcher; - } - - public void dispose() { - } - - @Override - protected void finalize() { - try { - super.finalize(); - } catch (Throwable throwable) { - Log.e(LOG_TAG, "Error while finalizing:", throwable); - } - 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_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 - updateMessageOnIccEf(int index, int status, byte[] pdu) { - if (DBG) log("updateMessageOnIccEf: index=" + index + - " status=" + status + " ==> " + - "("+ Arrays.toString(pdu) + ")"); - enforceReceiveAndSend("Updating message on SIM"); - synchronized(mLock) { - mSuccess = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - - 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); - 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 SIM. - * - * @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 copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { - if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + - "pdu=("+ Arrays.toString(pdu) + - "), smsm=(" + Arrays.toString(smsc) +")"); - enforceReceiveAndSend("Copying message to SIM"); - synchronized(mLock) { - mSuccess = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - - mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc), - 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 ICC. - * - * @return list of SmsRawData of all sms on ICC - */ - public List getAllMessagesFromIccEf() { - if (DBG) log("getAllMessagesFromEF"); - - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.RECEIVE_SMS", - "Reading messages from SIM"); - 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 SIM"); - } - } - return mSms; - } - - public boolean enableCellBroadcast(int messageIdentifier) { - return enableCellBroadcastRange(messageIdentifier, messageIdentifier); - } - - public boolean disableCellBroadcast(int messageIdentifier) { - return disableCellBroadcastRange(messageIdentifier, messageIdentifier); - } - - public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { - if (DBG) log("enableCellBroadcastRange"); - - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.RECEIVE_SMS", - "Enabling cell broadcast SMS"); - - String client = context.getPackageManager().getNameForUid( - Binder.getCallingUid()); - - if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) { - log("Failed to add cell broadcast subscription for MID range " + startMessageId - + " to " + endMessageId + " from client " + client); - return false; - } - - if (DBG) - log("Added cell broadcast subscription for MID range " + startMessageId - + " to " + endMessageId + " from client " + client); - - setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); - - return true; - } - - public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { - if (DBG) log("disableCellBroadcastRange"); - - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.RECEIVE_SMS", - "Disabling cell broadcast SMS"); - - String client = context.getPackageManager().getNameForUid( - Binder.getCallingUid()); - - if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) { - log("Failed to remove cell broadcast subscription for MID range " + startMessageId - + " to " + endMessageId + " from client " + client); - return false; - } - - if (DBG) - log("Removed cell broadcast subscription for MID range " + startMessageId - + " to " + endMessageId + " from client " + client); - - setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); - - return true; - } - - class CellBroadcastRangeManager extends IntRangeManager { - private ArrayList mConfigList = - new ArrayList(); - - /** - * Called when the list of enabled ranges has changed. This will be - * followed by zero or more calls to {@link #addRange} followed by - * a call to {@link #finishUpdate}. - */ - protected void startUpdate() { - mConfigList.clear(); - } - - /** - * Called after {@link #startUpdate} to indicate a range of enabled - * values. - * @param startId the first id included in the range - * @param endId the last id included in the range - */ - protected void addRange(int startId, int endId, boolean selected) { - mConfigList.add(new SmsBroadcastConfigInfo(startId, endId, - SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected)); - } - - /** - * Called to indicate the end of a range update started by the - * previous call to {@link #startUpdate}. - * @return true if successful, false otherwise - */ - protected boolean finishUpdate() { - if (mConfigList.isEmpty()) { - return true; - } else { - SmsBroadcastConfigInfo[] configs = - mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]); - return setCellBroadcastConfig(configs); - } - } - } - - private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) { - if (DBG) - log("Calling setGsmBroadcastConfig with " + configs.length + " configurations"); - - synchronized (mLock) { - Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE); - - mSuccess = false; - mPhone.mCM.setGsmBroadcastConfig(configs, response); - - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to set cell broadcast config"); - } - } - - return mSuccess; - } - - private boolean setCellBroadcastActivation(boolean activate) { - if (DBG) - log("Calling setCellBroadcastActivation(" + activate + ')'); - - synchronized (mLock) { - Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE); - - mSuccess = false; - mPhone.mCM.setGsmBroadcastActivation(activate, response); - - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to set cell broadcast activation"); - } - } - - return mSuccess; - } - - @Override - 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 deleted file mode 100644 index 497cf5fb7769..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java +++ /dev/null @@ -1,118 +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; - -/** - * SIM Tag-Length-Value record - * TS 102 223 Annex C - * - * {@hide} - * - */ -public class SimTlv -{ - //***** Private Instance Variables - - byte record[]; - int tlvOffset; - int tlvLength; - int curOffset; - int curDataOffset; - int curDataLength; - boolean hasValidTlvObject; - - public SimTlv(byte[] record, int offset, int length) { - this.record = record; - - this.tlvOffset = offset; - this.tlvLength = length; - curOffset = offset; - - hasValidTlvObject = parseCurrentTlvObject(); - } - - public boolean nextObject() { - if (!hasValidTlvObject) return false; - curOffset = curDataOffset + curDataLength; - hasValidTlvObject = parseCurrentTlvObject(); - return hasValidTlvObject; - } - - public boolean isValidObject() { - return hasValidTlvObject; - } - - /** - * Returns the tag for the current TLV object - * Return 0 if !isValidObject() - * 0 and 0xff are invalid tag values - * valid tags range from 1 - 0xfe - */ - public int getTag() { - if (!hasValidTlvObject) return 0; - return record[curOffset] & 0xff; - } - - /** - * Returns data associated with current TLV object - * returns null if !isValidObject() - */ - - public byte[] getData() { - if (!hasValidTlvObject) return null; - - byte[] ret = new byte[curDataLength]; - System.arraycopy(record, curDataOffset, ret, 0, curDataLength); - return ret; - } - - /** - * Updates curDataLength and curDataOffset - * @return false on invalid record, true on valid record - */ - - private boolean parseCurrentTlvObject() { - // 0x00 and 0xff are invalid tag values - - try { - if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) { - return false; - } - - if ((record[curOffset + 1] & 0xff) < 0x80) { - // one byte length 0 - 0x7f - curDataLength = record[curOffset + 1] & 0xff; - curDataOffset = curOffset + 2; - } else if ((record[curOffset + 1] & 0xff) == 0x81) { - // two byte length 0x80 - 0xff - curDataLength = record[curOffset + 2] & 0xff; - curDataOffset = curOffset + 3; - } else { - return false; - } - } catch (ArrayIndexOutOfBoundsException ex) { - return false; - } - - if (curDataLength + curDataOffset > tlvOffset + tlvLength) { - return false; - } - - return true; - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java deleted file mode 100644 index 66e7ce0783cf..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -/** - * SmsBroadcastConfigInfo defines one configuration of Cell Broadcast - * Message (CBM) to be received by the ME - * - * fromServiceId - toServiceId defines a range of CBM message identifiers - * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS - * and 9.4.4.2.2 for UMTS. All other values can be treated as empty - * CBM message ID. - * - * fromCodeScheme - toCodeScheme defines a range of CBM data coding schemes - * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS - * and 9.4.4.2.3 for UMTS. - * All other values can be treated as empty CBM data coding scheme. - * - * selected false means message types specified in {@code } - * and {@code } are not accepted, while true means accepted. - * - */ -public final class SmsBroadcastConfigInfo { - private int fromServiceId; - private int toServiceId; - private int fromCodeScheme; - private int toCodeScheme; - private boolean selected; - - /** - * Initialize the object from rssi and cid. - */ - public SmsBroadcastConfigInfo(int fromId, int toId, int fromScheme, - int toScheme, boolean selected) { - fromServiceId = fromId; - toServiceId = toId; - fromCodeScheme = fromScheme; - toCodeScheme = toScheme; - this.selected = selected; - } - - /** - * @param fromServiceId the fromServiceId to set - */ - public void setFromServiceId(int fromServiceId) { - this.fromServiceId = fromServiceId; - } - - /** - * @return the fromServiceId - */ - public int getFromServiceId() { - return fromServiceId; - } - - /** - * @param toServiceId the toServiceId to set - */ - public void setToServiceId(int toServiceId) { - this.toServiceId = toServiceId; - } - - /** - * @return the toServiceId - */ - public int getToServiceId() { - return toServiceId; - } - - /** - * @param fromCodeScheme the fromCodeScheme to set - */ - public void setFromCodeScheme(int fromCodeScheme) { - this.fromCodeScheme = fromCodeScheme; - } - - /** - * @return the fromCodeScheme - */ - public int getFromCodeScheme() { - return fromCodeScheme; - } - - /** - * @param toCodeScheme the toCodeScheme to set - */ - public void setToCodeScheme(int toCodeScheme) { - this.toCodeScheme = toCodeScheme; - } - - /** - * @return the toCodeScheme - */ - public int getToCodeScheme() { - return toCodeScheme; - } - - /** - * @param selected the selected to set - */ - public void setSelected(boolean selected) { - this.selected = selected; - } - - /** - * @return the selected - */ - public boolean isSelected() { - return selected; - } - - @Override - public String toString() { - return "SmsBroadcastConfigInfo: Id [" + - fromServiceId + ',' + toServiceId + "] Code [" + - fromCodeScheme + ',' + toCodeScheme + "] " + - (selected ? "ENABLED" : "DISABLED"); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java deleted file mode 100644 index ebb4666f91f3..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2012 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; - -/** - * Constants used in SMS Cell Broadcast messages (see 3GPP TS 23.041). This class is used by the - * boot-time broadcast channel enable and database upgrade code in CellBroadcastReceiver, so it - * is public, but should be avoided in favor of the radio technology independent constants in - * {@link android.telephony.SmsCbMessage}, {@link android.telephony.SmsCbEtwsInfo}, and - * {@link android.telephony.SmsCbCmasInfo} classes. - * - * {@hide} - */ -public class SmsCbConstants { - - /** Private constructor for utility class. */ - private SmsCbConstants() { } - - /** Start of PWS Message Identifier range (includes ETWS and CMAS). */ - public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER = 0x1100; - - /** Bitmask for messages of ETWS type (including future extensions). */ - public static final int MESSAGE_ID_ETWS_TYPE_MASK = 0xFFF8; - - /** Value for messages of ETWS type after applying {@link #MESSAGE_ID_ETWS_TYPE_MASK}. */ - public static final int MESSAGE_ID_ETWS_TYPE = 0x1100; - - /** ETWS Message Identifier for earthquake warning message. */ - public static final int MESSAGE_ID_ETWS_EARTHQUAKE_WARNING = 0x1100; - - /** ETWS Message Identifier for tsunami warning message. */ - public static final int MESSAGE_ID_ETWS_TSUNAMI_WARNING = 0x1101; - - /** ETWS Message Identifier for earthquake and tsunami combined warning message. */ - public static final int MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING = 0x1102; - - /** ETWS Message Identifier for test message. */ - public static final int MESSAGE_ID_ETWS_TEST_MESSAGE = 0x1103; - - /** ETWS Message Identifier for messages related to other emergency types. */ - public static final int MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE = 0x1104; - - /** Start of CMAS Message Identifier range. */ - public static final int MESSAGE_ID_CMAS_FIRST_IDENTIFIER = 0x1112; - - /** CMAS Message Identifier for Presidential Level alerts. */ - public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL = 0x1112; - - /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed. */ - public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED = 0x1113; - - /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely. */ - public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY = 0x1114; - - /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed. */ - public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED = 0x1115; - - /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely. */ - public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY = 0x1116; - - /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed. */ - public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED = 0x1117; - - /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely. */ - public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY = 0x1118; - - /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed. */ - public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED = 0x1119; - - /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely. */ - public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY = 0x111A; - - /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert). */ - public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY = 0x111B; - - /** CMAS Message Identifier for the Required Monthly Test. */ - public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST = 0x111C; - - /** CMAS Message Identifier for CMAS Exercise. */ - public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE = 0x111D; - - /** CMAS Message Identifier for operator defined use. */ - public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE = 0x111E; - - /** End of CMAS Message Identifier range (including future extensions). */ - public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = 0x112F; - - /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */ - public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER = 0x18FF; - - /** ETWS serial number flag to activate the popup display. */ - public static final int SERIAL_NUMBER_ETWS_ACTIVATE_POPUP = 0x1000; - - /** ETWS serial number flag to activate the emergency user alert. */ - public static final int SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT = 0x2000; - - /** ETWS warning type value for earthquake. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; - - /** ETWS warning type value for tsunami. */ - public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; - - /** ETWS warning type value for earthquake and tsunami. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; - - /** ETWS warning type value for test broadcast. */ - public static final int ETWS_WARNING_TYPE_TEST = 0x03; - - /** ETWS warning type value for other notifications. */ - public static final int ETWS_WARNING_TYPE_OTHER = 0x04; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java deleted file mode 100644 index 569204489c45..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbEtwsInfo; - -import java.util.Arrays; - -/** - * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by - * CellBroadcastReceiver test cases, but should not be used by applications. - * - * All relevant header information is now sent as a Parcelable - * {@link android.telephony.SmsCbMessage} object in the "message" extra of the - * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or - * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent. - * The raw PDU is no longer sent to SMS CB applications. - */ -class SmsCbHeader { - - /** - * Length of SMS-CB header - */ - static final int PDU_HEADER_LENGTH = 6; - - /** - * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1 - */ - static final int FORMAT_GSM = 1; - - /** - * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2 - */ - static final int FORMAT_UMTS = 2; - - /** - * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3 - */ - static final int FORMAT_ETWS_PRIMARY = 3; - - /** - * Message type value as defined in 3gpp TS 25.324, section 11.1. - */ - private static final int MESSAGE_TYPE_CBS_MESSAGE = 1; - - /** - * Length of GSM pdus - */ - private static final int PDU_LENGTH_GSM = 88; - - /** - * Maximum length of ETWS primary message GSM pdus - */ - private static final int PDU_LENGTH_ETWS = 56; - - private final int geographicalScope; - - /** The serial number combines geographical scope, message code, and update number. */ - private final int serialNumber; - - /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */ - private final int messageIdentifier; - - private final int dataCodingScheme; - - private final int pageIndex; - - private final int nrOfPages; - - private final int format; - - /** ETWS warning notification info. */ - private final SmsCbEtwsInfo mEtwsInfo; - - /** CMAS warning notification info. */ - private final SmsCbCmasInfo mCmasInfo; - - public SmsCbHeader(byte[] pdu) throws IllegalArgumentException { - if (pdu == null || pdu.length < PDU_HEADER_LENGTH) { - throw new IllegalArgumentException("Illegal PDU"); - } - - if (pdu.length <= PDU_LENGTH_ETWS) { - format = FORMAT_ETWS_PRIMARY; - geographicalScope = (pdu[0] & 0xc0) >> 6; - serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff); - messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff); - dataCodingScheme = -1; - pageIndex = -1; - nrOfPages = -1; - boolean emergencyUserAlert = (pdu[4] & 0x1) != 0; - boolean activatePopup = (pdu[5] & 0x80) != 0; - int warningType = (pdu[4] & 0xfe) >> 1; - byte[] warningSecurityInfo; - // copy the Warning-Security-Information, if present - if (pdu.length > PDU_HEADER_LENGTH) { - warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length); - } else { - warningSecurityInfo = null; - } - mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, - warningSecurityInfo); - mCmasInfo = null; - return; // skip the ETWS/CMAS initialization code for regular notifications - } else if (pdu.length <= PDU_LENGTH_GSM) { - // GSM pdus are no more than 88 bytes - format = FORMAT_GSM; - geographicalScope = (pdu[0] & 0xc0) >> 6; - serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff); - messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff); - dataCodingScheme = pdu[4] & 0xff; - - // Check for invalid page parameter - int pageIndex = (pdu[5] & 0xf0) >> 4; - int nrOfPages = pdu[5] & 0x0f; - - if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) { - pageIndex = 1; - nrOfPages = 1; - } - - this.pageIndex = pageIndex; - this.nrOfPages = nrOfPages; - } else { - // UMTS pdus are always at least 90 bytes since the payload includes - // a number-of-pages octet and also one length octet per page - format = FORMAT_UMTS; - - int messageType = pdu[0]; - - if (messageType != MESSAGE_TYPE_CBS_MESSAGE) { - throw new IllegalArgumentException("Unsupported message type " + messageType); - } - - messageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff; - geographicalScope = (pdu[3] & 0xc0) >> 6; - serialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff); - dataCodingScheme = pdu[5] & 0xff; - - // We will always consider a UMTS message as having one single page - // since there's only one instance of the header, even though the - // actual payload may contain several pages. - pageIndex = 1; - nrOfPages = 1; - } - - if (isEtwsMessage()) { - boolean emergencyUserAlert = isEtwsEmergencyUserAlert(); - boolean activatePopup = isEtwsPopupAlert(); - int warningType = getEtwsWarningType(); - mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, null); - mCmasInfo = null; - } else if (isCmasMessage()) { - int messageClass = getCmasMessageClass(); - int severity = getCmasSeverity(); - int urgency = getCmasUrgency(); - int certainty = getCmasCertainty(); - mEtwsInfo = null; - mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, - SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty); - } else { - mEtwsInfo = null; - mCmasInfo = null; - } - } - - int getGeographicalScope() { - return geographicalScope; - } - - int getSerialNumber() { - return serialNumber; - } - - int getServiceCategory() { - return messageIdentifier; - } - - int getDataCodingScheme() { - return dataCodingScheme; - } - - int getPageIndex() { - return pageIndex; - } - - int getNumberOfPages() { - return nrOfPages; - } - - SmsCbEtwsInfo getEtwsInfo() { - return mEtwsInfo; - } - - SmsCbCmasInfo getCmasInfo() { - return mCmasInfo; - } - - /** - * Return whether this broadcast is an emergency (PWS) message type. - * @return true if this message is emergency type; false otherwise - */ - boolean isEmergencyMessage() { - return messageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER - && messageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER; - } - - /** - * Return whether this broadcast is an ETWS emergency message type. - * @return true if this message is ETWS emergency type; false otherwise - */ - private boolean isEtwsMessage() { - return (messageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK) - == SmsCbConstants.MESSAGE_ID_ETWS_TYPE; - } - - /** - * Return whether this broadcast is an ETWS primary notification. - * @return true if this message is an ETWS primary notification; false otherwise - */ - boolean isEtwsPrimaryNotification() { - return format == FORMAT_ETWS_PRIMARY; - } - - /** - * Return whether this broadcast is in UMTS format. - * @return true if this message is in UMTS format; false otherwise - */ - boolean isUmtsFormat() { - return format == FORMAT_UMTS; - } - - /** - * Return whether this message is a CMAS emergency message type. - * @return true if this message is CMAS emergency type; false otherwise - */ - private boolean isCmasMessage() { - return messageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER - && messageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER; - } - - /** - * Return whether the popup alert flag is set for an ETWS warning notification. - * This method assumes that the message ID has already been checked for ETWS type. - * - * @return true if the message code indicates a popup alert should be displayed - */ - private boolean isEtwsPopupAlert() { - return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0; - } - - /** - * Return whether the emergency user alert flag is set for an ETWS warning notification. - * This method assumes that the message ID has already been checked for ETWS type. - * - * @return true if the message code indicates an emergency user alert - */ - private boolean isEtwsEmergencyUserAlert() { - return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0; - } - - /** - * Returns the warning type for an ETWS warning notification. - * This method assumes that the message ID has already been checked for ETWS type. - * - * @return the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24 - */ - private int getEtwsWarningType() { - return messageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING; - } - - /** - * Returns the message class for a CMAS warning notification. - * This method assumes that the message ID has already been checked for CMAS type. - * @return the CMAS message class as defined in {@link SmsCbCmasInfo} - */ - private int getCmasMessageClass() { - switch (messageIdentifier) { - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL: - return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY: - return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST: - return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE: - return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE: - return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE; - - default: - return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN; - } - } - - /** - * Returns the severity for a CMAS warning notification. This is only available for extreme - * and severe alerts, not for other types such as Presidential Level and AMBER alerts. - * This method assumes that the message ID has already been checked for CMAS type. - * @return the CMAS severity as defined in {@link SmsCbCmasInfo} - */ - private int getCmasSeverity() { - switch (messageIdentifier) { - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE; - - default: - return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; - } - } - - /** - * Returns the urgency for a CMAS warning notification. This is only available for extreme - * and severe alerts, not for other types such as Presidential Level and AMBER alerts. - * This method assumes that the message ID has already been checked for CMAS type. - * @return the CMAS urgency as defined in {@link SmsCbCmasInfo} - */ - private int getCmasUrgency() { - switch (messageIdentifier) { - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: - return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED; - - default: - return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; - } - } - - /** - * Returns the certainty for a CMAS warning notification. This is only available for extreme - * and severe alerts, not for other types such as Presidential Level and AMBER alerts. - * This method assumes that the message ID has already been checked for CMAS type. - * @return the CMAS certainty as defined in {@link SmsCbCmasInfo} - */ - private int getCmasCertainty() { - switch (messageIdentifier) { - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: - return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED; - - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: - case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: - return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY; - - default: - return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; - } - } - - @Override - public String toString() { - return "SmsCbHeader{GS=" + geographicalScope + ", serialNumber=0x" + - Integer.toHexString(serialNumber) + - ", messageIdentifier=0x" + Integer.toHexString(messageIdentifier) + - ", DCS=0x" + Integer.toHexString(dataCodingScheme) + - ", page " + pageIndex + " of " + nrOfPages + '}'; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java deleted file mode 100644 index da605841d4bb..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.telephony.PhoneNumberUtils; -import android.text.format.Time; -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 java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -import static android.telephony.SmsMessage.ENCODING_16BIT; -import static android.telephony.SmsMessage.ENCODING_7BIT; -import static android.telephony.SmsMessage.ENCODING_8BIT; -import static android.telephony.SmsMessage.ENCODING_KSC5601; -import static android.telephony.SmsMessage.ENCODING_UNKNOWN; -import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES; -import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER; -import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS; -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; - } - } - - /** - * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated - * by TP_PID field set to value 0x40 - */ - public boolean isTypeZero() { - return (protocolIdentifier == 0x40); - } - - /** - * 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: [<alpha>], - * - * 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 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; - } - } - - /** - * 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 = 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 SubmitPdu 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) { - return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, header, - ENCODING_UNKNOWN, 0, 0); - } - - - /** - * Get an SMS-SUBMIT PDU for a destination address and a message using the - * specified encoding. - * - * @param scAddress Service Centre address. Null means use default. - * @param encoding Encoding defined by constants in android.telephony.SmsMessage.ENCODING_* - * @param languageTable - * @param languageShiftTable - * @return a SubmitPdu 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, int encoding, - int languageTable, int languageShiftTable) { - - // Perform null parameter checks. - if (message == null || destinationAddress == null) { - return null; - } - - if (encoding == ENCODING_UNKNOWN) { - // Find the best encoding to use - TextEncodingDetails ted = calculateLength(message, false); - encoding = ted.codeUnitSize; - languageTable = ted.languageTable; - languageShiftTable = ted.languageShiftTable; - - if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) { - if (header != null) { - SmsHeader smsHeader = SmsHeader.fromByteArray(header); - if (smsHeader.languageTable != languageTable - || smsHeader.languageShiftTable != languageShiftTable) { - Log.w(LOG_TAG, "Updating language table in SMS header: " - + smsHeader.languageTable + " -> " + languageTable + ", " - + smsHeader.languageShiftTable + " -> " + languageShiftTable); - smsHeader.languageTable = languageTable; - smsHeader.languageShiftTable = languageShiftTable; - header = SmsHeader.toByteArray(smsHeader); - } - } else { - SmsHeader smsHeader = new SmsHeader(); - smsHeader.languageTable = languageTable; - smsHeader.languageShiftTable = languageShiftTable; - header = SmsHeader.toByteArray(smsHeader); - } - } - } - - 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); - - // User Data (and length) - byte[] userData; - try { - if (encoding == ENCODING_7BIT) { - userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header, - languageTable, languageShiftTable); - } else { //assume UCS-2 - try { - userData = encodeUCS2(message, header); - } catch(UnsupportedEncodingException uex) { - Log.e(LOG_TAG, - "Implausible UnsupportedEncodingException ", - uex); - return null; - } - } - } catch (EncodeException ex) { - // Encoding to the 7-bit alphabet failed. Let's see if we can - // send it as a UCS-2 encoded message - try { - userData = encodeUCS2(message, header); - encoding = ENCODING_16BIT; - } catch(UnsupportedEncodingException uex) { - Log.e(LOG_TAG, - "Implausible UnsupportedEncodingException ", - uex); - return null; - } - } - - if (encoding == ENCODING_7BIT) { - if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) { - // Message too long - Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)"); - return null; - } - // TP-Data-Coding-Scheme - // Default encoding, uncompressed - // To test writing messages to the SIM card, change this value 0x00 - // to 0x12, which means "bits 1 and 0 contain message class, and the - // class is 2". Note that this takes effect for the sender. In other - // words, messages sent by the phone with this change will end up on - // the receiver's SIM card. You can then send messages to yourself - // (on a phone with this change) and they'll end up on the SIM card. - bo.write(0x00); - } else { // assume UCS-2 - if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) { - // Message too long - Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)"); - return null; - } - // TP-Data-Coding-Scheme - // UCS-2 encoding, uncompressed - bo.write(0x08); - } - - // (no TP-Validity-Period) - bo.write(userData, 0, userData.length); - ret.encodedMessage = bo.toByteArray(); - return ret; - } - - /** - * Packs header and UCS-2 encoded message. Includes TP-UDL & TP-UDHL if necessary - * - * @return - * @throws UnsupportedEncodingException - */ - private static byte[] encodeUCS2(String message, byte[] header) - throws UnsupportedEncodingException { - byte[] userData, textPart; - textPart = message.getBytes("utf-16be"); - - if (header != null) { - // Need 1 byte for UDHL - userData = new byte[header.length + textPart.length + 1]; - - userData[0] = (byte)header.length; - System.arraycopy(header, 0, userData, 1, header.length); - System.arraycopy(textPart, 0, userData, header.length + 1, textPart.length); - } - else { - userData = textPart; - } - byte[] ret = new byte[userData.length+1]; - ret[0] = (byte) (userData.length & 0xff ); - System.arraycopy(userData, 0, ret, 1, userData.length); - 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 SubmitPdu 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 & 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 SubmitPdu containing the encoded SC - * address, if applicable, and the encoded message. - * Returns null on encode error. - */ - public static SubmitPdu getSubmitPdu(String scAddress, - String destinationAddress, int destinationPort, byte[] data, - boolean statusReportRequested) { - - SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); - portAddrs.destPort = destinationPort; - portAddrs.origPort = 0; - portAddrs.areEightBits = false; - - SmsHeader smsHeader = new SmsHeader(); - smsHeader.portAddrs = portAddrs; - - byte[] smsHeaderData = SmsHeader.toByteArray(smsHeader); - - if ((data.length + smsHeaderData.length + 1) > MAX_USER_DATA_BYTES) { - Log.e(LOG_TAG, "SMS data message may only contain " - + (MAX_USER_DATA_BYTES - smsHeaderData.length - 1) + " 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) - - // Total size - bo.write(data.length + smsHeaderData.length + 1); - - // User data header - bo.write(smsHeaderData.length); - bo.write(smsHeaderData, 0, smsHeaderData.length); - - // 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 - * String. - * - * @param scAddress Service Centre address. null == use default - * @param destinationAddress the address of the destination for the message - * @param mtiByte - * @param ret SubmitPdu 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 (false) 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; - } - - private static class PduParser { - byte pdu[]; - int cur; - SmsHeader userDataHeader; - byte[] userData; - int mUserDataSeptetPadding; - int mUserDataSize; - - 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.gsmBcdByteToInt(pdu[cur++]); - int month = IccUtils.gsmBcdByteToInt(pdu[cur++]); - int day = IccUtils.gsmBcdByteToInt(pdu[cur++]); - int hour = IccUtils.gsmBcdByteToInt(pdu[cur++]); - int minute = IccUtils.gsmBcdByteToInt(pdu[cur++]); - int second = IccUtils.gsmBcdByteToInt(pdu[cur++]); - - // For the timezone, the most significant bit of the - // least significant 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.gsmBcdByteToInt((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; - int userDataHeaderLength = 0; - - if (hasUserDataHeader) { - userDataHeaderLength = pdu[offset++] & 0xff; - - byte[] udh = new byte[userDataHeaderLength]; - System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength); - userDataHeader = SmsHeader.fromByteArray(udh); - offset += userDataHeaderLength; - - int headerBits = (userDataHeaderLength + 1) * 8; - headerSeptets = headerBits / 7; - headerSeptets += (headerBits % 7) > 0 ? 1 : 0; - mUserDataSeptetPadding = (headerSeptets * 7) - headerBits; - } - - int bufferLen; - if (dataInSeptets) { - /* - * Here we just create the user data length to be the remainder of - * the pdu minus the user data header, since userDataLength means - * the number of uncompressed septets. - */ - bufferLen = pdu.length - offset; - } else { - /* - * userDataLength is the count of octets, so just subtract the - * user data header. - */ - bufferLen = userDataLength - (hasUserDataHeader ? (userDataHeaderLength + 1) : 0); - if (bufferLen < 0) { - bufferLen = 0; - } - } - - userData = new byte[bufferLen]; - System.arraycopy(pdu, offset, userData, 0, userData.length); - cur = offset; - - if (dataInSeptets) { - // Return the number of septets - int count = userDataLength - headerSeptets; - // If count < 0, return 0 (means UDL was probably incorrect) - return count < 0 ? 0 : count; - } else { - // Return the number of octets - return userData.length; - } - } - - /** - * 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 beginning of the user data - * array before the start of the septets. - * - * @return the number of padding bits at the beginning of the user data - * array before the start of the septets - */ - int getUserDataSeptetPadding() { - return mUserDataSeptetPadding; - } - - /** - * Returns an object representing the user data headers - * - * {@hide} - */ - SmsHeader getUserDataHeader() { - return userDataHeader; - } - - /** - * Interprets the user data payload as packed 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, int languageTable, - int languageShiftTable) { - String ret; - - ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount, - mUserDataSeptetPadding, languageTable, languageShiftTable); - - 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; - } - - /** - * Interprets the user data payload as KSC-5601 characters, and - * decodes them into a String. - * - * @param byteCount the number of bytes in the user data payload - * @return a String with the decoded characters - */ - String getUserDataKSC5601(int byteCount) { - String ret; - - try { - ret = new String(pdu, cur, byteCount, "KSC5601"); - } catch (UnsupportedEncodingException ex) { - ret = ""; - Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex); - } - - cur += byteCount; - return ret; - } - - boolean moreDataPresent() { - return (pdu.length > cur); - } - } - - /** - * Calculate the number of septets needed to encode the message. - * - * @param msgBody the message to encode - * @param use7bitOnly ignore (but still count) illegal characters if true - * @return TextEncodingDetails - */ - public static TextEncodingDetails calculateLength(CharSequence msgBody, - boolean use7bitOnly) { - TextEncodingDetails ted = GsmAlphabet.countGsmSeptets(msgBody, use7bitOnly); - if (ted == null) { - ted = new TextEncodingDetails(); - int octets = msgBody.length() * 2; - ted.codeUnitCount = msgBody.length(); - if (octets > MAX_USER_DATA_BYTES) { - ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) / - MAX_USER_DATA_BYTES_WITH_HEADER; - ted.codeUnitsRemaining = ((ted.msgCount * - MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2; - } else { - ted.msgCount = 1; - ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2; - } - ted.codeUnitSize = ENCODING_16BIT; - } - return ted; - } - - /** {@inheritDoc} */ - @Override - public int getProtocolIdentifier() { - return protocolIdentifier; - } - - /** - * Returns the TP-Data-Coding-Scheme byte, for acknowledgement of SMS-PP download messages. - * @return the TP-DCS field of the SMS header - */ - int getDataCodingScheme() { - return dataCodingScheme; - } - - /** {@inheritDoc} */ - @Override - public boolean isReplace() { - return (protocolIdentifier & 0xc0) == 0x40 - && (protocolIdentifier & 0x3f) > 0 - && (protocolIdentifier & 0x3f) < 8; - } - - /** {@inheritDoc} */ - @Override - public boolean isCphsMwiMessage() { - return ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear() - || ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet(); - } - - /** {@inheritDoc} */ - @Override - public boolean isMWIClearMessage() { - if (isMwi && !mwiSense) { - return true; - } - - return originatingAddress != null - && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear(); - } - - /** {@inheritDoc} */ - @Override - public boolean isMWISetMessage() { - if (isMwi && mwiSense) { - return true; - } - - return originatingAddress != null - && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet(); - } - - /** {@inheritDoc} */ - @Override - 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} */ - @Override - public int getStatus() { - return status; - } - - /** {@inheritDoc} */ - @Override - public boolean isStatusReportMessage() { - return isStatusReportMessage; - } - - /** {@inheritDoc} */ - @Override - public boolean isReplyPathPresent() { - return replyPathPresent; - } - - /** - * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6] - * 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 - * hex number (e.g. octet with integer value 42 is presented to TE as two - * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast, - * something else... - */ - private void parsePdu(byte[] pdu) { - mPdu = pdu; - // Log.d(LOG_TAG, "raw sms message:"); - // Log.d(LOG_TAG, s); - - PduParser p = new PduParser(pdu); - - scAddress = p.getSCAddress(); - - if (scAddress != null) { - if (false) 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: - case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved. - //This should be processed in the same way as MTI == 0 (Deliver) - 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 (false) 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 (false) { - Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier - + " data coding scheme: " + dataCodingScheme); - } - - scTimeMillis = p.getSCTimestampMillis(); - - if (false) 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 if ((dataCodingScheme & 0xC0) == 0x80) { - // 3GPP TS 23.038 V7.0.0 (2006-03) section 4 - // 0x80..0xBF == Reserved coding groups - if (dataCodingScheme == 0x84) { - // This value used for KSC5601 by carriers in Korea. - encodingType = ENCODING_KSC5601; - } else { - Log.w(LOG_TAG, "5 - Unsupported SMS data coding scheme " - + (dataCodingScheme & 0xff)); - } - } else { - Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme " - + (dataCodingScheme & 0xff)); - } - - // 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, - hasUserDataHeader ? userDataHeader.languageTable : 0, - hasUserDataHeader ? userDataHeader.languageShiftTable : 0); - break; - - case ENCODING_16BIT: - messageBody = p.getUserDataUCS2(count); - break; - - case ENCODING_KSC5601: - messageBody = p.getUserDataKSC5601(count); - break; - } - - if (false) 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} - */ - @Override - public MessageClass getMessageClass() { - return messageClass; - } - - /** - * Returns true if this is a (U)SIM data download type SM. - * See 3GPP TS 31.111 section 9.1 and TS 23.040 section 9.2.3.9. - * - * @return true if this is a USIM data download message; false otherwise - */ - boolean isUsimDataDownload() { - return messageClass == MessageClass.CLASS_2 && - (protocolIdentifier == 0x7f || protocolIdentifier == 0x7c); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java deleted file mode 100644 index 918c2d2be7ae..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.os.Environment; -import android.util.Log; -import android.util.Xml; - -import com.android.internal.util.XmlUtils; - -public class SpnOverride { - private HashMap CarrierSpnMap; - - - static final String LOG_TAG = "GSM"; - static final String PARTNER_SPN_OVERRIDE_PATH ="etc/spn-conf.xml"; - - SpnOverride () { - CarrierSpnMap = new HashMap(); - loadSpnOverrides(); - } - - boolean containsCarrier(String carrier) { - return CarrierSpnMap.containsKey(carrier); - } - - String getSpn(String carrier) { - return CarrierSpnMap.get(carrier); - } - - private void loadSpnOverrides() { - FileReader spnReader; - - final File spnFile = new File(Environment.getRootDirectory(), - PARTNER_SPN_OVERRIDE_PATH); - - try { - spnReader = new FileReader(spnFile); - } catch (FileNotFoundException e) { - Log.w(LOG_TAG, "Can't open " + - Environment.getRootDirectory() + "/" + PARTNER_SPN_OVERRIDE_PATH); - return; - } - - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(spnReader); - - XmlUtils.beginDocument(parser, "spnOverrides"); - - while (true) { - XmlUtils.nextElement(parser); - - String name = parser.getName(); - if (!"spnOverride".equals(name)) { - break; - } - - String numeric = parser.getAttributeValue(null, "numeric"); - String data = parser.getAttributeValue(null, "spn"); - - CarrierSpnMap.put(numeric, data); - } - } catch (XmlPullParserException e) { - Log.w(LOG_TAG, "Exception in spn-conf parser " + e); - } catch (IOException e) { - Log.w(LOG_TAG, "Exception in spn-conf parser " + e); - } - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java deleted file mode 100644 index e68655e76d0b..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.gsm; - -import android.telephony.PhoneNumberUtils; - -/** - * Represents a Supplementary Service Notification received from the network. - * - * {@hide} - */ -public class SuppServiceNotification { - /** Type of notification: 0 = MO; 1 = MT */ - public int notificationType; - /** TS 27.007 7.17 "code1" or "code2" */ - public int code; - /** TS 27.007 7.17 "index" */ - public int index; - /** TS 27.007 7.17 "type" (MT only) */ - 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; - static public final int MO_CODE_CALL_IS_WAITING = 3; - static public final int MO_CODE_CUG_CALL = 4; - static public final int MO_CODE_OUTGOING_CALLS_BARRED = 5; - 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; - static public final int MT_CODE_CALL_RETRIEVED = 3; - static public final int MT_CODE_MULTI_PARTY_CALL = 4; - static public final int MT_CODE_ON_HOLD_CALL_RELEASED = 5; - static public final int MT_CODE_FORWARD_CHECK_RECEIVED = 6; - static public final int MT_CODE_CALL_CONNECTING_ECT = 7; - static public final int MT_CODE_CALL_CONNECTED_ECT = 8; - static public final int MT_CODE_DEFLECTED_CALL = 9; - static public final int MT_CODE_ADDITIONAL_CALL_FORWARDED = 10; - - public String toString() - { - return super.toString() + " mobile" - + (notificationType == 0 ? " originated " : " terminated ") - + " code: " + code - + " index: " + index - + " \"" - + PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" "; - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java b/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java deleted file mode 100644 index f47ff1b03012..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2011 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.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.provider.Telephony.Sms.Intents; -import android.util.Log; - -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccIoResult; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.cat.ComprehensionTlvTag; - -/** - * Handler for SMS-PP data download messages. - * See 3GPP TS 31.111 section 7.1.1 - */ -public class UsimDataDownloadHandler extends Handler { - private static final String TAG = "UsimDataDownloadHandler"; - - /** BER-TLV tag for SMS-PP download. TS 31.111 section 9.1. */ - private static final int BER_SMS_PP_DOWNLOAD_TAG = 0xd1; - - /** Device identity value for UICC (destination). */ - private static final int DEV_ID_UICC = 0x81; - - /** Device identity value for network (source). */ - private static final int DEV_ID_NETWORK = 0x83; - - /** Message containing new SMS-PP message to process. */ - private static final int EVENT_START_DATA_DOWNLOAD = 1; - - /** Response to SMS-PP download envelope command. */ - private static final int EVENT_SEND_ENVELOPE_RESPONSE = 2; - - private final CommandsInterface mCI; - - public UsimDataDownloadHandler(CommandsInterface commandsInterface) { - mCI = commandsInterface; - } - - /** - * Start an SMS-PP data download for the specified message. Can be called from a different - * thread than this Handler is running on. - * - * @param smsMessage the message to process - * @return Activity.RESULT_OK on success; Intents.RESULT_SMS_GENERIC_ERROR on failure - */ - public int startDataDownload(SmsMessage smsMessage) { - if (sendMessage(obtainMessage(EVENT_START_DATA_DOWNLOAD, smsMessage))) { - return Activity.RESULT_OK; // we will send SMS ACK/ERROR based on UICC response - } else { - Log.e(TAG, "startDataDownload failed to send message to start data download."); - return Intents.RESULT_SMS_GENERIC_ERROR; - } - } - - private void handleDataDownload(SmsMessage smsMessage) { - int dcs = smsMessage.getDataCodingScheme(); - int pid = smsMessage.getProtocolIdentifier(); - byte[] pdu = smsMessage.getPdu(); // includes SC address - - int scAddressLength = pdu[0] & 0xff; - int tpduIndex = scAddressLength + 1; // start of TPDU - int tpduLength = pdu.length - tpduIndex; - - int bodyLength = getEnvelopeBodyLength(scAddressLength, tpduLength); - - // Add 1 byte for SMS-PP download tag and 1-2 bytes for BER-TLV length. - // See ETSI TS 102 223 Annex C for encoding of length and tags. - int totalLength = bodyLength + 1 + (bodyLength > 127 ? 2 : 1); - - byte[] envelope = new byte[totalLength]; - int index = 0; - - // SMS-PP download tag and length (assumed to be < 256 bytes). - envelope[index++] = (byte) BER_SMS_PP_DOWNLOAD_TAG; - if (bodyLength > 127) { - envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length - } - envelope[index++] = (byte) bodyLength; - - // Device identities TLV - envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value()); - envelope[index++] = (byte) 2; - envelope[index++] = (byte) DEV_ID_NETWORK; - envelope[index++] = (byte) DEV_ID_UICC; - - // Address TLV (if present). Encoded length is assumed to be < 127 bytes. - if (scAddressLength != 0) { - envelope[index++] = (byte) ComprehensionTlvTag.ADDRESS.value(); - envelope[index++] = (byte) scAddressLength; - System.arraycopy(pdu, 1, envelope, index, scAddressLength); - index += scAddressLength; - } - - // SMS TPDU TLV. Length is assumed to be < 256 bytes. - envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.SMS_TPDU.value()); - if (tpduLength > 127) { - envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length - } - envelope[index++] = (byte) tpduLength; - System.arraycopy(pdu, tpduIndex, envelope, index, tpduLength); - index += tpduLength; - - // Verify that we calculated the payload size correctly. - if (index != envelope.length) { - Log.e(TAG, "startDataDownload() calculated incorrect envelope length, aborting."); - acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR); - return; - } - - String encodedEnvelope = IccUtils.bytesToHexString(envelope); - mCI.sendEnvelopeWithStatus(encodedEnvelope, obtainMessage( - EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid })); - } - - /** - * Return the size in bytes of the envelope to send to the UICC, excluding the - * SMS-PP download tag byte and length byte(s). If the size returned is <= 127, - * the BER-TLV length will be encoded in 1 byte, otherwise 2 bytes are required. - * - * @param scAddressLength the length of the SMSC address, or zero if not present - * @param tpduLength the length of the TPDU from the SMS-PP message - * @return the number of bytes to allocate for the envelope command - */ - private static int getEnvelopeBodyLength(int scAddressLength, int tpduLength) { - // Add 4 bytes for device identities TLV + 1 byte for SMS TPDU tag byte - int length = tpduLength + 5; - // Add 1 byte for TPDU length, or 2 bytes if length > 127 - length += (tpduLength > 127 ? 2 : 1); - // Add length of address tag, if present (+ 2 bytes for tag and length) - if (scAddressLength != 0) { - length = length + 2 + scAddressLength; - } - return length; - } - - /** - * Handle the response to the ENVELOPE command. - * @param response UICC response encoded as hexadecimal digits. First two bytes are the - * UICC SW1 and SW2 status bytes. - */ - private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid) { - int sw1 = response.sw1; - int sw2 = response.sw2; - - boolean success; - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - Log.d(TAG, "USIM data download succeeded: " + response.toString()); - success = true; - } else if (sw1 == 0x93 && sw2 == 0x00) { - Log.e(TAG, "USIM data download failed: Toolkit busy"); - acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY); - return; - } else if (sw1 == 0x62 || sw1 == 0x63) { - Log.e(TAG, "USIM data download failed: " + response.toString()); - success = false; - } else { - Log.e(TAG, "Unexpected SW1/SW2 response from UICC: " + response.toString()); - success = false; - } - - byte[] responseBytes = response.payload; - if (responseBytes == null || responseBytes.length == 0) { - if (success) { - mCI.acknowledgeLastIncomingGsmSms(true, 0, null); - } else { - acknowledgeSmsWithError( - CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR); - } - return; - } - - byte[] smsAckPdu; - int index = 0; - if (success) { - smsAckPdu = new byte[responseBytes.length + 5]; - smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI - smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present - } else { - smsAckPdu = new byte[responseBytes.length + 6]; - smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI - smsAckPdu[index++] = (byte) - CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR; // TP-FCS - smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present - } - - smsAckPdu[index++] = (byte) pid; - smsAckPdu[index++] = (byte) dcs; - - if (is7bitDcs(dcs)) { - int septetCount = responseBytes.length * 8 / 7; - smsAckPdu[index++] = (byte) septetCount; - } else { - smsAckPdu[index++] = (byte) responseBytes.length; - } - - System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length); - - mCI.acknowledgeIncomingGsmSmsWithPdu(success, - IccUtils.bytesToHexString(smsAckPdu), null); - } - - private void acknowledgeSmsWithError(int cause) { - mCI.acknowledgeLastIncomingGsmSms(false, cause, null); - } - - /** - * Returns whether the DCS is 7 bit. If so, set TP-UDL to the septet count of TP-UD; - * otherwise, set TP-UDL to the octet count of TP-UD. - * @param dcs the TP-Data-Coding-Scheme field from the original download SMS - * @return true if the DCS specifies 7 bit encoding; false otherwise - */ - private static boolean is7bitDcs(int dcs) { - // See 3GPP TS 23.038 section 4 - return ((dcs & 0x8C) == 0x00) || ((dcs & 0xF4) == 0xF0); - } - - /** - * Handle UICC envelope response and send SMS acknowledgement. - * - * @param msg the message to handle - */ - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_START_DATA_DOWNLOAD: - handleDataDownload((SmsMessage) msg.obj); - break; - - case EVENT_SEND_ENVELOPE_RESPONSE: - AsyncResult ar = (AsyncResult) msg.obj; - - if (ar.exception != null) { - Log.e(TAG, "UICC Send Envelope failure, exception: " + ar.exception); - acknowledgeSmsWithError( - CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR); - return; - } - - int[] dcsPid = (int[]) ar.userObj; - sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, dcsPid[0], dcsPid[1]); - break; - - default: - Log.e(TAG, "Ignoring unexpected message, what=" + msg.what); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java deleted file mode 100755 index 8f5a4203ff62..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.AdnRecord; -import com.android.internal.telephony.AdnRecordCache; -import com.android.internal.telephony.IccConstants; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.PhoneBase; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -/** - * This class implements reading and parsing USIM records. - * Refer to Spec 3GPP TS 31.102 for more details. - * - * {@hide} - */ -public class UsimPhoneBookManager extends Handler implements IccConstants { - private static final String LOG_TAG = "GSM"; - private static final boolean DBG = true; - private PbrFile mPbrFile; - private Boolean mIsPbrPresent; - private IccFileHandler mFh; - private AdnRecordCache mAdnCache; - private Object mLock = new Object(); - private ArrayList mPhoneBookRecords; - private boolean mEmailPresentInIap = false; - private int mEmailTagNumberInIap = 0; - private ArrayList mIapFileRecord; - private ArrayList mEmailFileRecord; - private Map> mEmailsForAdnRec; - private boolean mRefreshCache = false; - - private static final int EVENT_PBR_LOAD_DONE = 1; - private static final int EVENT_USIM_ADN_LOAD_DONE = 2; - private static final int EVENT_IAP_LOAD_DONE = 3; - private static final int EVENT_EMAIL_LOAD_DONE = 4; - - private static final int USIM_TYPE1_TAG = 0xA8; - private static final int USIM_TYPE2_TAG = 0xA9; - private static final int USIM_TYPE3_TAG = 0xAA; - private static final int USIM_EFADN_TAG = 0xC0; - private static final int USIM_EFIAP_TAG = 0xC1; - private static final int USIM_EFEXT1_TAG = 0xC2; - private static final int USIM_EFSNE_TAG = 0xC3; - private static final int USIM_EFANR_TAG = 0xC4; - private static final int USIM_EFPBC_TAG = 0xC5; - private static final int USIM_EFGRP_TAG = 0xC6; - private static final int USIM_EFAAS_TAG = 0xC7; - private static final int USIM_EFGSD_TAG = 0xC8; - private static final int USIM_EFUID_TAG = 0xC9; - private static final int USIM_EFEMAIL_TAG = 0xCA; - private static final int USIM_EFCCP1_TAG = 0xCB; - - public UsimPhoneBookManager(IccFileHandler fh, AdnRecordCache cache) { - mFh = fh; - mPhoneBookRecords = new ArrayList(); - mPbrFile = null; - // We assume its present, after the first read this is updated. - // So we don't have to read from UICC if its not present on subsequent reads. - mIsPbrPresent = true; - mAdnCache = cache; - } - - public void reset() { - mPhoneBookRecords.clear(); - mIapFileRecord = null; - mEmailFileRecord = null; - mPbrFile = null; - mIsPbrPresent = true; - mRefreshCache = false; - } - - public ArrayList loadEfFilesFromUsim() { - synchronized (mLock) { - if (!mPhoneBookRecords.isEmpty()) { - if (mRefreshCache) { - mRefreshCache = false; - refreshCache(); - } - return mPhoneBookRecords; - } - - if (!mIsPbrPresent) return null; - - // Check if the PBR file is present in the cache, if not read it - // from the USIM. - if (mPbrFile == null) { - readPbrFileAndWait(); - } - - if (mPbrFile == null) return null; - - int numRecs = mPbrFile.mFileIds.size(); - for (int i = 0; i < numRecs; i++) { - readAdnFileAndWait(i); - readEmailFileAndWait(i); - } - // All EF files are loaded, post the response. - } - return mPhoneBookRecords; - } - - private void refreshCache() { - if (mPbrFile == null) return; - mPhoneBookRecords.clear(); - - int numRecs = mPbrFile.mFileIds.size(); - for (int i = 0; i < numRecs; i++) { - readAdnFileAndWait(i); - } - } - - public void invalidateCache() { - mRefreshCache = true; - } - - private void readPbrFileAndWait() { - mFh.loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE)); - try { - mLock.wait(); - } catch (InterruptedException e) { - Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait"); - } - } - - private void readEmailFileAndWait(int recNum) { - Map fileIds; - fileIds = mPbrFile.mFileIds.get(recNum); - if (fileIds == null) return; - - if (fileIds.containsKey(USIM_EFEMAIL_TAG)) { - int efid = fileIds.get(USIM_EFEMAIL_TAG); - // Check if the EFEmail is a Type 1 file or a type 2 file. - // If mEmailPresentInIap is true, its a type 2 file. - // So we read the IAP file and then read the email records. - // instead of reading directly. - if (mEmailPresentInIap) { - readIapFileAndWait(fileIds.get(USIM_EFIAP_TAG)); - if (mIapFileRecord == null) { - Log.e(LOG_TAG, "Error: IAP file is empty"); - return; - } - } - // Read the EFEmail file. - mFh.loadEFLinearFixedAll(fileIds.get(USIM_EFEMAIL_TAG), - obtainMessage(EVENT_EMAIL_LOAD_DONE)); - try { - mLock.wait(); - } catch (InterruptedException e) { - Log.e(LOG_TAG, "Interrupted Exception in readEmailFileAndWait"); - } - - if (mEmailFileRecord == null) { - Log.e(LOG_TAG, "Error: Email file is empty"); - return; - } - updatePhoneAdnRecord(); - } - - } - - private void readIapFileAndWait(int efid) { - mFh.loadEFLinearFixedAll(efid, obtainMessage(EVENT_IAP_LOAD_DONE)); - try { - mLock.wait(); - } catch (InterruptedException e) { - Log.e(LOG_TAG, "Interrupted Exception in readIapFileAndWait"); - } - } - - private void updatePhoneAdnRecord() { - if (mEmailFileRecord == null) return; - int numAdnRecs = mPhoneBookRecords.size(); - if (mIapFileRecord != null) { - // The number of records in the IAP file is same as the number of records in ADN file. - // The order of the pointers in an EFIAP shall be the same as the order of file IDs - // that appear in the TLV object indicated by Tag 'A9' in the reference file record. - // i.e value of mEmailTagNumberInIap - - for (int i = 0; i < numAdnRecs; i++) { - byte[] record = null; - try { - record = mIapFileRecord.get(i); - } catch (IndexOutOfBoundsException e) { - Log.e(LOG_TAG, "Error: Improper ICC card: No IAP record for ADN, continuing"); - break; - } - int recNum = record[mEmailTagNumberInIap]; - - if (recNum != -1) { - String[] emails = new String[1]; - // SIM record numbers are 1 based - emails[0] = readEmailRecord(recNum - 1); - AdnRecord rec = mPhoneBookRecords.get(i); - if (rec != null) { - rec.setEmails(emails); - } else { - // might be a record with only email - rec = new AdnRecord("", "", emails); - } - mPhoneBookRecords.set(i, rec); - } - } - } - - // ICC cards can be made such that they have an IAP file but all - // records are empty. So we read both type 1 and type 2 file - // email records, just to be sure. - - int len = mPhoneBookRecords.size(); - // Type 1 file, the number of records is the same as the number of - // records in the ADN file. - if (mEmailsForAdnRec == null) { - parseType1EmailFile(len); - } - for (int i = 0; i < numAdnRecs; i++) { - ArrayList emailList = null; - try { - emailList = mEmailsForAdnRec.get(i); - } catch (IndexOutOfBoundsException e) { - break; - } - if (emailList == null) continue; - - AdnRecord rec = mPhoneBookRecords.get(i); - - String[] emails = new String[emailList.size()]; - System.arraycopy(emailList.toArray(), 0, emails, 0, emailList.size()); - rec.setEmails(emails); - mPhoneBookRecords.set(i, rec); - } - } - - void parseType1EmailFile(int numRecs) { - mEmailsForAdnRec = new HashMap>(); - byte[] emailRec = null; - for (int i = 0; i < numRecs; i++) { - try { - emailRec = mEmailFileRecord.get(i); - } catch (IndexOutOfBoundsException e) { - Log.e(LOG_TAG, "Error: Improper ICC card: No email record for ADN, continuing"); - break; - } - int adnRecNum = emailRec[emailRec.length - 1]; - - if (adnRecNum == -1) { - continue; - } - - String email = readEmailRecord(i); - - if (email == null || email.equals("")) { - continue; - } - - // SIM record numbers are 1 based. - ArrayList val = mEmailsForAdnRec.get(adnRecNum - 1); - if (val == null) { - val = new ArrayList(); - } - val.add(email); - // SIM record numbers are 1 based. - mEmailsForAdnRec.put(adnRecNum - 1, val); - } - } - - private String readEmailRecord(int recNum) { - byte[] emailRec = null; - try { - emailRec = mEmailFileRecord.get(recNum); - } catch (IndexOutOfBoundsException e) { - return null; - } - - // The length of the record is X+2 byte, where X bytes is the email address - String email = IccUtils.adnStringFieldToString(emailRec, 0, emailRec.length - 2); - return email; - } - - private void readAdnFileAndWait(int recNum) { - Map fileIds; - fileIds = mPbrFile.mFileIds.get(recNum); - if (fileIds == null || fileIds.isEmpty()) return; - - - int extEf = 0; - // Only call fileIds.get while EFEXT1_TAG is available - if (fileIds.containsKey(USIM_EFEXT1_TAG)) { - extEf = fileIds.get(USIM_EFEXT1_TAG); - } - - mAdnCache.requestLoadAllAdnLike(fileIds.get(USIM_EFADN_TAG), - extEf, obtainMessage(EVENT_USIM_ADN_LOAD_DONE)); - try { - mLock.wait(); - } catch (InterruptedException e) { - Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait"); - } - } - - private void createPbrFile(ArrayList records) { - if (records == null) { - mPbrFile = null; - mIsPbrPresent = false; - return; - } - mPbrFile = new PbrFile(records); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch(msg.what) { - case EVENT_PBR_LOAD_DONE: - ar = (AsyncResult) msg.obj; - if (ar.exception == null) { - createPbrFile((ArrayList)ar.result); - } - synchronized (mLock) { - mLock.notify(); - } - break; - case EVENT_USIM_ADN_LOAD_DONE: - log("Loading USIM ADN records done"); - ar = (AsyncResult) msg.obj; - if (ar.exception == null) { - mPhoneBookRecords.addAll((ArrayList)ar.result); - } - synchronized (mLock) { - mLock.notify(); - } - break; - case EVENT_IAP_LOAD_DONE: - log("Loading USIM IAP records done"); - ar = (AsyncResult) msg.obj; - if (ar.exception == null) { - mIapFileRecord = ((ArrayList)ar.result); - } - synchronized (mLock) { - mLock.notify(); - } - break; - case EVENT_EMAIL_LOAD_DONE: - log("Loading USIM Email records done"); - ar = (AsyncResult) msg.obj; - if (ar.exception == null) { - mEmailFileRecord = ((ArrayList)ar.result); - } - - synchronized (mLock) { - mLock.notify(); - } - break; - } - } - - private class PbrFile { - // RecNum - HashMap> mFileIds; - - PbrFile(ArrayList records) { - mFileIds = new HashMap>(); - SimTlv recTlv; - int recNum = 0; - for (byte[] record: records) { - recTlv = new SimTlv(record, 0, record.length); - parseTag(recTlv, recNum); - recNum ++; - } - } - - void parseTag(SimTlv tlv, int recNum) { - SimTlv tlvEf; - int tag; - byte[] data; - Map val = new HashMap(); - do { - tag = tlv.getTag(); - switch(tag) { - case USIM_TYPE1_TAG: // A8 - case USIM_TYPE3_TAG: // AA - case USIM_TYPE2_TAG: // A9 - data = tlv.getData(); - tlvEf = new SimTlv(data, 0, data.length); - parseEf(tlvEf, val, tag); - break; - } - } while (tlv.nextObject()); - mFileIds.put(recNum, val); - } - - void parseEf(SimTlv tlv, Map val, int parentTag) { - int tag; - byte[] data; - int tagNumberWithinParentTag = 0; - do { - tag = tlv.getTag(); - if (parentTag == USIM_TYPE2_TAG && tag == USIM_EFEMAIL_TAG) { - mEmailPresentInIap = true; - mEmailTagNumberInIap = tagNumberWithinParentTag; - } - switch(tag) { - case USIM_EFEMAIL_TAG: - case USIM_EFADN_TAG: - case USIM_EFEXT1_TAG: - case USIM_EFANR_TAG: - case USIM_EFPBC_TAG: - case USIM_EFGRP_TAG: - case USIM_EFAAS_TAG: - case USIM_EFGSD_TAG: - case USIM_EFUID_TAG: - case USIM_EFCCP1_TAG: - case USIM_EFIAP_TAG: - case USIM_EFSNE_TAG: - data = tlv.getData(); - int efid = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF); - val.put(tag, efid); - break; - } - tagNumberWithinParentTag ++; - } while(tlv.nextObject()); - } - } - - private void log(String msg) { - if(DBG) Log.d(LOG_TAG, msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java deleted file mode 100644 index 3fe200bfaa91..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2011 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 com.android.internal.telephony.IccServiceTable; - -/** - * Wrapper class for the USIM Service Table EF. - * See 3GPP TS 31.102 Release 10 section 4.2.8 - */ -public final class UsimServiceTable extends IccServiceTable { - public enum UsimService { - PHONEBOOK, - FDN, // Fixed Dialing Numbers - FDN_EXTENSION, // FDN extension data in EF_EXT2 - SDN, // Service Dialing Numbers - SDN_EXTENSION, // SDN extension data in EF_EXT3 - BDN, // Barred Dialing Numbers - BDN_EXTENSION, // BDN extension data in EF_EXT4 - OUTGOING_CALL_INFO, - INCOMING_CALL_INFO, - SM_STORAGE, - SM_STATUS_REPORTS, - SM_SERVICE_PARAMS, - ADVICE_OF_CHARGE, - CAP_CONFIG_PARAMS_2, - CB_MESSAGE_ID, - CB_MESSAGE_ID_RANGES, - GROUP_ID_LEVEL_1, - GROUP_ID_LEVEL_2, - SPN, // Service Provider Name - USER_PLMN_SELECT, - MSISDN, - IMAGE, - LOCALISED_SERVICE_AREAS, - EMLPP, // Enhanced Multi-Level Precedence and Preemption - EMLPP_AUTO_ANSWER, - RFU, - GSM_ACCESS, - DATA_DL_VIA_SMS_PP, - DATA_DL_VIA_SMS_CB, - CALL_CONTROL_BY_USIM, - MO_SMS_CONTROL_BY_USIM, - RUN_AT_COMMAND, - IGNORED_1, - ENABLED_SERVICES_TABLE, - APN_CONTROL_LIST, - DEPERSONALISATION_CONTROL_KEYS, - COOPERATIVE_NETWORK_LIST, - GSM_SECURITY_CONTEXT, - CPBCCH_INFO, - INVESTIGATION_SCAN, - MEXE, - OPERATOR_PLMN_SELECT, - HPLMN_SELECT, - EXTENSION_5, // Extension data for ICI, OCI, MSISDN in EF_EXT5 - PLMN_NETWORK_NAME, - OPERATOR_PLMN_LIST, - MBDN, // Mailbox Dialing Numbers - MWI_STATUS, // Message Waiting Indication status - CFI_STATUS, // Call Forwarding Indication status - IGNORED_2, - SERVICE_PROVIDER_DISPLAY_INFO, - MMS_NOTIFICATION, - MMS_NOTIFICATION_EXTENSION, // MMS Notification extension data in EF_EXT8 - GPRS_CALL_CONTROL_BY_USIM, - MMS_CONNECTIVITY_PARAMS, - NETWORK_INDICATION_OF_ALERTING, - VGCS_GROUP_ID_LIST, - VBS_GROUP_ID_LIST, - PSEUDONYM, - IWLAN_USER_PLMN_SELECT, - IWLAN_OPERATOR_PLMN_SELECT, - USER_WSID_LIST, - OPERATOR_WSID_LIST, - VGCS_SECURITY, - VBS_SECURITY, - WLAN_REAUTH_IDENTITY, - MM_STORAGE, - GBA, // Generic Bootstrapping Architecture - MBMS_SECURITY, - DATA_DL_VIA_USSD, - EQUIVALENT_HPLMN, - TERMINAL_PROFILE_AFTER_UICC_ACTIVATION, - EQUIVALENT_HPLMN_PRESENTATION, - LAST_RPLMN_SELECTION_INDICATION, - OMA_BCAST_PROFILE, - GBA_LOCAL_KEY_ESTABLISHMENT, - TERMINAL_APPLICATIONS, - SPN_ICON, - PLMN_NETWORK_NAME_ICON, - USIM_IP_CONNECTION_PARAMS, - IWLAN_HOME_ID_LIST, - IWLAN_EQUIVALENT_HPLMN_PRESENTATION, - IWLAN_HPLMN_PRIORITY_INDICATION, - IWLAN_LAST_REGISTERED_PLMN, - EPS_MOBILITY_MANAGEMENT_INFO, - ALLOWED_CSG_LISTS_AND_INDICATIONS, - CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM, - HPLMN_DIRECT_ACCESS, - ECALL_DATA, - OPERATOR_CSG_LISTS_AND_INDICATIONS, - SM_OVER_IP, - CSG_DISPLAY_CONTROL, - IMS_COMMUNICATION_CONTROL_BY_USIM, - EXTENDED_TERMINAL_APPLICATIONS, - UICC_ACCESS_TO_IMS, - NAS_CONFIG_BY_USIM - } - - public UsimServiceTable(byte[] table) { - super(table); - } - - public boolean isAvailable(UsimService service) { - return super.isAvailable(service.ordinal()); - } - - @Override - protected String getTag() { - return "UsimServiceTable"; - } - - @Override - protected Object[] getValues() { - return UsimService.values(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java deleted file mode 100644 index 0e49e357abf3..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.os.Environment; -import android.util.Xml; -import android.util.Log; - -import java.util.HashMap; -import java.io.FileReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import com.android.internal.util.XmlUtils; - -/** - * {@hide} - */ -class VoiceMailConstants { - private HashMap CarrierVmMap; - - - static final String LOG_TAG = "GSM"; - static final String PARTNER_VOICEMAIL_PATH ="etc/voicemail-conf.xml"; - - static final int NAME = 0; - static final int NUMBER = 1; - static final int TAG = 2; - static final int SIZE = 3; - - VoiceMailConstants () { - CarrierVmMap = new HashMap(); - loadVoiceMail(); - } - - boolean containsCarrier(String carrier) { - return CarrierVmMap.containsKey(carrier); - } - - String getCarrierName(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[NAME]; - } - - String getVoiceMailNumber(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[NUMBER]; - } - - String getVoiceMailTag(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[TAG]; - } - - private void loadVoiceMail() { - FileReader vmReader; - - final File vmFile = new File(Environment.getRootDirectory(), - PARTNER_VOICEMAIL_PATH); - - try { - vmReader = new FileReader(vmFile); - } catch (FileNotFoundException e) { - Log.w(LOG_TAG, "Can't open " + - Environment.getRootDirectory() + "/" + PARTNER_VOICEMAIL_PATH); - return; - } - - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(vmReader); - - XmlUtils.beginDocument(parser, "voicemail"); - - while (true) { - XmlUtils.nextElement(parser); - - String name = parser.getName(); - if (!"voicemail".equals(name)) { - break; - } - - String[] data = new String[SIZE]; - String numeric = parser.getAttributeValue(null, "numeric"); - data[NAME] = parser.getAttributeValue(null, "carrier"); - data[NUMBER] = parser.getAttributeValue(null, "vmnumber"); - data[TAG] = parser.getAttributeValue(null, "vmtag"); - - CarrierVmMap.put(numeric, data); - } - } catch (XmlPullParserException e) { - Log.w(LOG_TAG, "Exception in Voicemail parser " + e); - } catch (IOException e) { - Log.w(LOG_TAG, "Exception in Voicemail parser " + e); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html deleted file mode 100755 index fed8399f48a2..000000000000 --- a/telephony/java/com/android/internal/telephony/gsm/package.html +++ /dev/null @@ -1,6 +0,0 @@ - - -Provides classes to control or read data from GSM phones. -@hide - - diff --git a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimRecords.java deleted file mode 100644 index b8b98b9ffa04..000000000000 --- a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2011 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.ims; - -/** - * {@hide} - */ -public interface IsimRecords { - - /** - * Return the IMS private user identity (IMPI). - * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM. - * @return the IMS private user identity string, or null if not available - */ - String getIsimImpi(); - - /** - * Return the IMS home network domain name. - * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM. - * @return the IMS home network domain name, or null if not available - */ - String getIsimDomain(); - - /** - * Return an array of IMS public user identities (IMPU). - * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM. - * @return an array of IMS public user identity strings, or null if not available - */ - String[] getIsimImpu(); -} diff --git a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java deleted file mode 100644 index ee1a42d5c6ba..000000000000 --- a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011 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.ims; - -import android.os.AsyncResult; -import android.os.Handler; -import android.util.Log; - -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccRecords; -import com.android.internal.telephony.gsm.SimTlv; - -import java.nio.charset.Charset; -import java.util.ArrayList; - -import static com.android.internal.telephony.IccConstants.EF_DOMAIN; -import static com.android.internal.telephony.IccConstants.EF_IMPI; -import static com.android.internal.telephony.IccConstants.EF_IMPU; - -/** - * {@hide} - */ -public final class IsimUiccRecords implements IsimRecords { - protected static final String LOG_TAG = "GSM"; - - private static final boolean DBG = true; - private static final boolean DUMP_RECORDS = false; // Note: PII is logged when this is true - - // ISIM EF records (see 3GPP TS 31.103) - private String mIsimImpi; // IMS private user identity - private String mIsimDomain; // IMS home network domain name - private String[] mIsimImpu; // IMS public user identity(s) - - private static final int TAG_ISIM_VALUE = 0x80; // From 3GPP TS 31.103 - - private class EfIsimImpiLoaded implements IccRecords.IccRecordLoaded { - public String getEfName() { - return "EF_ISIM_IMPI"; - } - public void onRecordLoaded(AsyncResult ar) { - byte[] data = (byte[]) ar.result; - mIsimImpi = isimTlvToString(data); - if (DUMP_RECORDS) log("EF_IMPI=" + mIsimImpi); - } - } - - private class EfIsimImpuLoaded implements IccRecords.IccRecordLoaded { - public String getEfName() { - return "EF_ISIM_IMPU"; - } - public void onRecordLoaded(AsyncResult ar) { - ArrayList impuList = (ArrayList) ar.result; - if (DBG) log("EF_IMPU record count: " + impuList.size()); - mIsimImpu = new String[impuList.size()]; - int i = 0; - for (byte[] identity : impuList) { - String impu = isimTlvToString(identity); - if (DUMP_RECORDS) log("EF_IMPU[" + i + "]=" + impu); - mIsimImpu[i++] = impu; - } - } - } - - private class EfIsimDomainLoaded implements IccRecords.IccRecordLoaded { - public String getEfName() { - return "EF_ISIM_DOMAIN"; - } - public void onRecordLoaded(AsyncResult ar) { - byte[] data = (byte[]) ar.result; - mIsimDomain = isimTlvToString(data); - if (DUMP_RECORDS) log("EF_DOMAIN=" + mIsimDomain); - } - } - - /** - * Request the ISIM records to load. - * @param iccFh the IccFileHandler to load the records from - * @param h the Handler to which the response message will be sent - * @return the number of EF record requests that were added - */ - public int fetchIsimRecords(IccFileHandler iccFh, Handler h) { - iccFh.loadEFTransparent(EF_IMPI, h.obtainMessage( - IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded())); - iccFh.loadEFLinearFixedAll(EF_IMPU, h.obtainMessage( - IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded())); - iccFh.loadEFTransparent(EF_DOMAIN, h.obtainMessage( - IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded())); - return 3; // number of EF record load requests - } - - /** - * ISIM records for IMS are stored inside a Tag-Length-Value record as a UTF-8 string - * with tag value 0x80. - * @param record the byte array containing the IMS data string - * @return the decoded String value, or null if the record can't be decoded - */ - private static String isimTlvToString(byte[] record) { - SimTlv tlv = new SimTlv(record, 0, record.length); - do { - if (tlv.getTag() == TAG_ISIM_VALUE) { - return new String(tlv.getData(), Charset.forName("UTF-8")); - } - } while (tlv.nextObject()); - - Log.e(LOG_TAG, "[ISIM] can't find TLV tag in ISIM record, returning null"); - return null; - } - - void log(String s) { - if (DBG) Log.d(LOG_TAG, "[ISIM] " + s); - } - - void loge(String s) { - if (DBG) Log.e(LOG_TAG, "[ISIM] " + s); - } - - /** - * Return the IMS private user identity (IMPI). - * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM. - * @return the IMS private user identity string, or null if not available - */ - public String getIsimImpi() { - return mIsimImpi; - } - - /** - * Return the IMS home network domain name. - * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM. - * @return the IMS home network domain name, or null if not available - */ - public String getIsimDomain() { - return mIsimDomain; - } - - /** - * Return an array of IMS public user identities (IMPU). - * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM. - * @return an array of IMS public user identity strings, or null if not available - */ - public String[] getIsimImpu() { - return (mIsimImpu != null) ? mIsimImpu.clone() : null; - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java b/telephony/java/com/android/internal/telephony/sip/SipCallBase.java deleted file mode 100644 index 9050a4382a59..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -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 android.net.sip.SipManager; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -abstract class SipCallBase extends Call { - protected List connections = new ArrayList(); - - protected abstract void setState(State newState); - - public List getConnections() { - // FIXME should return Collections.unmodifiableList(); - return connections; - } - - public boolean isMultiparty() { - return connections.size() > 1; - } - - public String toString() { - return state.toString() + ":" + super.toString(); - } - - void clearDisconnected() { - for (Iterator it = connections.iterator(); it.hasNext(); ) { - Connection c = it.next(); - if (c.getState() == State.DISCONNECTED) it.remove(); - } - - if (connections.isEmpty()) setState(State.IDLE); - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java deleted file mode 100644 index 99f4e0f09053..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -import android.content.Context; -import android.os.Handler; -import android.os.Message; - -import com.android.internal.telephony.BaseCommands; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.UUSInfo; -import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; - -/** - * SIP doesn't need CommandsInterface. The class does nothing but made to work - * with PhoneBase's constructor. - */ -class SipCommandInterface extends BaseCommands implements CommandsInterface { - SipCommandInterface(Context context) { - super(context); - } - - @Override public void setOnNITZTime(Handler h, int what, Object obj) { - } - - public void getIccCardStatus(Message result) { - } - - public void supplyIccPin(String pin, Message result) { - } - - public void supplyIccPuk(String puk, String newPin, Message result) { - } - - public void supplyIccPin2(String pin, Message result) { - } - - public void supplyIccPuk2(String puk, String newPin2, Message result) { - } - - public void changeIccPin(String oldPin, String newPin, Message result) { - } - - public void changeIccPin2(String oldPin2, String newPin2, Message result) { - } - - public void changeBarringPassword(String facility, String oldPwd, - String newPwd, Message result) { - } - - public void supplyNetworkDepersonalization(String netpin, Message result) { - } - - public void getCurrentCalls(Message result) { - } - - @Deprecated public void getPDPContextList(Message result) { - } - - public void getDataCallList(Message result) { - } - - public void dial(String address, int clirMode, Message result) { - } - - public void dial(String address, int clirMode, UUSInfo uusInfo, - Message result) { - } - - public void getIMSI(Message result) { - } - - public void getIMSIForApp(String aid, Message result) { - } - - public void getIMEI(Message result) { - } - - public void getIMEISV(Message result) { - } - - - public void hangupConnection (int gsmIndex, Message result) { - } - - public void hangupWaitingOrBackground (Message result) { - } - - public void hangupForegroundResumeBackground (Message result) { - } - - public void switchWaitingOrHoldingAndActive (Message result) { - } - - public void conference (Message result) { - } - - - public void setPreferredVoicePrivacy(boolean enable, Message result) { - } - - public void getPreferredVoicePrivacy(Message result) { - } - - public void separateConnection (int gsmIndex, Message result) { - } - - public void acceptCall (Message result) { - } - - public void rejectCall (Message result) { - } - - public void explicitCallTransfer (Message result) { - } - - public void getLastCallFailCause (Message result) { - } - - /** @deprecated */ - public void getLastPdpFailCause (Message result) { - } - - public void getLastDataCallFailCause (Message result) { - } - - public void setMute (boolean enableMute, Message response) { - } - - public void getMute (Message response) { - } - - public void getSignalStrength (Message result) { - } - - public void getVoiceRegistrationState (Message result) { - } - - public void getDataRegistrationState (Message result) { - } - - public void getOperator(Message result) { - } - - public void sendDtmf(char c, Message result) { - } - - public void startDtmf(char c, Message result) { - } - - public void stopDtmf(Message result) { - } - - public void sendBurstDtmf(String dtmfString, int on, int off, - Message result) { - } - - public void sendSMS (String smscPDU, String pdu, Message result) { - } - - public void sendCdmaSms(byte[] pdu, Message result) { - } - - public void deleteSmsOnSim(int index, Message response) { - } - - public void deleteSmsOnRuim(int index, Message response) { - } - - public void writeSmsToSim(int status, String smsc, String pdu, Message response) { - } - - public void writeSmsToRuim(int status, String pdu, Message response) { - } - - public void setupDataCall(String radioTechnology, String profile, - String apn, String user, String password, String authType, - String protocol, Message result) { - } - - public void deactivateDataCall(int cid, int reason, Message result) { - } - - public void setRadioPower(boolean on, Message result) { - } - - public void setSuppServiceNotifications(boolean enable, Message result) { - } - - public void acknowledgeLastIncomingGsmSms(boolean success, int cause, - Message result) { - } - - public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, - Message result) { - } - - public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, - Message result) { - } - - public void iccIO (int command, int fileid, String path, int p1, int p2, - int p3, String data, String pin2, Message result) { - } - public void iccIOForApp (int command, int fileid, String path, int p1, int p2, - int p3, String data, String pin2, String aid, Message result) { - } - - public void getCLIR(Message result) { - } - - public void setCLIR(int clirMode, Message result) { - } - - public void queryCallWaiting(int serviceClass, Message response) { - } - - public void setCallWaiting(boolean enable, int serviceClass, - Message response) { - } - - public void setNetworkSelectionModeAutomatic(Message response) { - } - - public void setNetworkSelectionModeManual( - String operatorNumeric, Message response) { - } - - public void getNetworkSelectionMode(Message response) { - } - - public void getAvailableNetworks(Message response) { - } - - public void setCallForward(int action, int cfReason, int serviceClass, - String number, int timeSeconds, Message response) { - } - - public void queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message response) { - } - - public void queryCLIP(Message response) { - } - - public void getBasebandVersion (Message response) { - } - - @Override - public void queryFacilityLock(String facility, String password, - int serviceClass, Message response) { - } - - @Override - public void queryFacilityLockForApp(String facility, String password, - int serviceClass, String appId, Message response) { - } - - @Override - public void setFacilityLock(String facility, boolean lockState, - String password, int serviceClass, Message response) { - } - - @Override - public void setFacilityLockForApp(String facility, boolean lockState, - String password, int serviceClass, String appId, Message response) { - } - - public void sendUSSD (String ussdString, Message response) { - } - - public void cancelPendingUssd (Message response) { - } - - public void resetRadio(Message result) { - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) { - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) { - } - - public void setBandMode (int bandMode, Message response) { - } - - public void queryAvailableBandMode (Message response) { - } - - public void sendTerminalResponse(String contents, Message response) { - } - - public void sendEnvelope(String contents, Message response) { - } - - public void sendEnvelopeWithStatus(String contents, Message response) { - } - - public void handleCallSetupRequestFromSim( - boolean accept, Message response) { - } - - public void setPreferredNetworkType(int networkType , Message response) { - } - - public void getPreferredNetworkType(Message response) { - } - - public void getNeighboringCids(Message response) { - } - - public void setLocationUpdates(boolean enable, Message response) { - } - - public void getSmscAddress(Message result) { - } - - public void setSmscAddress(String address, Message result) { - } - - public void reportSmsMemoryStatus(boolean available, Message result) { - } - - public void reportStkServiceIsRunning(Message result) { - } - - @Override - public void getCdmaSubscriptionSource(Message response) { - } - - public void getGsmBroadcastConfig(Message response) { - } - - public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) { - } - - public void setGsmBroadcastActivation(boolean activate, Message response) { - } - - // ***** Methods for CDMA support - public void getDeviceIdentity(Message response) { - } - - public void getCDMASubscription(Message response) { - } - - public void setPhoneType(int phoneType) { //Set by CDMAPhone and GSMPhone constructor - } - - public void queryCdmaRoamingPreference(Message response) { - } - - public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { - } - - public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) { - } - - public void queryTTYMode(Message response) { - } - - public void setTTYMode(int ttyMode, Message response) { - } - - public void sendCDMAFeatureCode(String FeatureCode, Message response) { - } - - public void getCdmaBroadcastConfig(Message response) { - } - - public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) { - } - - public void setCdmaBroadcastActivation(boolean activate, Message response) { - } - - public void exitEmergencyCallbackMode(Message response) { - } - - @Override - public void supplyIccPinForApp(String pin, String aid, Message response) { - } - - @Override - public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) { - } - - @Override - public void supplyIccPin2ForApp(String pin2, String aid, Message response) { - } - - @Override - public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) { - } - - @Override - public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) { - } - - @Override - public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, - Message response) { - } - - public void requestIsimAuthentication(String nonce, Message response) { - } - - public void getVoiceRadioTechnology(Message result) { - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java deleted file mode 100644 index c83f696df9ca..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.UUSInfo; - -import android.net.sip.SipAudioCall; -import android.os.SystemClock; -import android.util.Log; -import android.telephony.PhoneNumberUtils; - -abstract class SipConnectionBase extends Connection { - private static final String LOG_TAG = "SIP_CONN"; - - private SipAudioCall mSipAudioCall; - - private String dialString; // outgoing calls only - private String postDialString; // outgoing calls only - private int nextPostDialChar; // index into postDialString - private boolean isIncoming; - - /* - * These time/timespan values are based on System.currentTimeMillis(), - * i.e., "wall clock" time. - */ - private long createTime; - private long connectTime; - private long disconnectTime; - - /* - * These time/timespan values are based on SystemClock.elapsedRealTime(), - * i.e., time since boot. They are appropriate for comparison and - * calculating deltas. - */ - private long connectTimeReal; - private long duration = -1L; - private long holdingStartTime; // The time when the Connection last transitioned - // into HOLDING - - private DisconnectCause mCause = DisconnectCause.NOT_DISCONNECTED; - private PostDialState postDialState = PostDialState.NOT_STARTED; - - SipConnectionBase(String dialString) { - this.dialString = dialString; - - postDialString = PhoneNumberUtils.extractPostDialPortion(dialString); - - isIncoming = false; - createTime = System.currentTimeMillis(); - } - - protected void setState(Call.State state) { - switch (state) { - case ACTIVE: - if (connectTime == 0) { - connectTimeReal = SystemClock.elapsedRealtime(); - connectTime = System.currentTimeMillis(); - } - break; - case DISCONNECTED: - duration = getDurationMillis(); - disconnectTime = System.currentTimeMillis(); - break; - case HOLDING: - holdingStartTime = SystemClock.elapsedRealtime(); - break; - } - } - - @Override - public long getCreateTime() { - return createTime; - } - - @Override - public long getConnectTime() { - return connectTime; - } - - @Override - public long getDisconnectTime() { - return disconnectTime; - } - - @Override - public long getDurationMillis() { - if (connectTimeReal == 0) { - return 0; - } else if (duration < 0) { - return SystemClock.elapsedRealtime() - connectTimeReal; - } else { - return duration; - } - } - - @Override - public long getHoldDurationMillis() { - if (getState() != Call.State.HOLDING) { - // If not holding, return 0 - return 0; - } else { - return SystemClock.elapsedRealtime() - holdingStartTime; - } - } - - @Override - public DisconnectCause getDisconnectCause() { - return mCause; - } - - void setDisconnectCause(DisconnectCause cause) { - mCause = cause; - } - - @Override - public PostDialState getPostDialState() { - return postDialState; - } - - @Override - public void proceedAfterWaitChar() { - // TODO - } - - @Override - public void proceedAfterWildChar(String str) { - // TODO - } - - @Override - public void cancelPostDial() { - // TODO - } - - protected abstract Phone getPhone(); - - @Override - public String getRemainingPostDialString() { - if (postDialState == PostDialState.CANCELLED - || postDialState == PostDialState.COMPLETE - || postDialString == null - || postDialString.length() <= nextPostDialChar) { - return ""; - } - - return postDialString.substring(nextPostDialChar); - } - - private void log(String msg) { - Log.d(LOG_TAG, "[SipConn] " + msg); - } - - @Override - public int getNumberPresentation() { - // TODO: add PRESENTATION_URL - return Connection.PRESENTATION_ALLOWED; - } - - @Override - public UUSInfo getUUSInfo() { - // FIXME: what's this for SIP? - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java deleted file mode 100644 index 5471289c3a1f..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java +++ /dev/null @@ -1,938 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -import android.content.Context; -import android.media.AudioManager; -import android.net.rtp.AudioGroup; -import android.net.sip.SipAudioCall; -import android.net.sip.SipErrorCode; -import android.net.sip.SipException; -import android.net.sip.SipManager; -import android.net.sip.SipProfile; -import android.net.sip.SipSession; -import android.os.AsyncResult; -import android.os.Message; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneNotifier; - -import java.text.ParseException; -import java.util.List; -import java.util.regex.Pattern; - -/** - * {@hide} - */ -public class SipPhone extends SipPhoneBase { - private static final String LOG_TAG = "SipPhone"; - private static final boolean DEBUG = true; - private static final int TIMEOUT_MAKE_CALL = 15; // in seconds - private static final int TIMEOUT_ANSWER_CALL = 8; // in seconds - private static final int TIMEOUT_HOLD_CALL = 15; // in seconds - - // A call that is ringing or (call) waiting - private SipCall ringingCall = new SipCall(); - private SipCall foregroundCall = new SipCall(); - private SipCall backgroundCall = new SipCall(); - - private SipManager mSipManager; - private SipProfile mProfile; - - SipPhone (Context context, PhoneNotifier notifier, SipProfile profile) { - super(context, notifier); - - if (DEBUG) Log.d(LOG_TAG, "new SipPhone: " + profile.getUriString()); - ringingCall = new SipCall(); - foregroundCall = new SipCall(); - backgroundCall = new SipCall(); - mProfile = profile; - mSipManager = SipManager.newInstance(context); - } - - @Override - public boolean equals(Object o) { - if (o == this) return true; - if (!(o instanceof SipPhone)) return false; - SipPhone that = (SipPhone) o; - return mProfile.getUriString().equals(that.mProfile.getUriString()); - } - - public String getPhoneName() { - return "SIP:" + getUriString(mProfile); - } - - public String getSipUri() { - return mProfile.getUriString(); - } - - public boolean equals(SipPhone phone) { - return getSipUri().equals(phone.getSipUri()); - } - - public boolean canTake(Object incomingCall) { - synchronized (SipPhone.class) { - if (!(incomingCall instanceof SipAudioCall)) return false; - if (ringingCall.getState().isAlive()) return false; - - // FIXME: is it true that we cannot take any incoming call if - // both foreground and background are active - if (foregroundCall.getState().isAlive() - && backgroundCall.getState().isAlive()) { - return false; - } - - try { - SipAudioCall sipAudioCall = (SipAudioCall) incomingCall; - if (DEBUG) Log.d(LOG_TAG, "+++ taking call from: " - + sipAudioCall.getPeerProfile().getUriString()); - String localUri = sipAudioCall.getLocalProfile().getUriString(); - if (localUri.equals(mProfile.getUriString())) { - boolean makeCallWait = foregroundCall.getState().isAlive(); - ringingCall.initIncomingCall(sipAudioCall, makeCallWait); - if (sipAudioCall.getState() - != SipSession.State.INCOMING_CALL) { - // Peer cancelled the call! - if (DEBUG) Log.d(LOG_TAG, " call cancelled !!"); - ringingCall.reset(); - } - return true; - } - } catch (Exception e) { - // Peer may cancel the call at any time during the time we hook - // up ringingCall with sipAudioCall. Clean up ringingCall when - // that happens. - ringingCall.reset(); - } - return false; - } - } - - public void acceptCall() throws CallStateException { - synchronized (SipPhone.class) { - if ((ringingCall.getState() == Call.State.INCOMING) || - (ringingCall.getState() == Call.State.WAITING)) { - if (DEBUG) Log.d(LOG_TAG, "acceptCall"); - // Always unmute when answering a new call - ringingCall.setMute(false); - ringingCall.acceptCall(); - } else { - throw new CallStateException("phone not ringing"); - } - } - } - - public void rejectCall() throws CallStateException { - synchronized (SipPhone.class) { - if (ringingCall.getState().isRinging()) { - if (DEBUG) Log.d(LOG_TAG, "rejectCall"); - ringingCall.rejectCall(); - } else { - throw new CallStateException("phone not ringing"); - } - } - } - - public Connection dial(String dialString) throws CallStateException { - synchronized (SipPhone.class) { - return dialInternal(dialString); - } - } - - private Connection dialInternal(String dialString) - throws CallStateException { - clearDisconnected(); - - if (!canDial()) { - throw new CallStateException("cannot dial in current state"); - } - if (foregroundCall.getState() == SipCall.State.ACTIVE) { - switchHoldingAndActive(); - } - if (foregroundCall.getState() != SipCall.State.IDLE) { - //we should have failed in !canDial() above before we get here - throw new CallStateException("cannot dial in current state"); - } - - foregroundCall.setMute(false); - try { - Connection c = foregroundCall.dial(dialString); - return c; - } catch (SipException e) { - Log.e(LOG_TAG, "dial()", e); - throw new CallStateException("dial error: " + e); - } - } - - public void switchHoldingAndActive() throws CallStateException { - if (DEBUG) Log.d(LOG_TAG, " ~~~~~~ switch fg and bg"); - synchronized (SipPhone.class) { - foregroundCall.switchWith(backgroundCall); - if (backgroundCall.getState().isAlive()) backgroundCall.hold(); - if (foregroundCall.getState().isAlive()) foregroundCall.unhold(); - } - } - - public boolean canConference() { - return true; - } - - public void conference() throws CallStateException { - synchronized (SipPhone.class) { - if ((foregroundCall.getState() != SipCall.State.ACTIVE) - || (foregroundCall.getState() != SipCall.State.ACTIVE)) { - throw new CallStateException("wrong state to merge calls: fg=" - + foregroundCall.getState() + ", bg=" - + backgroundCall.getState()); - } - foregroundCall.merge(backgroundCall); - } - } - - public void conference(Call that) throws CallStateException { - synchronized (SipPhone.class) { - if (!(that instanceof SipCall)) { - throw new CallStateException("expect " + SipCall.class - + ", cannot merge with " + that.getClass()); - } - foregroundCall.merge((SipCall) that); - } - } - - public boolean canTransfer() { - return false; - } - - public void explicitCallTransfer() throws CallStateException { - //mCT.explicitCallTransfer(); - } - - public void clearDisconnected() { - synchronized (SipPhone.class) { - ringingCall.clearDisconnected(); - foregroundCall.clearDisconnected(); - backgroundCall.clearDisconnected(); - - updatePhoneState(); - notifyPreciseCallStateChanged(); - } - } - - public void sendDtmf(char c) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "sendDtmf called with invalid character '" + c + "'"); - } else if (foregroundCall.getState().isAlive()) { - synchronized (SipPhone.class) { - foregroundCall.sendDtmf(c); - } - } - } - - public void startDtmf(char c) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "startDtmf called with invalid character '" + c + "'"); - } else { - sendDtmf(c); - } - } - - public void stopDtmf() { - // no op - } - - public void sendBurstDtmf(String dtmfString) { - Log.e(LOG_TAG, "[SipPhone] sendBurstDtmf() is a CDMA method"); - } - - public void getOutgoingCallerIdDisplay(Message onComplete) { - // FIXME: what to reply? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, - Message onComplete) { - // FIXME: what's this for SIP? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void getCallWaiting(Message onComplete) { - // FIXME: what to reply? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - // FIXME: what to reply? - Log.e(LOG_TAG, "call waiting not supported"); - } - - @Override - public void setEchoSuppressionEnabled(boolean enabled) { - // TODO: Remove the enabled argument. We should check the speakerphone - // state with AudioManager instead of keeping a state here so the - // method with a state argument is redundant. Also rename the method - // to something like onSpeaerphoneStateChanged(). Echo suppression may - // not be available on every device. - synchronized (SipPhone.class) { - foregroundCall.setAudioGroupMode(); - } - } - - public void setMute(boolean muted) { - synchronized (SipPhone.class) { - foregroundCall.setMute(muted); - } - } - - public boolean getMute() { - return (foregroundCall.getState().isAlive() - ? foregroundCall.getMute() - : backgroundCall.getMute()); - } - - public Call getForegroundCall() { - return foregroundCall; - } - - public Call getBackgroundCall() { - return backgroundCall; - } - - public Call getRingingCall() { - return ringingCall; - } - - public ServiceState getServiceState() { - // FIXME: we may need to provide this when data connectivity is lost - // or when server is down - return super.getServiceState(); - } - - private String getUriString(SipProfile p) { - // SipProfile.getUriString() may contain "SIP:" and port - return p.getUserName() + "@" + getSipDomain(p); - } - - private String getSipDomain(SipProfile p) { - String domain = p.getSipDomain(); - // TODO: move this to SipProfile - if (domain.endsWith(":5060")) { - return domain.substring(0, domain.length() - 5); - } else { - return domain; - } - } - - private class SipCall extends SipCallBase { - void reset() { - connections.clear(); - setState(Call.State.IDLE); - } - - void switchWith(SipCall that) { - synchronized (SipPhone.class) { - SipCall tmp = new SipCall(); - tmp.takeOver(this); - this.takeOver(that); - that.takeOver(tmp); - } - } - - private void takeOver(SipCall that) { - connections = that.connections; - state = that.state; - for (Connection c : connections) { - ((SipConnection) c).changeOwner(this); - } - } - - @Override - public Phone getPhone() { - return SipPhone.this; - } - - @Override - public List getConnections() { - synchronized (SipPhone.class) { - // FIXME should return Collections.unmodifiableList(); - return connections; - } - } - - Connection dial(String originalNumber) throws SipException { - String calleeSipUri = originalNumber; - if (!calleeSipUri.contains("@")) { - String replaceStr = Pattern.quote(mProfile.getUserName() + "@"); - calleeSipUri = mProfile.getUriString().replaceFirst(replaceStr, - calleeSipUri + "@"); - } - try { - SipProfile callee = - new SipProfile.Builder(calleeSipUri).build(); - SipConnection c = new SipConnection(this, callee, - originalNumber); - c.dial(); - connections.add(c); - setState(Call.State.DIALING); - return c; - } catch (ParseException e) { - throw new SipException("dial", e); - } - } - - @Override - public void hangup() throws CallStateException { - synchronized (SipPhone.class) { - if (state.isAlive()) { - if (DEBUG) Log.d(LOG_TAG, "hang up call: " + getState() - + ": " + this + " on phone " + getPhone()); - setState(State.DISCONNECTING); - CallStateException excp = null; - for (Connection c : connections) { - try { - c.hangup(); - } catch (CallStateException e) { - excp = e; - } - } - if (excp != null) throw excp; - } else { - if (DEBUG) Log.d(LOG_TAG, "hang up dead call: " + getState() - + ": " + this + " on phone " + getPhone()); - } - } - } - - void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) { - SipProfile callee = sipAudioCall.getPeerProfile(); - SipConnection c = new SipConnection(this, callee); - connections.add(c); - - Call.State newState = makeCallWait ? State.WAITING : State.INCOMING; - c.initIncomingCall(sipAudioCall, newState); - - setState(newState); - notifyNewRingingConnectionP(c); - } - - void rejectCall() throws CallStateException { - hangup(); - } - - void acceptCall() throws CallStateException { - if (this != ringingCall) { - throw new CallStateException("acceptCall() in a non-ringing call"); - } - if (connections.size() != 1) { - throw new CallStateException("acceptCall() in a conf call"); - } - ((SipConnection) connections.get(0)).acceptCall(); - } - - private boolean isSpeakerOn() { - return ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)) - .isSpeakerphoneOn(); - } - - void setAudioGroupMode() { - AudioGroup audioGroup = getAudioGroup(); - if (audioGroup == null) return; - int mode = audioGroup.getMode(); - if (state == State.HOLDING) { - audioGroup.setMode(AudioGroup.MODE_ON_HOLD); - } else if (getMute()) { - audioGroup.setMode(AudioGroup.MODE_MUTED); - } else if (isSpeakerOn()) { - audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION); - } else { - audioGroup.setMode(AudioGroup.MODE_NORMAL); - } - if (DEBUG) Log.d(LOG_TAG, String.format( - "audioGroup mode change: %d --> %d", mode, - audioGroup.getMode())); - } - - void hold() throws CallStateException { - setState(State.HOLDING); - for (Connection c : connections) ((SipConnection) c).hold(); - setAudioGroupMode(); - } - - void unhold() throws CallStateException { - setState(State.ACTIVE); - AudioGroup audioGroup = new AudioGroup(); - for (Connection c : connections) { - ((SipConnection) c).unhold(audioGroup); - } - setAudioGroupMode(); - } - - void setMute(boolean muted) { - for (Connection c : connections) { - ((SipConnection) c).setMute(muted); - } - } - - boolean getMute() { - return connections.isEmpty() - ? false - : ((SipConnection) connections.get(0)).getMute(); - } - - void merge(SipCall that) throws CallStateException { - AudioGroup audioGroup = getAudioGroup(); - - // copy to an array to avoid concurrent modification as connections - // in that.connections will be removed in add(SipConnection). - Connection[] cc = that.connections.toArray( - new Connection[that.connections.size()]); - for (Connection c : cc) { - SipConnection conn = (SipConnection) c; - add(conn); - if (conn.getState() == Call.State.HOLDING) { - conn.unhold(audioGroup); - } - } - that.setState(Call.State.IDLE); - } - - private void add(SipConnection conn) { - SipCall call = conn.getCall(); - if (call == this) return; - if (call != null) call.connections.remove(conn); - - connections.add(conn); - conn.changeOwner(this); - } - - void sendDtmf(char c) { - AudioGroup audioGroup = getAudioGroup(); - if (audioGroup == null) return; - audioGroup.sendDtmf(convertDtmf(c)); - } - - private int convertDtmf(char c) { - int code = c - '0'; - if ((code < 0) || (code > 9)) { - switch (c) { - case '*': return 10; - case '#': return 11; - case 'A': return 12; - case 'B': return 13; - case 'C': return 14; - case 'D': return 15; - default: - throw new IllegalArgumentException( - "invalid DTMF char: " + (int) c); - } - } - return code; - } - - @Override - protected void setState(State newState) { - if (state != newState) { - if (DEBUG) Log.v(LOG_TAG, "+***+ call state changed: " + state - + " --> " + newState + ": " + this + ": on phone " - + getPhone() + " " + connections.size()); - - if (newState == Call.State.ALERTING) { - state = newState; // need in ALERTING to enable ringback - SipPhone.this.startRingbackTone(); - } else if (state == Call.State.ALERTING) { - SipPhone.this.stopRingbackTone(); - } - state = newState; - updatePhoneState(); - notifyPreciseCallStateChanged(); - } - } - - void onConnectionStateChanged(SipConnection conn) { - // this can be called back when a conf call is formed - if (state != State.ACTIVE) { - setState(conn.getState()); - } - } - - void onConnectionEnded(SipConnection conn) { - // set state to DISCONNECTED only when all conns are disconnected - if (state != State.DISCONNECTED) { - boolean allConnectionsDisconnected = true; - if (DEBUG) Log.d(LOG_TAG, "---check connections: " - + connections.size()); - for (Connection c : connections) { - if (DEBUG) Log.d(LOG_TAG, " state=" + c.getState() + ": " - + c); - if (c.getState() != State.DISCONNECTED) { - allConnectionsDisconnected = false; - break; - } - } - if (allConnectionsDisconnected) setState(State.DISCONNECTED); - } - notifyDisconnectP(conn); - } - - private AudioGroup getAudioGroup() { - if (connections.isEmpty()) return null; - return ((SipConnection) connections.get(0)).getAudioGroup(); - } - } - - private class SipConnection extends SipConnectionBase { - private SipCall mOwner; - private SipAudioCall mSipAudioCall; - private Call.State mState = Call.State.IDLE; - private SipProfile mPeer; - private String mOriginalNumber; // may be a PSTN number - private boolean mIncoming = false; - - private SipAudioCallAdapter mAdapter = new SipAudioCallAdapter() { - @Override - protected void onCallEnded(DisconnectCause cause) { - if (getDisconnectCause() != DisconnectCause.LOCAL) { - setDisconnectCause(cause); - } - synchronized (SipPhone.class) { - setState(Call.State.DISCONNECTED); - SipAudioCall sipAudioCall = mSipAudioCall; - mSipAudioCall = null; - String sessionState = (sipAudioCall == null) - ? "" - : (sipAudioCall.getState() + ", "); - if (DEBUG) Log.d(LOG_TAG, "--- connection ended: " - + mPeer.getUriString() + ": " + sessionState - + "cause: " + getDisconnectCause() + ", on phone " - + getPhone()); - if (sipAudioCall != null) { - sipAudioCall.setListener(null); - sipAudioCall.close(); - } - mOwner.onConnectionEnded(SipConnection.this); - } - } - - @Override - public void onCallEstablished(SipAudioCall call) { - onChanged(call); - if (mState == Call.State.ACTIVE) call.startAudio(); - } - - @Override - public void onCallHeld(SipAudioCall call) { - onChanged(call); - if (mState == Call.State.HOLDING) call.startAudio(); - } - - @Override - public void onChanged(SipAudioCall call) { - synchronized (SipPhone.class) { - Call.State newState = getCallStateFrom(call); - if (mState == newState) return; - if (newState == Call.State.INCOMING) { - setState(mOwner.getState()); // INCOMING or WAITING - } else { - if (mOwner == ringingCall) { - if (ringingCall.getState() == Call.State.WAITING) { - try { - switchHoldingAndActive(); - } catch (CallStateException e) { - // disconnect the call. - onCallEnded(DisconnectCause.LOCAL); - return; - } - } - foregroundCall.switchWith(ringingCall); - } - setState(newState); - } - mOwner.onConnectionStateChanged(SipConnection.this); - if (DEBUG) Log.v(LOG_TAG, "+***+ connection state changed: " - + mPeer.getUriString() + ": " + mState - + " on phone " + getPhone()); - } - } - - @Override - protected void onError(DisconnectCause cause) { - if (DEBUG) Log.d(LOG_TAG, "SIP error: " + cause); - onCallEnded(cause); - } - }; - - public SipConnection(SipCall owner, SipProfile callee, - String originalNumber) { - super(originalNumber); - mOwner = owner; - mPeer = callee; - mOriginalNumber = originalNumber; - } - - public SipConnection(SipCall owner, SipProfile callee) { - this(owner, callee, getUriString(callee)); - } - - @Override - public String getCnapName() { - String displayName = mPeer.getDisplayName(); - return TextUtils.isEmpty(displayName) ? null - : displayName; - } - - @Override - public int getNumberPresentation() { - return Connection.PRESENTATION_ALLOWED; - } - - void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) { - setState(newState); - mSipAudioCall = sipAudioCall; - sipAudioCall.setListener(mAdapter); // call back to set state - mIncoming = true; - } - - void acceptCall() throws CallStateException { - try { - mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL); - } catch (SipException e) { - throw new CallStateException("acceptCall(): " + e); - } - } - - void changeOwner(SipCall owner) { - mOwner = owner; - } - - AudioGroup getAudioGroup() { - if (mSipAudioCall == null) return null; - return mSipAudioCall.getAudioGroup(); - } - - void dial() throws SipException { - setState(Call.State.DIALING); - mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null, - TIMEOUT_MAKE_CALL); - mSipAudioCall.setListener(mAdapter); - } - - void hold() throws CallStateException { - setState(Call.State.HOLDING); - try { - mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL); - } catch (SipException e) { - throw new CallStateException("hold(): " + e); - } - } - - void unhold(AudioGroup audioGroup) throws CallStateException { - mSipAudioCall.setAudioGroup(audioGroup); - setState(Call.State.ACTIVE); - try { - mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL); - } catch (SipException e) { - throw new CallStateException("unhold(): " + e); - } - } - - void setMute(boolean muted) { - if ((mSipAudioCall != null) && (muted != mSipAudioCall.isMuted())) { - mSipAudioCall.toggleMute(); - } - } - - boolean getMute() { - return (mSipAudioCall == null) ? false - : mSipAudioCall.isMuted(); - } - - @Override - protected void setState(Call.State state) { - if (state == mState) return; - super.setState(state); - mState = state; - } - - @Override - public Call.State getState() { - return mState; - } - - @Override - public boolean isIncoming() { - return mIncoming; - } - - @Override - public String getAddress() { - // Phone app uses this to query caller ID. Return the original dial - // number (which may be a PSTN number) instead of the peer's SIP - // URI. - return mOriginalNumber; - } - - @Override - public SipCall getCall() { - return mOwner; - } - - @Override - protected Phone getPhone() { - return mOwner.getPhone(); - } - - @Override - public void hangup() throws CallStateException { - synchronized (SipPhone.class) { - if (DEBUG) Log.d(LOG_TAG, "hangup conn: " + mPeer.getUriString() - + ": " + mState + ": on phone " - + getPhone().getPhoneName()); - if (!mState.isAlive()) return; - try { - SipAudioCall sipAudioCall = mSipAudioCall; - if (sipAudioCall != null) { - sipAudioCall.setListener(null); - sipAudioCall.endCall(); - } - } catch (SipException e) { - throw new CallStateException("hangup(): " + e); - } finally { - mAdapter.onCallEnded(((mState == Call.State.INCOMING) - || (mState == Call.State.WAITING)) - ? DisconnectCause.INCOMING_REJECTED - : DisconnectCause.LOCAL); - } - } - } - - @Override - public void separate() throws CallStateException { - synchronized (SipPhone.class) { - SipCall call = (getPhone() == SipPhone.this) - ? (SipCall) SipPhone.this.getBackgroundCall() - : (SipCall) SipPhone.this.getForegroundCall(); - if (call.getState() != Call.State.IDLE) { - throw new CallStateException( - "cannot put conn back to a call in non-idle state: " - + call.getState()); - } - if (DEBUG) Log.d(LOG_TAG, "separate conn: " - + mPeer.getUriString() + " from " + mOwner + " back to " - + call); - - // separate the AudioGroup and connection from the original call - Phone originalPhone = getPhone(); - AudioGroup audioGroup = call.getAudioGroup(); // may be null - call.add(this); - mSipAudioCall.setAudioGroup(audioGroup); - - // put the original call to bg; and the separated call becomes - // fg if it was in bg - originalPhone.switchHoldingAndActive(); - - // start audio and notify the phone app of the state change - call = (SipCall) SipPhone.this.getForegroundCall(); - mSipAudioCall.startAudio(); - call.onConnectionStateChanged(this); - } - } - - } - - private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) { - if (sipAudioCall.isOnHold()) return Call.State.HOLDING; - int sessionState = sipAudioCall.getState(); - switch (sessionState) { - case SipSession.State.READY_TO_CALL: return Call.State.IDLE; - case SipSession.State.INCOMING_CALL: - case SipSession.State.INCOMING_CALL_ANSWERING: return Call.State.INCOMING; - case SipSession.State.OUTGOING_CALL: return Call.State.DIALING; - case SipSession.State.OUTGOING_CALL_RING_BACK: return Call.State.ALERTING; - case SipSession.State.OUTGOING_CALL_CANCELING: return Call.State.DISCONNECTING; - case SipSession.State.IN_CALL: return Call.State.ACTIVE; - default: - Log.w(LOG_TAG, "illegal connection state: " + sessionState); - return Call.State.DISCONNECTED; - } - } - - private abstract class SipAudioCallAdapter extends SipAudioCall.Listener { - protected abstract void onCallEnded(Connection.DisconnectCause cause); - protected abstract void onError(Connection.DisconnectCause cause); - - @Override - public void onCallEnded(SipAudioCall call) { - onCallEnded(call.isInCall() - ? Connection.DisconnectCause.NORMAL - : Connection.DisconnectCause.INCOMING_MISSED); - } - - @Override - public void onCallBusy(SipAudioCall call) { - onCallEnded(Connection.DisconnectCause.BUSY); - } - - @Override - public void onError(SipAudioCall call, int errorCode, - String errorMessage) { - switch (errorCode) { - case SipErrorCode.SERVER_UNREACHABLE: - onError(Connection.DisconnectCause.SERVER_UNREACHABLE); - break; - case SipErrorCode.PEER_NOT_REACHABLE: - onError(Connection.DisconnectCause.NUMBER_UNREACHABLE); - break; - case SipErrorCode.INVALID_REMOTE_URI: - onError(Connection.DisconnectCause.INVALID_NUMBER); - break; - case SipErrorCode.TIME_OUT: - case SipErrorCode.TRANSACTION_TERMINTED: - onError(Connection.DisconnectCause.TIMED_OUT); - break; - case SipErrorCode.DATA_CONNECTION_LOST: - onError(Connection.DisconnectCause.LOST_SIGNAL); - break; - case SipErrorCode.INVALID_CREDENTIALS: - onError(Connection.DisconnectCause.INVALID_CREDENTIALS); - break; - case SipErrorCode.CROSS_DOMAIN_AUTHENTICATION: - onError(Connection.DisconnectCause.OUT_OF_NETWORK); - break; - case SipErrorCode.SERVER_ERROR: - onError(Connection.DisconnectCause.SERVER_ERROR); - break; - case SipErrorCode.SOCKET_ERROR: - case SipErrorCode.CLIENT_ERROR: - default: - Log.w(LOG_TAG, "error: " + SipErrorCode.toString(errorCode) - + ": " + errorMessage); - onError(Connection.DisconnectCause.ERROR_UNSPECIFIED); - } - } - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java deleted file mode 100755 index 5c4b446a78cf..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -import android.content.Context; -import android.net.LinkProperties; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.telephony.CellLocation; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.util.Log; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.DataConnection; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccPhoneBookInterfaceManager; -import com.android.internal.telephony.IccSmsInterfaceManager; -import com.android.internal.telephony.MmiCode; -import com.android.internal.telephony.OperatorInfo; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.PhoneNotifier; -import com.android.internal.telephony.PhoneSubInfo; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.UUSInfo; - -import java.util.ArrayList; -import java.util.List; - -abstract class SipPhoneBase extends PhoneBase { - private static final String LOG_TAG = "SipPhone"; - - private RegistrantList mRingbackRegistrants = new RegistrantList(); - private State state = State.IDLE; - - public SipPhoneBase(Context context, PhoneNotifier notifier) { - super(notifier, context, new SipCommandInterface(context), false); - } - - public abstract Call getForegroundCall(); - - public abstract Call getBackgroundCall(); - - public abstract Call getRingingCall(); - - public Connection dial(String dialString, UUSInfo uusInfo) - throws CallStateException { - // ignore UUSInfo - return dial(dialString); - } - - void migrateFrom(SipPhoneBase from) { - migrate(mRingbackRegistrants, from.mRingbackRegistrants); - migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants); - migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants); - migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants); - migrate(mDisconnectRegistrants, from.mDisconnectRegistrants); - migrate(mServiceStateRegistrants, from.mServiceStateRegistrants); - migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants); - migrate(mMmiRegistrants, from.mMmiRegistrants); - migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); - migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); - } - - static void migrate(RegistrantList to, RegistrantList from) { - from.removeCleared(); - for (int i = 0, n = from.size(); i < n; i++) { - to.add((Registrant) from.get(i)); - } - } - - @Override - public void registerForRingbackTone(Handler h, int what, Object obj) { - mRingbackRegistrants.addUnique(h, what, obj); - } - - @Override - public void unregisterForRingbackTone(Handler h) { - mRingbackRegistrants.remove(h); - } - - protected void startRingbackTone() { - AsyncResult result = new AsyncResult(null, Boolean.TRUE, null); - mRingbackRegistrants.notifyRegistrants(result); - } - - protected void stopRingbackTone() { - AsyncResult result = new AsyncResult(null, Boolean.FALSE, null); - mRingbackRegistrants.notifyRegistrants(result); - } - - public ServiceState getServiceState() { - // FIXME: we may need to provide this when data connectivity is lost - // or when server is down - ServiceState s = new ServiceState(); - s.setState(ServiceState.STATE_IN_SERVICE); - return s; - } - - public CellLocation getCellLocation() { - return null; - } - - public State getState() { - return state; - } - - public int getPhoneType() { - return Phone.PHONE_TYPE_SIP; - } - - public SignalStrength getSignalStrength() { - return new SignalStrength(); - } - - public boolean getMessageWaitingIndicator() { - return false; - } - - public boolean getCallForwardingIndicator() { - return false; - } - - public List getPendingMmiCodes() { - return new ArrayList(0); - } - - public DataState getDataConnectionState() { - return DataState.DISCONNECTED; - } - - public DataState getDataConnectionState(String apnType) { - return DataState.DISCONNECTED; - } - - public DataActivityState getDataActivityState() { - return DataActivityState.NONE; - } - - /** - * Notify any interested party of a Phone state change {@link Phone.State} - */ - void notifyPhoneStateChanged() { - mNotifier.notifyPhoneState(this); - } - - /** - * Notify registrants of a change in the call state. This notifies changes in {@link Call.State} - * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged. - */ - void notifyPreciseCallStateChanged() { - /* we'd love it if this was package-scoped*/ - super.notifyPreciseCallStateChangedP(); - } - - void notifyNewRingingConnection(Connection c) { - super.notifyNewRingingConnectionP(c); - } - - void notifyDisconnect(Connection cn) { - mDisconnectRegistrants.notifyResult(cn); - } - - void notifyUnknownConnection() { - mUnknownConnectionRegistrants.notifyResult(this); - } - - void notifySuppServiceFailed(SuppService code) { - mSuppServiceFailedRegistrants.notifyResult(code); - } - - void notifyServiceStateChanged(ServiceState ss) { - super.notifyServiceStateChangedP(ss); - } - - public void notifyCallForwardingIndicator() { - mNotifier.notifyCallForwardingChanged(this); - } - - public boolean canDial() { - int serviceState = getServiceState().getState(); - Log.v(LOG_TAG, "canDial(): serviceState = " + serviceState); - if (serviceState == ServiceState.STATE_POWER_OFF) return false; - - String disableCall = SystemProperties.get( - TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); - Log.v(LOG_TAG, "canDial(): disableCall = " + disableCall); - if (disableCall.equals("true")) return false; - - Log.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState()); - Log.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState()); - Log.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState()); - return !getRingingCall().isRinging() - && (!getForegroundCall().getState().isAlive() - || !getBackgroundCall().getState().isAlive()); - } - - public boolean handleInCallMmiCommands(String dialString) - throws CallStateException { - return false; - } - - boolean isInCall() { - Call.State foregroundCallState = getForegroundCall().getState(); - Call.State backgroundCallState = getBackgroundCall().getState(); - Call.State ringingCallState = getRingingCall().getState(); - - return (foregroundCallState.isAlive() || backgroundCallState.isAlive() - || ringingCallState.isAlive()); - } - - public boolean handlePinMmi(String dialString) { - return false; - } - - public void sendUssdResponse(String ussdMessge) { - } - - public void registerForSuppServiceNotification( - Handler h, int what, Object obj) { - } - - public void unregisterForSuppServiceNotification(Handler h) { - } - - public void setRadioPower(boolean power) { - } - - public String getVoiceMailNumber() { - return null; - } - - public String getVoiceMailAlphaTag() { - return null; - } - - public String getDeviceId() { - return null; - } - - public String getDeviceSvn() { - return null; - } - - public String getImei() { - return null; - } - - public String getEsn() { - Log.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method"); - return "0"; - } - - public String getMeid() { - Log.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method"); - return "0"; - } - - public String getSubscriberId() { - return null; - } - - public String getIccSerialNumber() { - return null; - } - - public String getLine1Number() { - return null; - } - - public String getLine1AlphaTag() { - return null; - } - - public void setLine1Number(String alphaTag, String number, Message onComplete) { - // FIXME: what to reply for SIP? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, - Message onComplete) { - // FIXME: what to reply for SIP? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { - } - - public void setCallForwardingOption(int commandInterfaceCFAction, - int commandInterfaceCFReason, String dialingNumber, - int timerSeconds, Message onComplete) { - } - - public void getOutgoingCallerIdDisplay(Message onComplete) { - // FIXME: what to reply? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, - Message onComplete) { - // FIXME: what's this for SIP? - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void getCallWaiting(Message onComplete) { - AsyncResult.forMessage(onComplete, null, null); - onComplete.sendToTarget(); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - Log.e(LOG_TAG, "call waiting not supported"); - } - - public boolean getIccRecordsLoaded() { - return false; - } - - public IccCard getIccCard() { - return null; - } - - public void getAvailableNetworks(Message response) { - } - - public void setNetworkSelectionModeAutomatic(Message response) { - } - - public void selectNetworkManually( - OperatorInfo network, - Message response) { - } - - public void getNeighboringCids(Message response) { - } - - public void setOnPostDialCharacter(Handler h, int what, Object obj) { - } - - public void getDataCallList(Message response) { - } - - public List getCurrentDataConnectionList () { - return null; - } - - public void updateServiceLocation() { - } - - public void enableLocationUpdates() { - } - - public void disableLocationUpdates() { - } - - public boolean getDataRoamingEnabled() { - return false; - } - - public void setDataRoamingEnabled(boolean enable) { - } - - public boolean enableDataConnectivity() { - return false; - } - - public boolean disableDataConnectivity() { - return false; - } - - public boolean isDataConnectivityPossible() { - return false; - } - - boolean updateCurrentCarrierInProvider() { - return false; - } - - public void saveClirSetting(int commandInterfaceCLIRMode) { - } - - public PhoneSubInfo getPhoneSubInfo(){ - return null; - } - - public IccSmsInterfaceManager getIccSmsInterfaceManager(){ - return null; - } - - public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ - return null; - } - - public IccFileHandler getIccFileHandler(){ - return null; - } - - public void activateCellBroadcastSms(int activate, Message response) { - Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); - } - - public void getCellBroadcastSmsConfig(Message response) { - Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); - } - - public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){ - Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); - } - - //@Override - public boolean needsOtaServiceProvisioning() { - // FIXME: what's this for SIP? - return false; - } - - //@Override - public LinkProperties getLinkProperties(String apnType) { - // FIXME: what's this for SIP? - return null; - } - - void updatePhoneState() { - State oldState = state; - - if (getRingingCall().isRinging()) { - state = State.RINGING; - } else if (getForegroundCall().isIdle() - && getBackgroundCall().isIdle()) { - state = State.IDLE; - } else { - state = State.OFFHOOK; - } - - if (state != oldState) { - Log.d(LOG_TAG, " ^^^ new phone state: " + state); - notifyPhoneStateChanged(); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java deleted file mode 100644 index 611e3ea020ec..000000000000 --- a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.sip; - -import com.android.internal.telephony.PhoneNotifier; - -import android.content.Context; -import android.net.sip.SipProfile; -import android.util.Log; - -import java.text.ParseException; - -/** - * {@hide} - */ -public class SipPhoneFactory { - /** - * Makes a {@link SipPhone} object. - * @param sipUri the local SIP URI the phone runs on - * @param context {@code Context} needed to create a Phone object - * @param phoneNotifier {@code PhoneNotifier} needed to create a Phone - * object - * @return the {@code SipPhone} object or null if the SIP URI is not valid - */ - public static SipPhone makePhone(String sipUri, Context context, - PhoneNotifier phoneNotifier) { - try { - SipProfile profile = new SipProfile.Builder(sipUri).build(); - return new SipPhone(context, phoneNotifier, profile); - } catch (ParseException e) { - Log.w("SipPhoneFactory", "makePhone", e); - return null; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java deleted file mode 100644 index b116c354c118..000000000000 --- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java +++ /dev/null @@ -1,741 +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.test; - -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.List; - -// Also in ATChannel.java -class LineReader -{ - /** - * Not threadsafe - * Assumes input is ASCII - */ - - //***** Constants - - // For what it's worth, this is also the size of an - // OMAP CSMI mailbox - static final int BUFFER_SIZE = 0x1000; - - // just to prevent constant allocations - byte buffer[] = new byte[BUFFER_SIZE]; - - //***** Instance Variables - - InputStream inStream; - - LineReader (InputStream s) - { - inStream = s; - } - - String - getNextLine() - { - return getNextLine(false); - } - - String - getNextLineCtrlZ() - { - return getNextLine(true); - } - - /** - * Note: doesn't return the last incomplete line read on EOF, since - * it doesn't typically matter anyway - * - * Returns NULL on EOF - */ - - String - getNextLine(boolean ctrlZ) - { - int i = 0; - - try { - for (;;) { - int result; - - result = inStream.read(); - - if (result < 0) { - return null; - } - - if (ctrlZ && result == 0x1a) { - break; - } else if (result == '\r' || result == '\n') { - if (i == 0) { - // Skip leading cr/lf - continue; - } else { - break; - } - } - - buffer[i++] = (byte)result; - } - } catch (IOException ex) { - return null; - } catch (IndexOutOfBoundsException ex) { - System.err.println("ATChannel: buffer overflow"); - } - - try { - return new String(buffer, 0, i, "US-ASCII"); - } catch (UnsupportedEncodingException ex) { - System.err.println("ATChannel: implausable UnsupportedEncodingException"); - return null; - } - } -} - - - -class InterpreterEx extends Exception -{ - public - InterpreterEx (String result) - { - this.result = result; - } - - String result; -} - -public class ModelInterpreter - implements Runnable, SimulatedRadioControl -{ - static final int MAX_CALLS = 6; - - /** number of msec between dialing -> alerting and alerting->active */ - static final int CONNECTING_PAUSE_MSEC = 5 * 100; - - static final String LOG_TAG = "ModelInterpreter"; - - //***** Instance Variables - - InputStream in; - OutputStream out; - LineReader lineReader; - ServerSocket ss; - - private String finalResponse; - - SimulatedGsmCallState simulatedCallState; - - HandlerThread mHandlerThread; - - int pausedResponseCount; - Object pausedResponseMonitor = new Object(); - - //***** Events - - static final int PROGRESS_CALL_STATE = 1; - - //***** Constructor - - public - ModelInterpreter (InputStream in, OutputStream out) - { - this.in = in; - this.out = out; - - init(); - } - - public - ModelInterpreter (InetSocketAddress sa) throws java.io.IOException - { - ss = new ServerSocket(); - - ss.setReuseAddress(true); - ss.bind(sa); - - init(); - } - - private void - init() - { - new Thread(this, "ModelInterpreter").start(); - mHandlerThread = new HandlerThread("ModelInterpreter"); - mHandlerThread.start(); - Looper looper = mHandlerThread.getLooper(); - simulatedCallState = new SimulatedGsmCallState(looper); - } - - //***** Runnable Implementation - - public void run() - { - for (;;) { - if (ss != null) { - Socket s; - - try { - s = ss.accept(); - } catch (java.io.IOException ex) { - Log.w(LOG_TAG, - "IOException on socket.accept(); stopping", ex); - return; - } - - try { - in = s.getInputStream(); - out = s.getOutputStream(); - } catch (java.io.IOException ex) { - Log.w(LOG_TAG, - "IOException on accepted socket(); re-listening", ex); - continue; - } - - Log.i(LOG_TAG, "New connection accepted"); - } - - - lineReader = new LineReader (in); - - println ("Welcome"); - - for (;;) { - String line; - - line = lineReader.getNextLine(); - - //System.out.println("MI<< " + line); - - if (line == null) { - break; - } - - synchronized(pausedResponseMonitor) { - while (pausedResponseCount > 0) { - try { - pausedResponseMonitor.wait(); - } catch (InterruptedException ex) { - } - } - } - - synchronized (this) { - try { - finalResponse = "OK"; - processLine(line); - println(finalResponse); - } catch (InterpreterEx ex) { - println(ex.result); - } catch (RuntimeException ex) { - ex.printStackTrace(); - println("ERROR"); - } - } - } - - Log.i(LOG_TAG, "Disconnected"); - - if (ss == null) { - // no reconnect in this case - break; - } - } - } - - - //***** Instance Methods - - /** Start the simulated phone ringing */ - public void - triggerRing(String number) - { - synchronized (this) { - boolean success; - - success = simulatedCallState.triggerRing(number); - - if (success) { - println ("RING"); - } - } - } - - /** If a call is DIALING or ALERTING, progress it to the next state */ - public void - progressConnectingCallState() - { - simulatedCallState.progressConnectingCallState(); - } - - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() - { - simulatedCallState.progressConnectingToActive(); - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) - { - simulatedCallState.setAutoProgressConnectingCall(b); - } - - public void - setNextDialFailImmediately(boolean b) - { - simulatedCallState.setNextDialFailImmediately(b); - } - - public void setNextCallFailCause(int gsmCause) - { - //FIXME implement - } - - - /** hangup ringing, dialing, or actuve calls */ - public void - triggerHangupForeground() - { - boolean success; - - success = simulatedCallState.triggerHangupForeground(); - - if (success) { - println ("NO CARRIER"); - } - } - - /** hangup holding calls */ - public void - triggerHangupBackground() - { - boolean success; - - success = simulatedCallState.triggerHangupBackground(); - - if (success) { - println ("NO CARRIER"); - } - } - - /** hangup all */ - - public void - triggerHangupAll() - { - boolean success; - - success = simulatedCallState.triggerHangupAll(); - - if (success) { - println ("NO CARRIER"); - } - } - - public void - sendUnsolicited (String unsol) - { - synchronized (this) { - println(unsol); - } - } - - public void triggerSsn(int a, int b) {} - public void triggerIncomingUssd(String statusCode, String message) {} - - public void - triggerIncomingSMS(String message) - { -/************** - StringBuilder pdu = new StringBuilder(); - - pdu.append ("00"); //SMSC address - 0 bytes - - pdu.append ("04"); // Message type indicator - - // source address: +18005551212 - pdu.append("918100551521F0"); - - // protocol ID and data coding scheme - pdu.append("0000"); - - Calendar c = Calendar.getInstance(); - - pdu.append (c. - - - - synchronized (this) { - println("+CMT: ,1\r" + pdu.toString()); - } - -**************/ - } - - public void - pauseResponses() - { - synchronized(pausedResponseMonitor) { - pausedResponseCount++; - } - } - - public void - resumeResponses() - { - synchronized(pausedResponseMonitor) { - pausedResponseCount--; - - if (pausedResponseCount == 0) { - pausedResponseMonitor.notifyAll(); - } - } - } - - //***** Private Instance Methods - - private void - onAnswer() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.onAnswer(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onHangup() throws InterpreterEx - { - boolean success = false; - - success = simulatedCallState.onAnswer(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - - finalResponse = "NO CARRIER"; - } - - private void - onCHLD(String command) throws InterpreterEx - { - // command starts with "+CHLD=" - char c0; - char c1 = 0; - boolean success; - - c0 = command.charAt(6); - - if (command.length() >= 8) { - c1 = command.charAt(7); - } - - success = simulatedCallState.onChld(c0, c1); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - releaseHeldOrUDUB() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.releaseHeldOrUDUB(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - releaseActiveAcceptHeldOrWaiting() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.releaseActiveAcceptHeldOrWaiting(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - switchActiveAndHeldOrWaiting() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.switchActiveAndHeldOrWaiting(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - separateCall(int index) throws InterpreterEx - { - boolean success; - - success = simulatedCallState.separateCall(index); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - conference() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.conference(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onDial(String command) throws InterpreterEx - { - boolean success; - - success = simulatedCallState.onDial(command.substring(1)); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onCLCC() throws InterpreterEx - { - List lines; - - lines = simulatedCallState.getClccLines(); - - for (int i = 0, s = lines.size() ; i < s ; i++) { - println (lines.get(i)); - } - } - - private void - onSMSSend(String command) throws InterpreterEx - { - String pdu; - - print ("> "); - pdu = lineReader.getNextLineCtrlZ(); - - println("+CMGS: 1"); - } - - void - processLine (String line) throws InterpreterEx - { - String[] commands; - - commands = splitCommands(line); - - for (int i = 0; i < commands.length ; i++) { - String command = commands[i]; - - if (command.equals("A")) { - onAnswer(); - } else if (command.equals("H")) { - onHangup(); - } else if (command.startsWith("+CHLD=")) { - onCHLD(command); - } else if (command.equals("+CLCC")) { - onCLCC(); - } else if (command.startsWith("D")) { - onDial(command); - } else if (command.startsWith("+CMGS=")) { - onSMSSend(command); - } else { - boolean found = false; - - for (int j = 0; j < sDefaultResponses.length ; j++) { - if (command.equals(sDefaultResponses[j][0])) { - String r = sDefaultResponses[j][1]; - if (r != null) { - println(r); - } - found = true; - break; - } - } - - if (!found) { - throw new InterpreterEx ("ERROR"); - } - } - } - } - - - String[] - splitCommands(String line) throws InterpreterEx - { - if (!line.startsWith ("AT")) { - throw new InterpreterEx("ERROR"); - } - - if (line.length() == 2) { - // Just AT by itself - return new String[0]; - } - - String ret[] = new String[1]; - - //TODO fix case here too - ret[0] = line.substring(2); - - return ret; -/**** - try { - // i = 2 to skip over AT - for (int i = 2, s = line.length() ; i < s ; i++) { - // r"|([A-RT-Z]\d?)" # Normal commands eg ATA or I0 - // r"|(&[A-Z]\d*)" # & commands eg &C - // r"|(S\d+(=\d+)?)" # S registers - // r"((\+|%)\w+(\?|=([^;]+(;|$)))?)" # extended command eg +CREG=2 - - - } - } catch (StringIndexOutOfBoundsException ex) { - throw new InterpreterEx ("ERROR"); - } -***/ - } - - void - println (String s) - { - synchronized(this) { - try { - byte[] bytes = s.getBytes("US-ASCII"); - - //System.out.println("MI>> " + s); - - out.write(bytes); - out.write('\r'); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - void - print (String s) - { - synchronized(this) { - try { - byte[] bytes = s.getBytes("US-ASCII"); - - //System.out.println("MI>> " + s + " (no )"); - - out.write(bytes); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - - public void - shutdown() - { - Looper looper = mHandlerThread.getLooper(); - if (looper != null) { - looper.quit(); - } - - try { - in.close(); - } catch (IOException ex) { - } - try { - out.close(); - } catch (IOException ex) { - } - } - - - static final String [][] sDefaultResponses = { - {"E0Q0V1", null}, - {"+CMEE=2", null}, - {"+CREG=2", null}, - {"+CGREG=2", null}, - {"+CCWA=1", null}, - {"+COPS=0", null}, - {"+CFUN=1", null}, - {"+CGMI", "+CGMI: Android Model AT Interpreter\r"}, - {"+CGMM", "+CGMM: Android Model AT Interpreter\r"}, - {"+CGMR", "+CGMR: 1.0\r"}, - {"+CGSN", "000000000000000\r"}, - {"+CIMI", "320720000000000\r"}, - {"+CSCS=?", "+CSCS: (\"HEX\",\"UCS2\")\r"}, - {"+CFUN?", "+CFUN: 1\r"}, - {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", - "+COPS: 0,0,\"Android\"\r" - + "+COPS: 0,1,\"Android\"\r" - + "+COPS: 0,2,\"310995\"\r"}, - {"+CREG?", "+CREG: 2,5, \"0113\", \"6614\"\r"}, - {"+CGREG?", "+CGREG: 2,0\r"}, - {"+CSQ", "+CSQ: 16,99\r"}, - {"+CNMI?", "+CNMI: 1,2,2,1,1\r"}, - {"+CLIR?", "+CLIR: 1,3\r"}, - {"%CPVWI=2", "%CPVWI: 0\r"}, - {"+CUSD=1,\"#646#\"", "+CUSD=0,\"You have used 23 minutes\"\r"}, - {"+CRSM=176,12258,0,0,10", "+CRSM: 144,0,981062200050259429F6\r"}, - {"+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000A2FE204000FF55501020000\r"}, - - /* EF[ADN] */ - {"+CRSM=192,28474,0,0,15", "+CRSM: 144,0,0000005a6f3a040011f5220102011e\r"}, - {"+CRSM=178,28474,1,4,30", "+CRSM: 144,0,437573746f6d65722043617265ffffff07818100398799f7ffffffffffff\r"}, - {"+CRSM=178,28474,2,4,30", "+CRSM: 144,0,566f696365204d61696cffffffffffff07918150367742f3ffffffffffff\r"}, - {"+CRSM=178,28474,3,4,30", "+CRSM: 144,0,4164676a6dffffffffffffffffffffff0b918188551512c221436587ff01\r"}, - {"+CRSM=178,28474,4,4,30", "+CRSM: 144,0,810101c1ffffffffffffffffffffffff068114455245f8ffffffffffffff\r"}, - /* EF[EXT1] */ - {"+CRSM=192,28490,0,0,15", "+CRSM: 144,0,000000416f4a040011f5550102010d\r"}, - {"+CRSM=178,28490,1,4,13", "+CRSM: 144,0,0206092143658709ffffffffff\r"} - }; -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java deleted file mode 100644 index 4f61509f918d..000000000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java +++ /dev/null @@ -1,1525 +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.test; - -import android.os.AsyncResult; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.BaseCommands; -import com.android.internal.telephony.CommandException; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.DataCallState; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.UUSInfo; -import com.android.internal.telephony.gsm.CallFailCause; -import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; -import com.android.internal.telephony.gsm.SuppServiceNotification; - -import java.util.ArrayList; - -public final class SimulatedCommands extends BaseCommands - implements CommandsInterface, SimulatedRadioControl { - private final static String LOG_TAG = "SIM"; - - private enum SimLockState { - NONE, - REQUIRE_PIN, - REQUIRE_PUK, - SIM_PERM_LOCKED - } - - private enum SimFdnState { - NONE, - REQUIRE_PIN2, - REQUIRE_PUK2, - SIM_PERM_LOCKED - } - - private final static SimLockState INITIAL_LOCK_STATE = SimLockState.NONE; - private final static String DEFAULT_SIM_PIN_CODE = "1234"; - private final static String SIM_PUK_CODE = "12345678"; - private final static SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE; - private final static String DEFAULT_SIM_PIN2_CODE = "5678"; - private final static String SIM_PUK2_CODE = "87654321"; - - //***** Instance Variables - - SimulatedGsmCallState simulatedCallState; - HandlerThread mHandlerThread; - SimLockState mSimLockedState; - boolean mSimLockEnabled; - int mPinUnlockAttempts; - int mPukUnlockAttempts; - String mPinCode; - SimFdnState mSimFdnEnabledState; - boolean mSimFdnEnabled; - int mPin2UnlockAttempts; - int mPuk2UnlockAttempts; - int mNetworkType; - String mPin2Code; - boolean mSsnNotifyOn = false; - - int pausedResponseCount; - ArrayList pausedResponses = new ArrayList(); - - int nextCallFailCause = CallFailCause.NORMAL_CLEARING; - - //***** Constructor - - public - SimulatedCommands() { - super(null); // Don't log statistics - mHandlerThread = new HandlerThread("SimulatedCommands"); - mHandlerThread.start(); - Looper looper = mHandlerThread.getLooper(); - - simulatedCallState = new SimulatedGsmCallState(looper); - - setRadioState(RadioState.RADIO_OFF); - mSimLockedState = INITIAL_LOCK_STATE; - mSimLockEnabled = (mSimLockedState != SimLockState.NONE); - mPinCode = DEFAULT_SIM_PIN_CODE; - mSimFdnEnabledState = INITIAL_FDN_STATE; - mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE); - mPin2Code = DEFAULT_SIM_PIN2_CODE; - } - - //***** CommandsInterface implementation - - public void getIccCardStatus(Message result) { - unimplemented(result); - } - - public void supplyIccPin(String pin, Message result) { - if (mSimLockedState != SimLockState.REQUIRE_PIN) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (pin != null && pin.equals(mPinCode)) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin: success!"); - mPinUnlockAttempts = 0; - mSimLockedState = SimLockState.NONE; - mIccStatusChangedRegistrants.notifyRegistrants(); - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPinUnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplyIccPin: failed! attempt=" + - mPinUnlockAttempts); - if (mPinUnlockAttempts >= 3) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin: set state to REQUIRE_PUK"); - mSimLockedState = SimLockState.REQUIRE_PUK; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplyIccPuk(String puk, String newPin, Message result) { - if (mSimLockedState != SimLockState.REQUIRE_PUK) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (puk != null && puk.equals(SIM_PUK_CODE)) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!"); - mSimLockedState = SimLockState.NONE; - mPukUnlockAttempts = 0; - mIccStatusChangedRegistrants.notifyRegistrants(); - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPukUnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: failed! attempt=" + - mPukUnlockAttempts); - if (mPukUnlockAttempts >= 10) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: set state to SIM_PERM_LOCKED"); - mSimLockedState = SimLockState.SIM_PERM_LOCKED; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplyIccPin2(String pin2, Message result) { - if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: wrong state, state=" + - mSimFdnEnabledState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (pin2 != null && pin2.equals(mPin2Code)) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: success!"); - mPin2UnlockAttempts = 0; - mSimFdnEnabledState = SimFdnState.NONE; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPin2UnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: failed! attempt=" + - mPin2UnlockAttempts); - if (mPin2UnlockAttempts >= 3) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: set state to REQUIRE_PUK2"); - mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplyIccPuk2(String puk2, String newPin2, Message result) { - if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: success!"); - mSimFdnEnabledState = SimFdnState.NONE; - mPuk2UnlockAttempts = 0; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPuk2UnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: failed! attempt=" + - mPuk2UnlockAttempts); - if (mPuk2UnlockAttempts >= 10) { - Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: set state to SIM_PERM_LOCKED"); - mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void changeIccPin(String oldPin, String newPin, Message result) { - if (oldPin != null && oldPin.equals(mPinCode)) { - mPinCode = newPin; - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] changeIccPin: pin failed!"); - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void changeIccPin2(String oldPin2, String newPin2, Message result) { - if (oldPin2 != null && oldPin2.equals(mPin2Code)) { - mPin2Code = newPin2; - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] changeIccPin2: pin2 failed!"); - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void - changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) { - unimplemented(result); - } - - public void - setSuppServiceNotifications(boolean enable, Message result) { - resultSuccess(result, null); - - if (enable && mSsnNotifyOn) { - Log.w(LOG_TAG, "Supp Service Notifications already enabled!"); - } - - mSsnNotifyOn = enable; - } - - @Override - public void queryFacilityLock(String facility, String pin, - int serviceClass, Message result) { - queryFacilityLockForApp(facility, pin, serviceClass, null, result); - } - - @Override - public void queryFacilityLockForApp(String facility, String pin, int serviceClass, - String appId, Message result) { - if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) { - if (result != null) { - int[] r = new int[1]; - r[0] = (mSimLockEnabled ? 1 : 0); - Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is " - + (r[0] == 0 ? "unlocked" : "locked")); - AsyncResult.forMessage(result, r, null); - result.sendToTarget(); - } - return; - } else if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) { - if (result != null) { - int[] r = new int[1]; - r[0] = (mSimFdnEnabled ? 1 : 0); - Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is " - + (r[0] == 0 ? "disabled" : "enabled")); - AsyncResult.forMessage(result, r, null); - result.sendToTarget(); - } - return; - } - - unimplemented(result); - } - - @Override - public void setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass, - Message result) { - setFacilityLockForApp(facility, lockEnabled, pin, serviceClass, null, result); - } - - @Override - public void setFacilityLockForApp(String facility, boolean lockEnabled, - String pin, int serviceClass, String appId, - Message result) { - if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) { - if (pin != null && pin.equals(mPinCode)) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid"); - mSimLockEnabled = lockEnabled; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!"); - - CommandException ex = new CommandException( - CommandException.Error.GENERIC_FAILURE); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - - return; - } else if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) { - if (pin != null && pin.equals(mPin2Code)) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid"); - mSimFdnEnabled = lockEnabled; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!"); - - CommandException ex = new CommandException( - CommandException.Error.GENERIC_FAILURE); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - - return; - } - - unimplemented(result); - } - - public void supplyNetworkDepersonalization(String netpin, Message result) { - unimplemented(result); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result contains a List of DriverCall - * The ar.result List is sorted by DriverCall.index - */ - public void getCurrentCalls (Message result) { - if ((mState == RadioState.RADIO_ON) && !isSimLocked()) { - //Log.i("GSM", "[SimCmds] getCurrentCalls"); - resultSuccess(result, simulatedCallState.getDriverCalls()); - } else { - //Log.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!"); - resultFail(result, - new CommandException( - CommandException.Error.RADIO_NOT_AVAILABLE)); - } - } - - /** - * @deprecated - */ - public void getPDPContextList(Message result) { - getDataCallList(result); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result contains a List of DataCallState - */ - public void getDataCallList(Message result) { - resultSuccess(result, new ArrayList(0)); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - public void dial (String address, int clirMode, Message result) { - simulatedCallState.onDial(address); - - resultSuccess(result, null); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { - simulatedCallState.onDial(address); - - resultSuccess(result, null); - } - - public void getIMSI(Message result) { - getIMSIForApp(null, result); - } - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is String containing IMSI on success - */ - public void getIMSIForApp(String aid, Message result) { - resultSuccess(result, "012345678901234"); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is String containing IMEI on success - */ - public void getIMEI(Message result) { - resultSuccess(result, "012345678901234"); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is String containing IMEISV on success - */ - public void getIMEISV(Message result) { - resultSuccess(result, "99"); - } - - /** - * Hang up one individual connection. - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - * - * 3GPP 22.030 6.5.5 - * "Releases a specific active call X" - */ - public void hangupConnection (int gsmIndex, Message result) { - boolean success; - - success = simulatedCallState.onChld('1', (char)('0'+gsmIndex)); - - if (!success){ - Log.i("GSM", "[SimCmd] hangupConnection: resultFail"); - resultFail(result, new RuntimeException("Hangup Error")); - } else { - Log.i("GSM", "[SimCmd] hangupConnection: resultSuccess"); - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Releases all held calls or sets User Determined User Busy (UDUB) - * for a waiting call." - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void hangupWaitingOrBackground (Message result) { - boolean success; - - success = simulatedCallState.onChld('0', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Releases all active calls (if any exist) and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void hangupForegroundResumeBackground (Message result) { - boolean success; - - success = simulatedCallState.onChld('1', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls (if any exist) on hold and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void switchWaitingOrHoldingAndActive (Message result) { - boolean success; - - success = simulatedCallState.onChld('2', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Adds a held call to the conversation" - * - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void conference (Message result) { - boolean success; - - success = simulatedCallState.onChld('3', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Connects the two calls and disconnects the subscriber from both calls" - * - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void explicitCallTransfer (Message result) { - boolean success; - - success = simulatedCallState.onChld('4', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls on hold except call X with which - * communication shall be supported." - */ - public void separateConnection (int gsmIndex, Message result) { - boolean success; - - char ch = (char)(gsmIndex + '0'); - success = simulatedCallState.onChld('2', ch); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void acceptCall (Message result) { - boolean success; - - success = simulatedCallState.onAnswer(); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * also known as UDUB - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void rejectCall (Message result) { - boolean success; - - success = simulatedCallState.onChld('0', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * cause code returned as Integer in Message.obj.response - * Returns integer cause code defined in TS 24.008 - * Annex H or closest approximation. - * Most significant codes: - * - Any defined in 22.001 F.4 (for generating busy/congestion) - * - Cause 68: ACM >= ACMMax - */ - public void getLastCallFailCause (Message result) { - int[] ret = new int[1]; - - ret[0] = nextCallFailCause; - resultSuccess(result, ret); - } - - /** - * @deprecated - */ - public void getLastPdpFailCause (Message result) { - unimplemented(result); - } - - public void getLastDataCallFailCause(Message result) { - // - unimplemented(result); - } - - public void setMute (boolean enableMute, Message result) {unimplemented(result);} - - public void getMute (Message result) {unimplemented(result);} - - /** - * response.obj is an AsyncResult - * response.obj.result is an int[2] - * response.obj.result[0] is received signal strength (0-31, 99) - * response.obj.result[1] is bit error rate (0-7, 99) - * as defined in TS 27.007 8.5 - */ - public void getSignalStrength (Message result) { - int ret[] = new int[2]; - - ret[0] = 23; - ret[1] = 0; - - resultSuccess(result, ret); - } - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param result is callback message - */ - public void setBandMode (int bandMode, Message result) { - resultSuccess(result, null); - } - - /** - * Query the list of band mode supported by RF. - * - * @param result is callback message - * ((AsyncResult)response.obj).result is an int[] with every - * element representing one available BM_*_BAND - */ - public void queryAvailableBandMode (Message result) { - int ret[] = new int [4]; - - ret[0] = 4; - ret[1] = Phone.BM_US_BAND; - ret[2] = Phone.BM_JPN_BAND; - ret[3] = Phone.BM_AUS_BAND; - - resultSuccess(result, ret); - } - - /** - * {@inheritDoc} - */ - public void sendTerminalResponse(String contents, Message response) { - resultSuccess(response, null); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelope(String contents, Message response) { - resultSuccess(response, null); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelopeWithStatus(String contents, Message response) { - resultSuccess(response, null); - } - - /** - * {@inheritDoc} - */ - public void handleCallSetupRequestFromSim( - boolean accept, Message response) { - resultSuccess(response, null); - } - - /** - * response.obj.result is an String[14] - * See ril.h for details - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - public void getVoiceRegistrationState (Message result) { - String ret[] = new String[14]; - - ret[0] = "5"; // registered roam - ret[1] = null; - ret[2] = null; - ret[3] = null; - ret[4] = null; - ret[5] = null; - ret[6] = null; - ret[7] = null; - ret[8] = null; - ret[9] = null; - ret[10] = null; - ret[11] = null; - ret[12] = null; - ret[13] = null; - - resultSuccess(result, ret); - } - - /** - * response.obj.result is an String[4] - * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2 - * response.obj.result[1] is LAC if registered or NULL if not - * response.obj.result[2] is CID if registered or NULL if not - * response.obj.result[3] indicates the available radio technology, where: - * 0 == unknown - * 1 == GPRS only - * 2 == EDGE - * 3 == UMTS - * - * valid LAC are 0x0000 - 0xffff - * valid CID are 0x00000000 - 0xffffffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" in the Android telephony system - */ - public void getDataRegistrationState (Message result) { - String ret[] = new String[4]; - - ret[0] = "5"; // registered roam - ret[1] = null; - ret[2] = null; - ret[3] = "2"; - - resultSuccess(result, ret); - } - - /** - * response.obj.result is a String[3] - * response.obj.result[0] is long alpha or null if unregistered - * response.obj.result[1] is short alpha or null if unregistered - * response.obj.result[2] is numeric or null if unregistered - */ - public void getOperator(Message result) { - String[] ret = new String[3]; - - ret[0] = "El Telco Loco"; - ret[1] = "Telco Loco"; - ret[2] = "001001"; - - resultSuccess(result, ret); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void sendDtmf(char c, Message result) { - resultSuccess(result, null); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void startDtmf(char c, Message result) { - resultSuccess(result, null); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void stopDtmf(Message result) { - resultSuccess(result, null); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the original value of result.obj - * ar.result is null on success and failure - */ - public void sendBurstDtmf(String dtmfString, int on, int off, Message result) { - resultSuccess(result, null); - } - - /** - * smscPDU is smsc address in PDU form GSM BCD format prefixed - * by a length byte (as expected by TS 27.005) or NULL for default SMSC - * pdu is SMS in PDU format as an ASCII hex string - * less the SMSC address - */ - public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);} - - public void deleteSmsOnSim(int index, Message response) { - Log.d(LOG_TAG, "Delete message at index " + index); - 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 setupDataCall(String radioTechnology, String profile, - String apn, String user, String password, String authType, - String protocol, Message result) { - unimplemented(result); - } - - public void deactivateDataCall(int cid, int reason, Message result) {unimplemented(result);} - - public void setPreferredNetworkType(int networkType , Message result) { - mNetworkType = networkType; - resultSuccess(result, null); - } - - public void getPreferredNetworkType(Message result) { - int ret[] = new int[1]; - - ret[0] = mNetworkType; - resultSuccess(result, ret); - } - - public void getNeighboringCids(Message result) { - int ret[] = new int[7]; - - ret[0] = 6; - for (int i = 1; i<7; i++) { - ret[i] = i; - } - resultSuccess(result, ret); - } - - public void setLocationUpdates(boolean enable, Message response) { - unimplemented(response); - } - - public void getSmscAddress(Message result) { - unimplemented(result); - } - - public void setSmscAddress(String address, Message result) { - unimplemented(result); - } - - public void reportSmsMemoryStatus(boolean available, Message result) { - unimplemented(result); - } - - public void reportStkServiceIsRunning(Message result) { - resultSuccess(result, null); - } - - @Override - public void getCdmaSubscriptionSource(Message result) { - unimplemented(result); - } - - private boolean isSimLocked() { - if (mSimLockedState != SimLockState.NONE) { - return true; - } - return false; - } - - public void setRadioPower(boolean on, Message result) { - if(on) { - setRadioState(RadioState.RADIO_ON); - } else { - setRadioState(RadioState.RADIO_OFF); - } - } - - - public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) { - unimplemented(result); - } - - public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) { - unimplemented(result); - } - - public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, - Message result) { - unimplemented(result); - } - - public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data, - String pin2, Message response) { - iccIOForApp(command, fileid, path, p1, p2, p3, data,pin2, null, response); - } - - /** - * parameters equivalent to 27.007 AT+CRSM command - * response.obj will be an AsyncResult - * response.obj.userObj will be a SimIoResult on success - */ - public void iccIOForApp (int command, int fileid, String path, int p1, int p2, - int p3, String data, String pin2, String aid, Message result) { - unimplemented(result); - } - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned". - * - * @param response is callback message - */ - public void queryCLIP(Message response) { unimplemented(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 - * - * 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 - */ - - public void getCLIR(Message result) {unimplemented(result);} - - /** - * clirMode is one of the CLIR_* constants above - * - * response.obj is null - */ - - public void setCLIR(int clirMode, Message result) {unimplemented(result);} - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 0 for disabled, 1 for enabled. - * - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - public void queryCallWaiting(int serviceClass, Message response) { - unimplemented(response); - } - - /** - * @param enable is true to enable, false to disable - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - public void setCallWaiting(boolean enable, int serviceClass, - Message response) { - unimplemented(response); - } - - /** - * @param action is one of CF_ACTION_* - * @param cfReason is one of CF_REASON_* - * @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);} - - /** - * 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" - */ - public void queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message result) {unimplemented(result);} - - public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);} - public void exitEmergencyCallbackMode(Message result) {unimplemented(result);} - public void setNetworkSelectionModeManual( - String operatorNumeric, Message result) {unimplemented(result);} - - /** - * Queries whether the current network selection mode is automatic - * or manual - * - * ((AsyncResult)response.obj).result is an int[] with element [0] being - * a 0 for automatic selection and a 1 for manual selection - */ - - public void getNetworkSelectionMode(Message result) { - int ret[] = new int[1]; - - ret[0] = 0; - resultSuccess(result, ret); - } - - /** - * Queries the currently available networks - * - * ((AsyncResult)response.obj).result is a List of NetworkInfo objects - */ - public void getAvailableNetworks(Message result) {unimplemented(result);} - - public void getBasebandVersion (Message result) { - resultSuccess(result, "SimulatedCommands"); - } - - /** - * Simulates an incoming USSD message - * @param statusCode Status code string. See setOnUSSD - * in CommandsInterface.java - * @param message Message text to send or null if none - */ - public void triggerIncomingUssd(String statusCode, String message) { - if (mUSSDRegistrant != null) { - String[] result = {statusCode, message}; - mUSSDRegistrant.notifyResult(result); - } - } - - - public void sendUSSD (String ussdString, Message result) { - - // We simulate this particular sequence - if (ussdString.equals("#646#")) { - resultSuccess(result, null); - - // 0 == USSD-Notify - triggerIncomingUssd("0", "You have NNN minutes remaining."); - } else { - resultSuccess(result, null); - - triggerIncomingUssd("0", "All Done"); - } - } - - // inherited javadoc suffices - public void cancelPendingUssd (Message response) { - resultSuccess(response, null); - } - - - public void resetRadio(Message result) { - unimplemented(result); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) { - // Just echo back data - if (response != null) { - AsyncResult.forMessage(response).result = data; - response.sendToTarget(); - } - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) { - // Just echo back data - if (response != null) { - AsyncResult.forMessage(response).result = strings; - response.sendToTarget(); - } - } - - //***** SimulatedRadioControl - - - /** Start the simulated phone ringing */ - public void - triggerRing(String number) { - simulatedCallState.triggerRing(number); - mCallStateRegistrants.notifyRegistrants(); - } - - public void - progressConnectingCallState() { - simulatedCallState.progressConnectingCallState(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() { - simulatedCallState.progressConnectingToActive(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) { - simulatedCallState.setAutoProgressConnectingCall(b); - } - - public void - setNextDialFailImmediately(boolean b) { - simulatedCallState.setNextDialFailImmediately(b); - } - - public void - setNextCallFailCause(int gsmCause) { - nextCallFailCause = gsmCause; - } - - public void - triggerHangupForeground() { - simulatedCallState.triggerHangupForeground(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** hangup holding calls */ - public void - triggerHangupBackground() { - simulatedCallState.triggerHangupBackground(); - mCallStateRegistrants.notifyRegistrants(); - } - - public void triggerSsn(int type, int code) { - SuppServiceNotification not = new SuppServiceNotification(); - not.notificationType = type; - not.code = code; - mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null)); - } - - public void - shutdown() { - setRadioState(RadioState.RADIO_UNAVAILABLE); - Looper looper = mHandlerThread.getLooper(); - if (looper != null) { - looper.quit(); - } - } - - /** hangup all */ - - public void - triggerHangupAll() { - simulatedCallState.triggerHangupAll(); - mCallStateRegistrants.notifyRegistrants(); - } - - public void - triggerIncomingSMS(String message) { - //TODO - } - - public void - pauseResponses() { - pausedResponseCount++; - } - - public void - resumeResponses() { - pausedResponseCount--; - - if (pausedResponseCount == 0) { - for (int i = 0, s = pausedResponses.size(); i < s ; i++) { - pausedResponses.get(i).sendToTarget(); - } - pausedResponses.clear(); - } else { - Log.e("GSM", "SimulatedCommands.resumeResponses < 0"); - } - } - - //***** Private Methods - - private void unimplemented(Message result) { - if (result != null) { - AsyncResult.forMessage(result).exception - = new RuntimeException("Unimplemented"); - - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - - private void resultSuccess(Message result, Object ret) { - if (result != null) { - AsyncResult.forMessage(result).result = ret; - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - - private void resultFail(Message result, Throwable tr) { - if (result != null) { - AsyncResult.forMessage(result).exception = tr; - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - - // ***** Methods for CDMA support - public void - getDeviceIdentity(Message response) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(response); - } - - public void - getCDMASubscription(Message response) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(response); - } - - public void - setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(response); - } - - public void queryCdmaRoamingPreference(Message response) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(response); - } - - public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(response); - } - - public void - setPhoneType(int phoneType) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - } - - public void getPreferredVoicePrivacy(Message result) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(result); - } - - public void setPreferredVoicePrivacy(boolean enable, Message result) { - Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands"); - unimplemented(result); - } - - /** - * Set the TTY mode - * - * @param ttyMode is one of the following: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * @param response is callback message - */ - public void setTTYMode(int ttyMode, Message response) { - Log.w(LOG_TAG, "Not implemented in SimulatedCommands"); - unimplemented(response); - } - - /** - * Query the TTY mode - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * tty mode: - * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - * @param response is callback message - */ - public void queryTTYMode(Message response) { - 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 setCdmaBroadcastActivation(boolean activate, Message response) { - unimplemented(response); - - } - - public void getCdmaBroadcastConfig(Message response) { - unimplemented(response); - - } - - public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) { - unimplemented(response); - - } - - public void forceDataDormancy(Message response) { - unimplemented(response); - } - - - public void setGsmBroadcastActivation(boolean activate, Message response) { - unimplemented(response); - } - - - public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) { - unimplemented(response); - } - - public void getGsmBroadcastConfig(Message response) { - unimplemented(response); - } - - @Override - public void supplyIccPinForApp(String pin, String aid, Message response) { - unimplemented(response); - } - - @Override - public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) { - unimplemented(response); - } - - @Override - public void supplyIccPin2ForApp(String pin2, String aid, Message response) { - unimplemented(response); - } - - @Override - public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) { - unimplemented(response); - } - - @Override - public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) { - unimplemented(response); - } - - @Override - public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, - Message response) { - unimplemented(response); - } - - public void requestIsimAuthentication(String nonce, Message response) { - unimplemented(response); - } - - public void getVoiceRadioTechnology(Message response) { - unimplemented(response); - } -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java deleted file mode 100644 index c6c301d24b63..000000000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java +++ /dev/null @@ -1,809 +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.test; - -import android.os.Looper; -import android.os.Message; -import android.os.Handler; -import android.telephony.PhoneNumberUtils; -import com.android.internal.telephony.ATParseEx; -import com.android.internal.telephony.DriverCall; -import java.util.List; -import java.util.ArrayList; - -import android.util.Log; - -class CallInfo { - enum State { - ACTIVE(0), - HOLDING(1), - DIALING(2), // MO call only - ALERTING(3), // MO call only - INCOMING(4), // MT call only - WAITING(5); // MT call only - - State (int value) {this.value = value;} - - private final int value; - public int value() {return value;}; - }; - - boolean isMT; - State state; - boolean isMpty; - String number; - int TOA; - - CallInfo (boolean isMT, State state, boolean isMpty, String number) { - this.isMT = isMT; - this.state = state; - this.isMpty = isMpty; - this.number = number; - - if (number.length() > 0 && number.charAt(0) == '+') { - TOA = PhoneNumberUtils.TOA_International; - } else { - TOA = PhoneNumberUtils.TOA_Unknown; - } - } - - static CallInfo - createOutgoingCall(String number) { - return new CallInfo (false, State.DIALING, false, number); - } - - static CallInfo - createIncomingCall(String number) { - return new CallInfo (true, State.INCOMING, false, number); - } - - String - toCLCCLine(int index) { - return - "+CLCC: " - + index + "," + (isMT ? "1" : "0") +"," - + state.value() + ",0," + (isMpty ? "1" : "0") - + ",\"" + number + "\"," + TOA; - } - - DriverCall - toDriverCall(int index) { - DriverCall ret; - - ret = new DriverCall(); - - ret.index = index; - ret.isMT = isMT; - - try { - ret.state = DriverCall.stateFromCLCC(state.value()); - } catch (ATParseEx ex) { - throw new RuntimeException("should never happen", ex); - } - - ret.isMpty = isMpty; - ret.number = number; - ret.TOA = TOA; - ret.isVoice = true; - ret.als = 0; - - return ret; - } - - - boolean - isActiveOrHeld() { - return state == State.ACTIVE || state == State.HOLDING; - } - - boolean - isConnecting() { - return state == State.DIALING || state == State.ALERTING; - } - - boolean - isRinging() { - return state == State.INCOMING || state == State.WAITING; - } - -} - -class InvalidStateEx extends Exception { - InvalidStateEx() { - - } -} - - -class SimulatedGsmCallState extends Handler { - //***** Instance Variables - - CallInfo calls[] = new CallInfo[MAX_CALLS]; - - private boolean autoProgressConnecting = true; - private boolean nextDialFailImmediately; - - - //***** Event Constants - - static final int EVENT_PROGRESS_CALL_STATE = 1; - - //***** Constants - - static final int MAX_CALLS = 7; - /** number of msec between dialing -> alerting and alerting->active */ - static final int CONNECTING_PAUSE_MSEC = 5 * 100; - - - //***** Overridden from Handler - - public SimulatedGsmCallState(Looper looper) { - super(looper); - } - - public void - handleMessage(Message msg) { - synchronized(this) { switch (msg.what) { - // PLEASE REMEMBER - // calls may have hung up by the time delayed events happen - - case EVENT_PROGRESS_CALL_STATE: - progressConnectingCallState(); - break; - }} - } - - //***** Public Methods - - /** - * Start the simulated phone ringing - * true if succeeded, false if failed - */ - public boolean - triggerRing(String number) { - synchronized (this) { - int empty = -1; - boolean isCallWaiting = false; - - // ensure there aren't already calls INCOMING or WAITING - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call == null && empty < 0) { - empty = i; - } else if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - Log.w("ModelInterpreter", - "triggerRing failed; phone already ringing"); - return false; - } else if (call != null) { - isCallWaiting = true; - } - } - - if (empty < 0 ) { - Log.w("ModelInterpreter", "triggerRing failed; all full"); - return false; - } - - calls[empty] = CallInfo.createIncomingCall( - PhoneNumberUtils.extractNetworkPortion(number)); - - if (isCallWaiting) { - calls[empty].state = CallInfo.State.WAITING; - } - - } - return true; - } - - /** If a call is DIALING or ALERTING, progress it to the next state */ - public void - progressConnectingCallState() { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state == CallInfo.State.DIALING) { - call.state = CallInfo.State.ALERTING; - - if (autoProgressConnecting) { - sendMessageDelayed( - obtainMessage(EVENT_PROGRESS_CALL_STATE, call), - CONNECTING_PAUSE_MSEC); - } - break; - } else if (call != null - && call.state == CallInfo.State.ALERTING - ) { - call.state = CallInfo.State.ACTIVE; - break; - } - } - } - } - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && (call.state == CallInfo.State.DIALING - || call.state == CallInfo.State.ALERTING) - ) { - call.state = CallInfo.State.ACTIVE; - break; - } - } - } - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) { - autoProgressConnecting = b; - } - - public void - setNextDialFailImmediately(boolean b) { - nextDialFailImmediately = b; - } - - /** - * hangup ringing, dialing, or active calls - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupForeground() { - synchronized (this) { - boolean found; - - found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - calls[i] = null; - found = true; - } - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.DIALING - || call.state == CallInfo.State.ACTIVE - || call.state == CallInfo.State.ALERTING) - ) { - calls[i] = null; - found = true; - } - } - return found; - } - } - - /** - * hangup holding calls - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupBackground() { - synchronized (this) { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state == CallInfo.State.HOLDING) { - calls[i] = null; - found = true; - } - } - - return found; - } - } - - /** - * hangup all - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupAll() { - synchronized(this) { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (calls[i] != null) { - found = true; - } - - calls[i] = null; - } - - return found; - } - } - - public boolean - onAnswer() { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - return switchActiveAndHeldOrWaiting(); - } - } - } - - return false; - } - - public boolean - onHangup() { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state != CallInfo.State.WAITING) { - calls[i] = null; - found = true; - } - } - - return found; - } - - public boolean - onChld(char c0, char c1) { - boolean ret; - int callIndex = 0; - - if (c1 != 0) { - callIndex = c1 - '1'; - - if (callIndex < 0 || callIndex >= calls.length) { - return false; - } - } - - switch (c0) { - case '0': - ret = releaseHeldOrUDUB(); - break; - case '1': - if (c1 <= 0) { - ret = releaseActiveAcceptHeldOrWaiting(); - } else { - if (calls[callIndex] == null) { - ret = false; - } else { - calls[callIndex] = null; - ret = true; - } - } - break; - case '2': - if (c1 <= 0) { - ret = switchActiveAndHeldOrWaiting(); - } else { - ret = separateCall(callIndex); - } - break; - case '3': - ret = conference(); - break; - case '4': - ret = explicitCallTransfer(); - break; - case '5': - if (true) { //just so javac doesnt complain about break - //CCBS not impled - ret = false; - } - break; - default: - ret = false; - - } - - return ret; - } - - public boolean - releaseHeldOrUDUB() { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.isRinging()) { - found = true; - calls[i] = null; - break; - } - } - - if (!found) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - found = true; - calls[i] = null; - // don't stop...there may be more than one - } - } - } - - return true; - } - - - public boolean - releaseActiveAcceptHeldOrWaiting() { - boolean foundHeld = false; - boolean foundActive = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.ACTIVE) { - calls[i] = null; - foundActive = true; - } - } - - if (!foundActive) { - // FIXME this may not actually be how most basebands react - // CHLD=1 may not hang up dialing/alerting calls - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null - && (c.state == CallInfo.State.DIALING - || c.state == CallInfo.State.ALERTING) - ) { - calls[i] = null; - foundActive = true; - } - } - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - c.state = CallInfo.State.ACTIVE; - foundHeld = true; - } - } - - if (foundHeld) { - return true; - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.isRinging()) { - c.state = CallInfo.State.ACTIVE; - return true; - } - } - - return true; - } - - public boolean - switchActiveAndHeldOrWaiting() { - boolean hasHeld = false; - - // first, are there held calls? - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - hasHeld = true; - break; - } - } - - // Now, switch - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - if (c.state == CallInfo.State.ACTIVE) { - c.state = CallInfo.State.HOLDING; - } else if (c.state == CallInfo.State.HOLDING) { - c.state = CallInfo.State.ACTIVE; - } else if (!hasHeld && c.isRinging()) { - c.state = CallInfo.State.ACTIVE; - } - } - } - - return true; - } - - - public boolean - separateCall(int index) { - try { - CallInfo c; - - c = calls[index]; - - if (c == null || c.isConnecting() || countActiveLines() != 1) { - return false; - } - - c.state = CallInfo.State.ACTIVE; - c.isMpty = false; - - for (int i = 0 ; i < calls.length ; i++) { - int countHeld=0, lastHeld=0; - - if (i != index) { - CallInfo cb = calls[i]; - - if (cb != null && cb.state == CallInfo.State.ACTIVE) { - cb.state = CallInfo.State.HOLDING; - countHeld++; - lastHeld = i; - } - } - - if (countHeld == 1) { - // if there's only one left, clear the MPTY flag - calls[lastHeld].isMpty = false; - } - } - - return true; - } catch (InvalidStateEx ex) { - return false; - } - } - - - - public boolean - conference() { - int countCalls = 0; - - // if there's connecting calls, we can't do this yet - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - countCalls++; - - if (c.isConnecting()) { - return false; - } - } - } - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - c.state = CallInfo.State.ACTIVE; - if (countCalls > 0) { - c.isMpty = true; - } - } - } - - return true; - } - - public boolean - explicitCallTransfer() { - int countCalls = 0; - - // if there's connecting calls, we can't do this yet - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - countCalls++; - - if (c.isConnecting()) { - return false; - } - } - } - - // disconnect the subscriber from both calls - return triggerHangupAll(); - } - - public boolean - onDial(String address) { - CallInfo call; - int freeSlot = -1; - - Log.d("GSM", "SC> dial '" + address + "'"); - - if (nextDialFailImmediately) { - nextDialFailImmediately = false; - - Log.d("GSM", "SC< dial fail (per request)"); - return false; - } - - String phNum = PhoneNumberUtils.extractNetworkPortion(address); - - if (phNum.length() == 0) { - Log.d("GSM", "SC< dial fail (invalid ph num)"); - return false; - } - - // Ignore setting up GPRS - if (phNum.startsWith("*99") && phNum.endsWith("#")) { - Log.d("GSM", "SC< dial ignored (gprs)"); - return true; - } - - // There can be at most 1 active "line" when we initiate - // a new call - try { - if (countActiveLines() > 1) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - } catch (InvalidStateEx ex) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - - for (int i = 0 ; i < calls.length ; i++) { - if (freeSlot < 0 && calls[i] == null) { - freeSlot = i; - } - - if (calls[i] != null && !calls[i].isActiveOrHeld()) { - // Can't make outgoing calls when there is a ringing or - // connecting outgoing call - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) { - // All active calls behome held - calls[i].state = CallInfo.State.HOLDING; - } - } - - if (freeSlot < 0) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - - calls[freeSlot] = CallInfo.createOutgoingCall(phNum); - - if (autoProgressConnecting) { - sendMessageDelayed( - obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]), - CONNECTING_PAUSE_MSEC); - } - - Log.d("GSM", "SC< dial (slot = " + freeSlot + ")"); - - return true; - } - - public List - getDriverCalls() { - ArrayList ret = new ArrayList(calls.length); - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - DriverCall dc; - - dc = c.toDriverCall(i + 1); - ret.add(dc); - } - } - - Log.d("GSM", "SC< getDriverCalls " + ret); - - return ret; - } - - public List - getClccLines() { - ArrayList ret = new ArrayList(calls.length); - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - ret.add((c.toCLCCLine(i + 1))); - } - } - - return ret; - } - - private int - countActiveLines() throws InvalidStateEx { - boolean hasMpty = false; - boolean hasHeld = false; - boolean hasActive = false; - boolean hasConnecting = false; - boolean hasRinging = false; - boolean mptyIsHeld = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null) { - if (!hasMpty && call.isMpty) { - mptyIsHeld = call.state == CallInfo.State.HOLDING; - } else if (call.isMpty && mptyIsHeld - && call.state == CallInfo.State.ACTIVE - ) { - Log.e("ModelInterpreter", "Invalid state"); - throw new InvalidStateEx(); - } else if (!call.isMpty && hasMpty && mptyIsHeld - && call.state == CallInfo.State.HOLDING - ) { - Log.e("ModelInterpreter", "Invalid state"); - throw new InvalidStateEx(); - } - - hasMpty |= call.isMpty; - hasHeld |= call.state == CallInfo.State.HOLDING; - hasActive |= call.state == CallInfo.State.ACTIVE; - hasConnecting |= call.isConnecting(); - hasRinging |= call.isRinging(); - } - } - - int ret = 0; - - if (hasHeld) ret++; - if (hasActive) ret++; - if (hasConnecting) ret++; - if (hasRinging) ret++; - - return ret; - } - -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java deleted file mode 100644 index 054d37024ad6..000000000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java +++ /dev/null @@ -1,53 +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.test; - -public interface SimulatedRadioControl -{ - public void triggerRing(String number); - - public void progressConnectingCallState(); - - public void progressConnectingToActive(); - - public void setAutoProgressConnectingCall(boolean b); - - public void setNextDialFailImmediately(boolean b); - - public void setNextCallFailCause(int gsmCause); - - public void triggerHangupForeground(); - - public void triggerHangupBackground(); - - public void triggerHangupAll(); - - public void triggerIncomingSMS(String message); - - public void shutdown(); - - /** Pause responses to async requests until (ref-counted) resumeResponses() */ - public void pauseResponses(); - - /** see pauseResponses */ - public void resumeResponses(); - - public void triggerSsn(int type, int code); - - /** Generates an incoming USSD message. */ - public void triggerIncomingUssd(String statusCode, String message); -} diff --git a/telephony/java/com/android/internal/telephony/test/package.html b/telephony/java/com/android/internal/telephony/test/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/telephony/java/com/android/internal/telephony/test/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - - diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java deleted file mode 100644 index 5961efd35b53..000000000000 --- a/telephony/java/com/android/internal/telephony/uicc/UiccController.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2011 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.uicc; - -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.cdma.CDMALTEPhone; -import com.android.internal.telephony.cdma.CDMAPhone; -import com.android.internal.telephony.gsm.GSMPhone; - -import android.util.Log; - -/* This class is responsible for keeping all knowledge about - * ICCs in the system. It is also used as API to get appropriate - * applications to pass them to phone and service trackers. - */ -public class UiccController { - private static final boolean DBG = true; - private static final String LOG_TAG = "RIL_UiccController"; - - private static UiccController mInstance; - - private PhoneBase mCurrentPhone; - private boolean mIsCurrentCard3gpp; - private IccCard mIccCard; - - public static synchronized UiccController getInstance(PhoneBase phone) { - if (mInstance == null) { - mInstance = new UiccController(phone); - } else { - mInstance.setNewPhone(phone); - } - return mInstance; - } - - public IccCard getIccCard() { - return mIccCard; - } - - private UiccController(PhoneBase phone) { - if (DBG) log("Creating UiccController"); - setNewPhone(phone); - } - - private void setNewPhone(PhoneBase phone) { - mCurrentPhone = phone; - if (phone instanceof GSMPhone) { - if (DBG) log("New phone is GSMPhone"); - updateCurrentCard(IccCard.CARD_IS_3GPP); - } else if (phone instanceof CDMALTEPhone){ - if (DBG) log("New phone type is CDMALTEPhone"); - updateCurrentCard(IccCard.CARD_IS_3GPP); - } else if (phone instanceof CDMAPhone){ - if (DBG) log("New phone type is CDMAPhone"); - updateCurrentCard(IccCard.CARD_IS_NOT_3GPP); - } else { - Log.e(LOG_TAG, "Unhandled phone type. Critical error!"); - } - } - - private void updateCurrentCard(boolean isNewCard3gpp) { - if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) { - return; - } - - if (mIccCard != null) { - mIccCard.dispose(); - mIccCard = null; - } - - mIsCurrentCard3gpp = isNewCard3gpp; - mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(), - isNewCard3gpp, DBG); - } - - private void log(String string) { - Log.d(LOG_TAG, string); - } -} \ No newline at end of file diff --git a/telephony/mockril/Android.mk b/telephony/mockril/Android.mk deleted file mode 100644 index 95ae84c544c2..000000000000 --- a/telephony/mockril/Android.mk +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (C) 2010 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -LOCAL_PATH:=$(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := core framework - -LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java - -LOCAL_MODULE := mockrilcontroller - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java b/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java deleted file mode 100644 index 0e75c72483d3..000000000000 --- a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.mockril; - -import android.os.Bundle; -import android.util.Log; - -import com.android.internal.communication.MsgHeader; -import com.android.internal.communication.Msg; -import com.android.internal.telephony.RilChannel; -import com.android.internal.telephony.ril_proto.RilCtrlCmds; -import com.android.internal.telephony.ril_proto.RilCmds; -import com.google.protobuf.micro.MessageMicro; - -import java.io.IOException; - -/** - * Contain a list of commands to control Mock RIL. Before using these commands the devices - * needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details. - * - */ -public class MockRilController { - private static final String TAG = "MockRILController"; - private RilChannel mRilChannel = null; - private Msg mMessage = null; - - public MockRilController() throws IOException { - mRilChannel = RilChannel.makeRilChannel(); - } - - /** - * Close the channel after the communication is done. - * This method has to be called after the test is finished. - */ - public void closeChannel() { - mRilChannel.close(); - } - - /** - * Send commands and return true on success - * @param cmd for MsgHeader - * @param token for MsgHeader - * @param status for MsgHeader - * @param pbData for Msg data - * @return true if command is sent successfully, false if it fails - */ - private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) { - try { - Msg.send(mRilChannel, cmd, token, status, pbData); - } catch (IOException e) { - Log.v(TAG, "send command : %d failed: " + e.getStackTrace()); - return false; - } - return true; - } - - /** - * Get control response - * @return Msg if response is received, else return null. - */ - private Msg getCtrlResponse() { - Msg response = null; - try { - response = Msg.recv(mRilChannel); - } catch (IOException e) { - Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace()); - return null; - } - return response; - } - - /** - * @return the radio state if it is valid, otherwise return -1 - */ - public int getRadioState() { - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) { - return -1; - } - Msg response = getCtrlResponse(); - if (response == null) { - Log.v(TAG, "failed to get response"); - return -1; - } - response.printHeader(TAG); - RilCtrlCmds.CtrlRspRadioState resp = - response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); - int state = resp.getState(); - if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY)) - return state; - else - return -1; - } - - /** - * Set the radio state of mock ril to the given state - * @param state for given radio state - * @return true if the state is set successful, false if it fails - */ - public boolean setRadioState(int state) { - RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState(); - if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) { - Log.v(TAG, "the give radio state is not valid."); - return false; - } - req.setState(state); - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) { - Log.v(TAG, "send set radio state request failed."); - return false; - } - Msg response = getCtrlResponse(); - if (response == null) { - Log.v(TAG, "failed to get response for setRadioState"); - return false; - } - response.printHeader(TAG); - RilCtrlCmds.CtrlRspRadioState resp = - response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); - int curstate = resp.getState(); - return curstate == state; - } - - /** - * Start an incoming call for the given phone number - * - * @param phoneNumber is the number to show as incoming call - * @return true if the incoming call is started successfully, false if it fails. - */ - public boolean startIncomingCall(String phoneNumber) { - RilCtrlCmds.CtrlReqSetMTCall req = new RilCtrlCmds.CtrlReqSetMTCall(); - - req.setPhoneNumber(phoneNumber); - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) { - Log.v(TAG, "send CMD_SET_MT_CALL request failed"); - return false; - } - return true; - } - - /** - * Hang up a connection remotelly for the given call fail cause - * - * @param connectionID is the connection to be hung up - * @param failCause is the call fail cause defined in ril.h - * @return true if the hangup is successful, false if it fails - */ - public boolean hangupRemote(int connectionId, int failCause) { - RilCtrlCmds.CtrlHangupConnRemote req = new RilCtrlCmds.CtrlHangupConnRemote(); - req.setConnectionId(connectionId); - req.setCallFailCause(failCause); - - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) { - Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed"); - return false; - } - return true; - } - - /** - * Set call transition flag to the Mock Ril - * - * @param flag is a boolean value for the call transiton flag - * true: call transition: dialing->alert, alert->active is controlled - * false: call transition is automatically handled by Mock Ril - * @return true if the request is successful, false if it failed to set the flag - */ - public boolean setCallTransitionFlag(boolean flag) { - RilCtrlCmds.CtrlSetCallTransitionFlag req = new RilCtrlCmds.CtrlSetCallTransitionFlag(); - - req.setFlag(flag); - - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) { - Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed"); - return false; - } - return true; - } - - /** - * Set the dialing call to alert if the call transition flag is true - * - * @return true if the call transition is successful, false if it fails - */ - public boolean setDialCallToAlert() { - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) { - Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed"); - return false; - } - return true; - } - - /** - * Set the alert call to active if the call transition flag is true - * - * @return true if the call transition is successful, false if it fails - */ - public boolean setAlertCallToActive() { - if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) { - Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed"); - return false; - } - return true; - } -} diff --git a/telephony/tests/telephonymockriltests/Android.mk b/telephony/tests/telephonymockriltests/Android.mk deleted file mode 100644 index 9731d0d0059d..000000000000 --- a/telephony/tests/telephonymockriltests/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_STATIC_JAVA_LIBRARIES := mockrilcontroller - -LOCAL_JAVA_LIBRARIES := android.test.runner - -LOCAL_PACKAGE_NAME := TelephonyMockRilTests - -include $(BUILD_PACKAGE) diff --git a/telephony/tests/telephonymockriltests/AndroidManifest.xml b/telephony/tests/telephonymockriltests/AndroidManifest.xml deleted file mode 100644 index 63f44a2d8a6f..000000000000 --- a/telephony/tests/telephonymockriltests/AndroidManifest.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java deleted file mode 100644 index 78ee73809cfa..000000000000 --- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.telephonymockriltests; - -import android.os.Bundle; -import android.test.InstrumentationTestRunner; -import android.test.InstrumentationTestSuite; -import com.android.internal.telephony.mockril.MockRilController; -import android.util.Log; - -import com.android.telephonymockriltests.functional.SimpleTestUsingMockRil; - -import java.io.IOException; -import junit.framework.TestSuite; -import junit.framework.TestCase; - -/** - * Test runner for telephony tests that using Mock RIL - * - */ -public class TelephonyMockTestRunner extends InstrumentationTestRunner { - private static final String TAG="TelephonyMockTestRunner"; - public MockRilController mController; - - @Override - public TestSuite getAllTests() { - TestSuite suite = new InstrumentationTestSuite(this); - suite.addTestSuite(SimpleTestUsingMockRil.class); - return suite; - } - - @Override - public void onCreate(Bundle icicle) { - try { - mController = new MockRilController(); - } catch (IOException e) { - e.printStackTrace(); - TestCase.assertTrue("Create Mock RIl Controller failed", false); - } - TestCase.assertNotNull(mController); - super.onCreate(icicle); - } - - @Override - public void finish(int resultCode, Bundle results) { - if (mController != null) - mController.closeChannel(); - super.finish(resultCode, results); - } -} diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java deleted file mode 100644 index 3ea1cf20a03c..000000000000 --- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.telephonymockriltests.functional; - -import com.android.internal.telephony.mockril.MockRilController; -import android.test.InstrumentationTestCase; -import android.util.Log; - -import com.android.telephonymockriltests.TelephonyMockTestRunner; - -/** - * A simple test that using Mock RIL Controller - */ -public class SimpleTestUsingMockRil extends InstrumentationTestCase { - private static final String TAG = "SimpleTestUsingMockRil"; - private MockRilController mMockRilCtrl = null; - private TelephonyMockTestRunner mRunner; - - @Override - public void setUp() throws Exception { - super.setUp(); - mRunner = (TelephonyMockTestRunner)getInstrumentation(); - mMockRilCtrl = mRunner.mController; - assertNotNull(mMockRilCtrl); - } - - /** - * Get the current radio state of RIL - */ - public void testGetRadioState() { - int state = mMockRilCtrl.getRadioState(); - Log.v(TAG, "testGetRadioState: " + state); - assertTrue(state >= 0 && state <= 9); - } - - /** - * Set the current radio state of RIL - * and verify the radio state is set correctly - */ - public void testSetRadioState() { - for (int state = 0; state <= 9; state++) { - Log.v(TAG, "set radio state to be " + state); - assertTrue("set radio state: " + state + " failed.", - mMockRilCtrl.setRadioState(state)); - } - assertFalse("use an invalid radio state", mMockRilCtrl.setRadioState(-1)); - assertFalse("the radio state doesn't exist", mMockRilCtrl.setRadioState(10)); - } -} diff --git a/telephony/tests/telephonytests/Android.mk b/telephony/tests/telephonytests/Android.mk deleted file mode 100644 index 98e44036145e..000000000000 --- a/telephony/tests/telephonytests/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java - -LOCAL_JAVA_LIBRARIES := android.test.runner - -LOCAL_PACKAGE_NAME := FrameworksTelephonyTests - -include $(BUILD_PACKAGE) diff --git a/telephony/tests/telephonytests/AndroidManifest.xml b/telephony/tests/telephonytests/AndroidManifest.xml deleted file mode 100644 index ba1d95745d84..000000000000 --- a/telephony/tests/telephonytests/AndroidManifest.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java b/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java deleted file mode 100644 index 9192f572f7e3..000000000000 --- a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.frameworks.telephonytests; - -import android.os.Bundle; - -import android.test.InstrumentationTestRunner; -import android.test.InstrumentationTestSuite; -import android.util.Log; - -import java.io.IOException; - -import com.android.internal.telephony.RilChannel; -import com.android.internal.telephony.mockril.MockRilTest; - -import junit.framework.TestSuite; - -public class TelephonyMockRilTestRunner extends InstrumentationTestRunner { - - public RilChannel mMockRilChannel; - - @Override - public TestSuite getAllTests() { - log("getAllTests E"); - TestSuite suite = new InstrumentationTestSuite(this); - suite.addTestSuite(MockRilTest.class); - log("getAllTests X"); - return suite; - } - - @Override - public ClassLoader getLoader() { - log("getLoader EX"); - return TelephonyMockRilTestRunner.class.getClassLoader(); - } - - @Override - public void onCreate(Bundle icicle) { - log("onCreate E"); - try { - mMockRilChannel = RilChannel.makeRilChannel(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - log("onCreate X"); - - super.onCreate(icicle); - } - - @Override - public void onDestroy() { - // I've not seen this called - log("onDestroy EX"); - super.onDestroy(); - } - - @Override - public void onStart() { - // Called when the instrumentation thread is started. - // At the moment we don't need the thread so return - // which will shut down this unused thread. - log("onStart EX"); - super.onStart(); - } - - @Override - public void finish(int resultCode, Bundle results) { - // Called when complete so I ask the mMockRilChannel to quit. - log("finish E"); - mMockRilChannel.close(); - log("finish X"); - super.finish(resultCode, results); - } - - private void log(String s) { - Log.e("TelephonyMockRilTestRunner", s); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java deleted file mode 100644 index 81727e482961..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java +++ /dev/null @@ -1,113 +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; - -import junit.framework.TestCase; -import android.test.suitebuilder.annotation.SmallTest; - -public class ATResponseParserTest extends TestCase { - @SmallTest - public void testBasic() throws Exception { - ATResponseParser p = new ATResponseParser("+CREG: 0"); - - assertEquals(0, p.nextInt()); - - assertFalse(p.hasMore()); - - try { - p.nextInt(); - fail("exception expected"); - } catch (ATParseEx ex) { - //test pass - } - - p = new ATResponseParser("+CREG: 0,1"); - assertEquals(0, p.nextInt()); - assertEquals(1, p.nextInt()); - assertFalse(p.hasMore()); - - p = new ATResponseParser("+CREG: 0, 1"); - assertEquals(0, p.nextInt()); - assertEquals(1, p.nextInt()); - assertFalse(p.hasMore()); - - p = new ATResponseParser("+CREG: 0, 1,"); - assertEquals(0, p.nextInt()); - assertEquals(1, p.nextInt()); - // this seems odd but is probably OK - assertFalse(p.hasMore()); - try { - p.nextInt(); - fail("exception expected"); - } catch (ATParseEx ex) { - //test pass - } - - p = new ATResponseParser("+CREG: 0, 1 "); - assertEquals(0, p.nextInt()); - assertEquals(1, p.nextInt()); - assertFalse(p.hasMore()); - - p = new ATResponseParser("0, 1 "); - // no prefix -> exception - try { - p.nextInt(); - fail("exception expected"); - } catch (ATParseEx ex) { - //test pass - } - - p = new ATResponseParser("+CREG: 0, 1, 5"); - assertFalse(p.nextBoolean()); - assertTrue(p.nextBoolean()); - try { - // is this over-constraining? - p.nextBoolean(); - fail("exception expected"); - } catch (ATParseEx ex) { - //test pass - } - - p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212\",145"); - - assertEquals(1, p.nextInt()); - assertFalse(p.nextBoolean()); - assertEquals(2, p.nextInt()); - assertEquals(0, p.nextInt()); - assertEquals(0, p.nextInt()); - assertEquals("+18005551212", p.nextString()); - assertEquals(145, p.nextInt()); - assertFalse(p.hasMore()); - - p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212,145"); - - assertEquals(1, p.nextInt()); - assertFalse(p.nextBoolean()); - assertEquals(2, p.nextInt()); - assertEquals(0, p.nextInt()); - assertEquals(0, p.nextInt()); - try { - p.nextString(); - fail("expected ex"); - } catch (ATParseEx ex) { - //test pass - } - - p = new ATResponseParser("+FOO: \"\""); - assertEquals("", p.nextString()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java deleted file mode 100644 index 8a4a285212b1..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java +++ /dev/null @@ -1,176 +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; - -import junit.framework.TestCase; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * {@hide} - */ -public class AdnRecordTest extends TestCase { - - @SmallTest - public void testBasic() throws Exception { - AdnRecord adn; - - // - // Typical record - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C07918150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("+18056377243", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // Empty records, empty strings - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); - - assertEquals("", adn.getAlphaTag()); - assertEquals("", adn.getNumber()); - assertTrue(adn.isEmpty()); - - // - // Record too short - // - adn = new AdnRecord(IccUtils.hexStringToBytes( "FF")); - - assertEquals("", adn.getAlphaTag()); - assertEquals("", adn.getNumber()); - assertTrue(adn.isEmpty()); - - // - // TOA = 0xff ("control string") - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C07FF8150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("18056377243", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // TOA = 0x81 (unknown) - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C07818150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("18056377243", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // Number Length is too long - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C0F918150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // Number Length is zero (invalid) - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C00918150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // Number Length is 2, first number byte is FF, TOA is international - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C0291FF50367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // Number Length is 2, first number digit is valid, TOA is international - // - adn = new AdnRecord( - IccUtils.hexStringToBytes("566F696365204D61696C0291F150367742F3FFFFFFFFFFFF")); - - assertEquals("Voice Mail", adn.getAlphaTag()); - assertEquals("+1", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // An extended record - // - adn = new AdnRecord( - IccUtils.hexStringToBytes( - "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678", adn.getNumber()); - assertFalse(adn.isEmpty()); - assertTrue(adn.hasExtendedRecord()); - - adn.appendExtRecord(IccUtils.hexStringToBytes("0206092143658709ffffffffff")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678901234567890", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // An extended record with an invalid extension - // - adn = new AdnRecord( - IccUtils.hexStringToBytes( - "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678", adn.getNumber()); - assertFalse(adn.isEmpty()); - assertTrue(adn.hasExtendedRecord()); - - adn.appendExtRecord(IccUtils.hexStringToBytes("0106092143658709ffffffffff")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678", adn.getNumber()); - assertFalse(adn.isEmpty()); - - // - // An extended record with an invalid extension - // - adn = new AdnRecord( - IccUtils.hexStringToBytes( - "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678", adn.getNumber()); - assertFalse(adn.isEmpty()); - assertTrue(adn.hasExtendedRecord()); - - adn.appendExtRecord(IccUtils.hexStringToBytes("020B092143658709ffffffffff")); - - assertEquals("Adgjm", adn.getAlphaTag()); - assertEquals("+18885551212,12345678", adn.getNumber()); - assertFalse(adn.isEmpty()); - } -} - - diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java deleted file mode 100755 index ac8c4c167b37..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import junit.framework.TestCase; - -import android.test.suitebuilder.annotation.SmallTest; - -public class ApnSettingTest extends TestCase { - - public static final String[] TYPES = {"default", "*"}; - - public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { - assertEquals(a1.carrier, a2.carrier); - assertEquals(a1.apn, a2.apn); - assertEquals(a1.proxy, a2.proxy); - assertEquals(a1.port, a2.port); - assertEquals(a1.mmsc, a2.mmsc); - assertEquals(a1.mmsProxy, a2.mmsProxy); - assertEquals(a1.mmsPort, a2.mmsPort); - assertEquals(a1.user, a2.user); - assertEquals(a1.password, a2.password); - assertEquals(a1.authType, a2.authType); - assertEquals(a1.id, a2.id); - assertEquals(a1.numeric, a2.numeric); - assertEquals(a1.protocol, a2.protocol); - assertEquals(a1.roamingProtocol, a2.roamingProtocol); - assertEquals(a1.types.length, a2.types.length); - int i; - for (i = 0; i < a1.types.length; i++) { - assertEquals(a1.types[i], a2.types[i]); - } - assertEquals(a1.carrierEnabled, a2.carrierEnabled); - assertEquals(a1.bearer, a2.bearer); - } - - @SmallTest - public void testFromString() throws Exception { - String[] dunTypes = {"DUN"}; - String[] mmsTypes = {"mms", "*"}; - - ApnSetting expected_apn; - String testString; - - // A real-world v1 example string. - testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN"; - expected_apn = new ApnSetting( - -1, "22210", "Vodafone IT", "web.omnitel.it", "", "", - "", "", "", "", "", 0, dunTypes, "IP", "IP",true,0); - assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); - - // A v2 string. - testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14"; - expected_apn = new ApnSetting( - -1, "12345", "Name", "apn", "", "", - "", "", "", "", "", 0, mmsTypes, "IPV6", "IP",true,14); - assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); - - // A v2 string with spaces. - testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV4V6, IP,true,14"; - expected_apn = new ApnSetting( - -1, "12345", "Name", "apn", "", "", - "", "", "", "", "", 0, mmsTypes, "IPV4V6", "IP",true,14); - assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); - - // Return null if insufficient fields given. - testString = "[ApnSettingV2] Name,apn,,,,,,,,,123, 45,,mms|*"; - assertEquals(null, ApnSetting.fromString(testString)); - - testString = "Name,apn,,,,,,,,,123, 45,"; - assertEquals(null, ApnSetting.fromString(testString)); - - // Parse (incorrect) V2 format without the tag as V1. - testString = "Name,apn,,,,,,,,,123, 45,,mms|*,IPV6,true,14"; - String[] incorrectTypes = {"mms|*", "IPV6"}; - expected_apn = new ApnSetting( - -1, "12345", "Name", "apn", "", "", - "", "", "", "", "", 0, incorrectTypes, "IP", "IP",true,14); - assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); - } - - - @SmallTest - public void testToString() throws Exception { - String[] types = {"default", "*"}; - ApnSetting apn = new ApnSetting( - 99, "12345", "Name", "apn", "proxy", "port", - "mmsc", "mmsproxy", "mmsport", "user", "password", 0, - types, "IPV4V6", "IP", true, 14); - String expected = "[ApnSettingV2] Name, 99, 12345, apn, proxy, " + - "mmsc, mmsproxy, mmsport, port, 0, default | *, " + - "IPV4V6, IP, true, 14"; - assertEquals(expected, apn.toString()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java deleted file mode 100644 index 1e5dafb3d45f..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.res.Resources; -import com.android.internal.telephony.CallerInfo; -import com.android.internal.telephony.CallerInfoAsyncQuery; -import android.util.Log; -import android.os.Looper; -import android.test.ActivityInstrumentationTestCase; -import android.util.StringBuilderPrinter; - -/* - * Check the CallerInfo utility class works as expected. - * - */ - -public class CallerInfoTest extends AndroidTestCase { - private CallerInfo mInfo; - private Context mContext; - - private static final String kEmergencyNumber = "Emergency Number"; - private static final int kToken = 0xdeadbeef; - private static final String TAG = "CallerInfoUnitTest"; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mContext = new MockContext(); - mInfo = new CallerInfo(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - /** - * Checks the caller info instance is flagged as an emergency if - * the number is an emergency one. There is no test for the - * contact based constructors because emergency number are not in - * the contact DB. - */ - @SmallTest - public void testEmergencyIsProperlySet() throws Exception { - assertFalse(mInfo.isEmergencyNumber()); - - mInfo = CallerInfo.getCallerInfo(mContext, "911"); - assertIsValidEmergencyCallerInfo(); - - mInfo = CallerInfo.getCallerInfo(mContext, "tel:911"); - assertIsValidEmergencyCallerInfo(); - - - // This one hits the content resolver. - mInfo = CallerInfo.getCallerInfo(mContext, "18001234567"); - assertFalse(mInfo.isEmergencyNumber()); - } - - /** - * Same as testEmergencyIsProperlySet but uses the async query api. - */ - @SmallTest - public void testEmergencyIsProperlySetUsingAsyncQuery() throws Exception { - QueryRunner query; - - query = new QueryRunner("911"); - query.runAndCheckCompletion(); - assertIsValidEmergencyCallerInfo(); - - query = new QueryRunner("tel:911"); - query.runAndCheckCompletion(); - assertIsValidEmergencyCallerInfo(); - - query = new QueryRunner("18001234567"); - query.runAndCheckCompletion(); - assertFalse(mInfo.isEmergencyNumber()); - } - - /** - * For emergency caller info, phoneNumber should be set to the - * string emergency_call_dialog_number_for_display and the - * photoResource should be set to the picture_emergency drawable. - */ - @SmallTest - public void testEmergencyNumberAndPhotoAreSet() throws Exception { - mInfo = CallerInfo.getCallerInfo(mContext, "911"); - - assertIsValidEmergencyCallerInfo(); - } - - // TODO: Add more tests: - /** - * Check if the voice mail number cannot be retrieved that the - * original phone number is preserved. - */ - /** - * Check the markAs* methods work. - */ - - - // - // Helpers - // - - // Partial implementation of MockResources. - public class MockResources extends android.test.mock.MockResources - { - @Override - public String getString(int resId) throws Resources.NotFoundException { - switch (resId) { - case com.android.internal.R.string.emergency_call_dialog_number_for_display: - return kEmergencyNumber; - default: - throw new UnsupportedOperationException("Missing handling for resid " + resId); - } - } - } - - // Partial implementation of MockContext. - public class MockContext extends android.test.mock.MockContext { - private ContentResolver mResolver; - private Resources mResources; - - public MockContext() { - mResolver = new android.test.mock.MockContentResolver(); - mResources = new MockResources(); - } - - @Override - public ContentResolver getContentResolver() { - return mResolver; - } - - @Override - public Resources getResources() { - return mResources; - } - } - - /** - * Class to run a CallerInfoAsyncQuery in a separate thread, with - * its own Looper. We cannot use the main Looper because on the - * 1st quit the thread is maked dead, ie no further test can use - * it. Also there is not way to inject a Looper instance in the - * query, so we have to use a thread with its own looper. - */ - private class QueryRunner extends Thread - implements CallerInfoAsyncQuery.OnQueryCompleteListener { - private Looper mLooper; - private String mNumber; - private boolean mAsyncCompleted; - - public QueryRunner(String number) { - super(); - mNumber = number; - } - - // Run the query in the thread, wait for completion. - public void runAndCheckCompletion() throws InterruptedException { - start(); - join(); - assertTrue(mAsyncCompleted); - } - - @Override - public void run() { - Looper.prepare(); - mLooper = Looper.myLooper(); - mAsyncCompleted = false; - // The query will pick the thread local looper we've just prepared. - CallerInfoAsyncQuery.startQuery(kToken, mContext, mNumber, this, null); - mLooper.loop(); - } - - // Quit the Looper on the 1st callback - // (EVENT_EMERGENCY_NUMBER). There is another message - // (EVENT_END_OF_QUEUE) that will never be delivered because - // the test has exited. The corresponding stack trace - // "Handler{xxxxx} sending message to a Handler on a dead - // thread" can be ignored. - public void onQueryComplete(int token, Object cookie, CallerInfo info) { - mAsyncCompleted = true; - mInfo = info; - mLooper.quit(); - } - } - - /** - * Fail if mInfo does not contain a valid emergency CallerInfo instance. - */ - private void assertIsValidEmergencyCallerInfo() throws Exception { - assertTrue(mInfo.isEmergencyNumber()); - - // For emergency caller info, phoneNumber should be set to the - // string emergency_call_dialog_number_for_display and the - // photoResource should be set to the picture_emergency drawable. - assertEquals(kEmergencyNumber, mInfo.phoneNumber); - assertEquals(com.android.internal.R.drawable.picture_emergency, mInfo.photoResource); - - // The name should be null - assertNull(mInfo.name); - assertEquals(0, mInfo.namePresentation); - assertNull(mInfo.cnapName); - assertEquals(0, mInfo.numberPresentation); - - assertFalse(mInfo.contactExists); - assertEquals(0, mInfo.person_id); - assertFalse(mInfo.needUpdate); - assertNull(mInfo.contactRefUri); - - assertNull(mInfo.phoneLabel); - assertEquals(0, mInfo.numberType); - assertNull(mInfo.numberLabel); - - assertNull(mInfo.contactRingtoneUri); - assertFalse(mInfo.shouldSendToVoicemail); - - assertNull(mInfo.cachedPhoto); - assertFalse(mInfo.isCachedPhotoCurrent); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java deleted file mode 100644 index f9dc3a938a63..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java +++ /dev/null @@ -1,361 +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; - -import com.android.internal.telephony.GsmAlphabet; - -import junit.framework.TestCase; - -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.SmallTest; - -public class GsmAlphabetTest extends TestCase { - - private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac"; - - @SmallTest - public void test7bitWithHeader() throws Exception { - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 1; - concatRef.seqNumber = 2; - concatRef.msgCount = 2; - concatRef.isEightBits = true; - SmsHeader header = new SmsHeader(); - header.concatRef = concatRef; - - String message = "aaaaaaaaaabbbbbbbbbbcccccccccc"; - byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, - SmsHeader.toByteArray(header), 0, 0); - int septetCount = GsmAlphabet.countGsmSeptetsUsingTables(message, true, 0, 0); - String parsedMessage = GsmAlphabet.gsm7BitPackedToString( - userData, SmsHeader.toByteArray(header).length+2, septetCount, 1, 0, 0); - assertEquals(message, parsedMessage); - } - - // TODO: This method should *really* be a series of individual test methods. - // However, it's a SmallTest because it executes quickly. - @SmallTest - public void testBasic() throws Exception { - // '@' maps to char 0 - assertEquals(0, GsmAlphabet.charToGsm('@')); - - // `a (a with grave accent) maps to last GSM character - assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0')); - - // - // These are the extended chars - // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE - // - - for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { - assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, - GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i))); - - } - - // euro symbol - assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, - GsmAlphabet.charToGsm('\u20ac')); - - // An unmappable char (the 'cent' char) maps to a space - assertEquals(GsmAlphabet.charToGsm(' '), - GsmAlphabet.charToGsm('\u00a2')); - - // unmappable = space = 1 septet - assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2')); - - // - // Test extended table - // - - for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { - assertEquals(sGsmExtendedChars.charAt(i), - GsmAlphabet.gsmExtendedToChar( - GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i)))); - - } - - // Unmappable extended char - assertEquals(GsmAlphabet.charToGsm(' '), - GsmAlphabet.charToGsmExtended('@')); - - // - // gsmToChar() - // - - assertEquals('@', GsmAlphabet.gsmToChar(0)); - - // `a (a with grave accent) maps to last GSM character - assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f)); - - assertEquals('\uffff', - GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE)); - - // Out-of-range/unmappable value - assertEquals(' ', GsmAlphabet.gsmToChar(0x80)); - - // - // gsmExtendedToChar() - // - - assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28)); - - // No double-escapes - assertEquals(' ', GsmAlphabet.gsmExtendedToChar( - GsmAlphabet.GSM_EXTENDED_ESCAPE)); - - // Reserved for extension to extension table (mapped to space) - assertEquals(' ', GsmAlphabet.gsmExtendedToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE)); - - // Unmappable (mapped to character in default or national locking shift table) - assertEquals('@', GsmAlphabet.gsmExtendedToChar(0)); - assertEquals('\u00e0', GsmAlphabet.gsmExtendedToChar(0x7f)); - - // - // stringTo7BitPacked, gsm7BitPackedToString - // - - byte[] packed; - StringBuilder testString = new StringBuilder(300); - - // Check all alignment cases - for (int i = 0; i < 9; i++, testString.append('@')) { - packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - assertEquals(testString.toString(), - GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); - } - - // Check full non-extended alphabet - for (int i = 0; i < 0x80; i++) { - char c; - - if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) { - continue; - } - - c = GsmAlphabet.gsmToChar(i); - testString.append(c); - - // These are all non-extended chars, so it should be - // one septet per char - assertEquals(1, GsmAlphabet.countGsmSeptets(c)); - } - - packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - assertEquals(testString.toString(), - GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); - - // Test extended chars too - - testString.append(sGsmExtendedChars); - - for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { - // These are all extended chars, so it should be - // two septets per char - assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i))); - - } - - packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - assertEquals(testString.toString(), - GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); - - // stringTo7BitPacked handles up to 255 septets - - testString.setLength(0); - for (int i = 0; i < 255; i++) { - testString.append('@'); - } - - packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - assertEquals(testString.toString(), - GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); - - // > 255 septets throws runtime exception - testString.append('@'); - - try { - GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - fail("expected exception"); - } catch (EncodeException ex) { - // exception expected - } - - // Try 254 septets with 127 extended chars - - testString.setLength(0); - for (int i = 0; i < (255 / 2); i++) { - testString.append('{'); - } - - packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - assertEquals(testString.toString(), - GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); - - // > 255 septets throws runtime exception - testString.append('{'); - - try { - GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); - fail("expected exception"); - } catch (EncodeException ex) { - // exception expected - } - - // Reserved for extension to extension table (mapped to space) - packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1}; - assertEquals(" ", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); - - // Unmappable (mapped to character in default alphabet table) - packed[0] = 0x1b; - packed[1] = 0x00; - assertEquals("@", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); - packed[0] = (byte)(0x1b | 0x80); - packed[1] = (byte)(0x7f >> 1); - assertEquals("\u00e0", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); - - // - // 8 bit unpacked format - // - // Note: we compare hex strings here - // because Assert doesn't have array comparisons - - byte unpacked[]; - - unpacked = IccUtils.hexStringToBytes("566F696365204D61696C"); - assertEquals("Voice Mail", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - assertEquals(IccUtils.bytesToHexString(unpacked), - IccUtils.bytesToHexString( - GsmAlphabet.stringToGsm8BitPacked("Voice Mail"))); - - unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars); - // two bytes for every extended char - assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); - assertEquals(sGsmExtendedChars, - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - // should be two bytes per extended char - assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); - - // Test truncation of unaligned extended chars - unpacked = new byte[3]; - GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked, - 0, unpacked.length); - - // Should be one extended char and an 0xff at the end - - assertEquals(0xff, 0xff & unpacked[2]); - assertEquals(sGsmExtendedChars.substring(0, 1), - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - // Test truncation of normal chars - unpacked = new byte[3]; - GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, - 0, unpacked.length); - - assertEquals("abc", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - // Test truncation of mixed normal and extended chars - unpacked = new byte[3]; - GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked, - 0, unpacked.length); - - assertEquals("a{", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - // Test padding after normal char - unpacked = new byte[3]; - GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked, - 0, unpacked.length); - - assertEquals("a", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - assertEquals(0xff, 0xff & unpacked[1]); - assertEquals(0xff, 0xff & unpacked[2]); - - // Test malformed input -- escape char followed by end of field - unpacked[0] = 0; - unpacked[1] = 0; - unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE; - - assertEquals("@@", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); - - // non-zero offset - assertEquals("@", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); - - // test non-zero offset - unpacked[0] = 0; - GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, - 1, unpacked.length - 1); - - - assertEquals(0, unpacked[0]); - - assertEquals("ab", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); - - // test non-zero offset with truncated extended char - unpacked[0] = 0; - - GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked, - 1, unpacked.length - 1); - - assertEquals(0, unpacked[0]); - - assertEquals("a", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); - - // Reserved for extension to extension table (mapped to space) - unpacked[0] = 0x1b; - unpacked[1] = 0x1b; - assertEquals(" ", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); - - // Unmappable (mapped to character in default or national locking shift table) - unpacked[1] = 0x00; - assertEquals("@", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); - unpacked[1] = 0x7f; - assertEquals("\u00e0", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); - } - - @SmallTest - public void testGsm8BitUpackedWithEuckr() throws Exception { - // Some feature phones in Korea store contacts as euc-kr. - // Test this situations. - byte unpacked[]; - - // Test general alphabet strings. - unpacked = IccUtils.hexStringToBytes("61626320646566FF"); - assertEquals("abc def", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); - - // Test korean strings. - unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF"); - assertEquals("\uD14C\uC2A4\uD2B8", - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); - - // Test gsm Extented Characters. - unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars); - assertEquals(sGsmExtendedChars, - GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java deleted file mode 100644 index 595066957435..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java +++ /dev/null @@ -1,538 +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; - -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.internal.telephony.gsm.SmsMessage; -import com.android.internal.util.HexDump; - -import java.util.ArrayList; - -public class GsmSmsTest extends AndroidTestCase { - - @SmallTest - public void testAddressing() throws Exception { - String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E"; - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - assertEquals("+14155551212", sms.getServiceCenterAddress()); - assertEquals("+16505551111", sms.getOriginatingAddress()); - assertEquals("Test", sms.getMessageBody()); - - pdu = "07914151551512f2040B916105551511f100036060924180008A0DA" - + "8695DAC2E8FE9296A794E07"; - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - assertEquals("+14155551212", sms.getServiceCenterAddress()); - assertEquals("+16505551111", sms.getOriginatingAddress()); - assertEquals("(Subject)Test", sms.getMessageBody()); - } - - @SmallTest - public void testUdh() throws Exception { - String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F" - + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D" - + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426" - + "66C414141414D7741414236514141414141008D908918802B3135313232393737" - + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703" - + "A2F2F36"; - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - SmsHeader header = sms.getUserDataHeader(); - assertNotNull(header); - assertNotNull(header.concatRef); - assertEquals(header.concatRef.refNumber, 42); - assertEquals(header.concatRef.msgCount, 2); - assertEquals(header.concatRef.seqNumber, 1); - assertEquals(header.concatRef.isEightBits, true); - assertNotNull(header.portAddrs); - assertEquals(header.portAddrs.destPort, 2948); - assertEquals(header.portAddrs.origPort, 9200); - assertEquals(header.portAddrs.areEightBits, false); - - pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F" - + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141" - + "42666C414141414D774141423651414141414100"; - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - header = sms.getUserDataHeader(); - assertNotNull(header); - assertNotNull(header.concatRef); - assertEquals(header.concatRef.refNumber, 42); - assertEquals(header.concatRef.msgCount, 2); - assertEquals(header.concatRef.seqNumber, 2); - assertEquals(header.concatRef.isEightBits, true); - assertNotNull(header.portAddrs); - assertEquals(header.portAddrs.destPort, 2948); - assertEquals(header.portAddrs.origPort, 9200); - assertEquals(header.portAddrs.areEightBits, false); - } - - @SmallTest - public void testUcs2() throws Exception { - String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220" - + "0A900AE00680065006C006C006F"; - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody()); - } - - @SmallTest - public void testMultipart() throws Exception { - /* - * Multi-part text SMS with septet data. - */ - String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003" - + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C" - + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" - + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" - + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C" - + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562"; - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - assertEquals(sms.getMessageBody(), - "1111111111111111111111111111111111111111" - + "1111111111111111111111111111111111111111" - + "1111111111111111111111111111111111111111" - + "111111111111111111111111111111111"); - - pdu = "07916163838408F6440B816105224431F700007060217185000A23050003" - + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C"; - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - assertEquals("1111111222222222222222222222", sms.getMessageBody()); - } - - @SmallTest - public void testCPHSVoiceMail() throws Exception { - // "set MWI flag" - - String pdu = "07912160130310F20404D0110041006060627171118A0120"; - - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertTrue(sms.isReplace()); - assertEquals("_@", sms.getOriginatingAddress()); - assertEquals(" ", sms.getMessageBody()); - assertTrue(sms.isMWISetMessage()); - - // "clear mwi flag" - - pdu = "07912160130310F20404D0100041006021924193352B0120"; - - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertTrue(sms.isMWIClearMessage()); - - // "clear MWI flag" - - pdu = "07912160130310F20404D0100041006060627161058A0120"; - - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertTrue(sms.isReplace()); - assertEquals("\u0394@", sms.getOriginatingAddress()); - assertEquals(" ", sms.getMessageBody()); - assertTrue(sms.isMWIClearMessage()); - } - - @SmallTest - public void testCingularVoiceMail() throws Exception { - // "set MWI flag" - - String pdu = "07912180958750F84401800500C87020026195702B06040102000200"; - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertTrue(sms.isMWISetMessage()); - assertTrue(sms.isMwiDontStore()); - - // "clear mwi flag" - - pdu = "07912180958750F84401800500C07020027160112B06040102000000"; - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertTrue(sms.isMWIClearMessage()); - assertTrue(sms.isMwiDontStore()); - } - - @SmallTest - public void testEmailGateway() throws Exception { - String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" + - "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3"; - - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertEquals("+14155551212", sms.getServiceCenterAddress()); - assertTrue(sms.isEmail()); - assertEquals("foo@example.com", sms.getEmailFrom()); - assertEquals("foo@example.com", sms.getDisplayOriginatingAddress()); - // As of https://android-git.corp.google.com/g/#change,9324 - // getPseudoSubject will always be empty, and any subject is not extracted. - assertEquals("", sms.getPseudoSubject()); - assertEquals("test subject /test body", sms.getDisplayMessageBody()); - assertEquals("test subject /test body", sms.getEmailBody()); - - // email gateway sms test, including gsm extended character set. - pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" + - "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629"; - - sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertEquals("+14155551212", sms.getServiceCenterAddress()); - assertTrue(sms.isEmail()); - assertEquals("foo@example.com", sms.getDisplayOriginatingAddress()); - assertEquals("foo@example.com", sms.getEmailFrom()); - assertEquals("{ testBody[^~\\] }", sms.getDisplayMessageBody()); - assertEquals("{ testBody[^~\\] }", sms.getEmailBody()); - } - - @SmallTest - public void testExtendedCharacterTable() throws Exception { - String pdu = "07914151551512f2040B916105551511f100006080615131728A44D4F29C0E2" + - "AE3E96537B94C068DD16179784C2FCB41F4B0985D06B958ADD00FB0E94536AF9749" + - "74DA6D281BA00E95E26D509B946FC3DBF87A25D56A04"; - - SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu)); - - assertEquals("+14155551212", sms.getServiceCenterAddress()); - assertEquals("+16505551111", sms.getOriginatingAddress()); - assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#", - sms.getMessageBody()); - } - - // GSM 7 bit tables in String form, Escape (0x1B) replaced with '@' - private static final String[] sBasicTables = { - // GSM 7 bit default alphabet - "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_" - + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u00c6\u00e6\u00df\u00c9" - + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" - + "\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", - - // Turkish locking shift table - "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_" - + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u015e\u015f\u00df\u00c9" - + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6" - + "\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0", - - // no locking shift table defined for Spanish - "", - - // Portuguese locking shift table - "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_" - + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|@\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba%&'()" - + "*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc" - + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0" - }; - - @SmallTest - public void testFragmentText() throws Exception { - boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == - TelephonyManager.PHONE_TYPE_GSM); - - // Valid 160 character 7-bit text. - String text = "123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901234567890123456789012345678901234567890" + - "123456789012345678901234567890"; - SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); - assertEquals(1, ted.msgCount); - assertEquals(160, ted.codeUnitCount); - assertEquals(1, ted.codeUnitSize); - assertEquals(0, ted.languageTable); - assertEquals(0, ted.languageShiftTable); - if (isGsmPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); - assertEquals(1, fragments.size()); - } - - // Valid 161 character 7-bit text. - text = "123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901"; - ted = SmsMessage.calculateLength(text, false); - assertEquals(2, ted.msgCount); - assertEquals(161, ted.codeUnitCount); - assertEquals(1, ted.codeUnitSize); - assertEquals(0, ted.languageTable); - assertEquals(0, ted.languageShiftTable); - if (isGsmPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); - assertEquals(2, fragments.size()); - assertEquals(text, fragments.get(0) + fragments.get(1)); - assertEquals(153, fragments.get(0).length()); - assertEquals(8, fragments.get(1).length()); - } - } - - @SmallTest - public void testFragmentTurkishText() throws Exception { - boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == - TelephonyManager.PHONE_TYPE_GSM); - - int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); - int[] turkishTable = { 1 }; - GsmAlphabet.setEnabledSingleShiftTables(turkishTable); - - // Valid 77 character text with Turkish characters. - String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + - "ĞŞİğşıĞŞİğşıĞŞİğş"; - SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); - assertEquals(1, ted.msgCount); - assertEquals(154, ted.codeUnitCount); - assertEquals(1, ted.codeUnitSize); - assertEquals(0, ted.languageTable); - assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); - assertEquals(1, fragments.size()); - assertEquals(text, fragments.get(0)); - assertEquals(77, fragments.get(0).length()); - } - - // Valid 78 character text with Turkish characters. - text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + - "ĞŞİğşıĞŞİğşıĞŞİğşı"; - ted = SmsMessage.calculateLength(text, false); - assertEquals(2, ted.msgCount); - assertEquals(156, ted.codeUnitCount); - assertEquals(1, ted.codeUnitSize); - assertEquals(0, ted.languageTable); - assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); - assertEquals(2, fragments.size()); - assertEquals(text, fragments.get(0) + fragments.get(1)); - assertEquals(74, fragments.get(0).length()); - assertEquals(4, fragments.get(1).length()); - } - - // Valid 160 character text with Turkish characters. - text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + - "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" + - "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı"; - ted = SmsMessage.calculateLength(text, false); - assertEquals(3, ted.msgCount); - assertEquals(320, ted.codeUnitCount); - assertEquals(1, ted.codeUnitSize); - assertEquals(0, ted.languageTable); - assertEquals(1, ted.languageShiftTable); - if (isGsmPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text); - assertEquals(3, fragments.size()); - assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); - assertEquals(74, fragments.get(0).length()); - assertEquals(74, fragments.get(1).length()); - assertEquals(12, fragments.get(2).length()); - } - - GsmAlphabet.setEnabledSingleShiftTables(oldTables); - } - - - @SmallTest - public void testDecode() throws Exception { - decodeSingle(0); // default table - decodeSingle(1); // Turkish locking shift table - decodeSingle(3); // Portuguese locking shift table - } - - private void decodeSingle(int language) throws Exception { - byte[] septets = new byte[(7 * 128 + 7) / 8]; - - int bitOffset = 0; - - for (int i = 0; i < 128; i++) { - int v; - if (i == 0x1b) { - // extended escape char - v = 0; - } else { - v = i; - } - - int byteOffset = bitOffset / 8; - int shift = bitOffset % 8; - - septets[byteOffset] |= v << shift; - - if (shift > 1) { - septets[byteOffset + 1] = (byte) (v >> (8 - shift)); - } - - bitOffset += 7; - } - - String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, 128, 0, language, 0); - byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, language, 0); - - assertEquals(sBasicTables[language], decoded); - - // reEncoded has the count septets byte at the front - assertEquals(septets.length + 1, reEncoded.length); - - for (int i = 0; i < septets.length; i++) { - assertEquals(septets[i], reEncoded[i + 1]); - } - } - - private static final int GSM_ESCAPE_CHARACTER = 0x1b; - - private static final String[] sExtendedTables = { - // GSM 7 bit default alphabet extension table - "\f^{}\\[~]|\u20ac", - - // Turkish single shift extension table - "\f^{}\\[~]|\u011e\u0130\u015e\u00e7\u20ac\u011f\u0131\u015f", - - // Spanish single shift extension table - "\u00e7\f^{}\\[~]|\u00c1\u00cd\u00d3\u00da\u00e1\u20ac\u00ed\u00f3\u00fa", - - // Portuguese single shift extension table - "\u00ea\u00e7\f\u00d4\u00f4\u00c1\u00e1\u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398\u00ca" - + "{}\\[~]|\u00c0\u00cd\u00d3\u00da\u00c3\u00d5\u00c2\u20ac\u00ed\u00f3\u00fa\u00e3" - + "\u00f5\u00e2" - }; - - private static final int[][] sExtendedTableIndexes = { - {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x65}, - {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x47, 0x49, 0x53, 0x63, - 0x65, 0x67, 0x69, 0x73}, - {0x09, 0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 0x4f, - 0x55, 0x61, 0x65, 0x69, 0x6f, 0x75}, - {0x05, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1f, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, - 0x4f, 0x55, 0x5b, 0x5c, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x7c, 0x7f} - }; - - @SmallTest - public void testDecodeExtended() throws Exception { - for (int language = 0; language < 3; language++) { - int[] tableIndex = sExtendedTableIndexes[language]; - int numSeptets = tableIndex.length * 2; // two septets per extended char - byte[] septets = new byte[(7 * numSeptets + 7) / 8]; - - int bitOffset = 0; - - for (int v : tableIndex) { - // escape character - int byteOffset = bitOffset / 8; - int shift = bitOffset % 8; - - septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; - - if (shift > 1) { - septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); - } - - bitOffset += 7; - - // extended table index - byteOffset = bitOffset / 8; - shift = bitOffset % 8; - - septets[byteOffset] |= v << shift; - - if (shift > 1) { - septets[byteOffset + 1] = (byte) (v >> (8 - shift)); - } - - bitOffset += 7; - } - - String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, - 0, language); - byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, 0, language); - - assertEquals(sExtendedTables[language], decoded); - - // reEncoded has the count septets byte at the front - assertEquals(septets.length + 1, reEncoded.length); - - for (int i = 0; i < septets.length; i++) { - assertEquals(septets[i], reEncoded[i + 1]); - } - } - } - - @SmallTest - public void testDecodeExtendedFallback() throws Exception { - // verify that unmapped characters in extension table fall back to locking shift table - for (int language = 0; language < 3; language++) { - int[] tableIndex = sExtendedTableIndexes[language]; - int numChars = 128 - tableIndex.length; - int numSeptets = numChars * 2; // two septets per extended char - byte[] septets = new byte[(7 * numSeptets + 7) / 8]; - - int tableOffset = 0; - int bitOffset = 0; - - StringBuilder defaultTable = new StringBuilder(128); - StringBuilder turkishTable = new StringBuilder(128); - StringBuilder portugueseTable = new StringBuilder(128); - - for (char c = 0; c < 128; c++) { - // skip characters that are present in the current extension table - if (tableOffset < tableIndex.length && tableIndex[tableOffset] == c) { - tableOffset++; - continue; - } - - // escape character - int byteOffset = bitOffset / 8; - int shift = bitOffset % 8; - - septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift; - - if (shift > 1) { - septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift)); - } - - bitOffset += 7; - - // extended table index - byteOffset = bitOffset / 8; - shift = bitOffset % 8; - - septets[byteOffset] |= c << shift; - - if (shift > 1) { - septets[byteOffset + 1] = (byte) (c >> (8 - shift)); - } - - bitOffset += 7; - - if (c == GsmAlphabet.GSM_EXTENDED_ESCAPE) { - // double Escape maps to space character - defaultTable.append(' '); - turkishTable.append(' '); - portugueseTable.append(' '); - } else { - // other unmapped chars map to the default or locking shift table - defaultTable.append(sBasicTables[0].charAt(c)); - turkishTable.append(sBasicTables[1].charAt(c)); - portugueseTable.append(sBasicTables[3].charAt(c)); - } - } - - String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, - 0, language); - - assertEquals(defaultTable.toString(), decoded); - - decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 1, language); - assertEquals(turkishTable.toString(), decoded); - - decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 3, language); - assertEquals(portugueseTable.toString(), decoded); - } - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java deleted file mode 100644 index c89f33a8301f..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2011 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * Test IccServiceTable class. - */ -public class IccServiceTableTest extends AndroidTestCase { - - static class TestIccServiceTable extends IccServiceTable { - public enum TestIccService { - SERVICE1, - SERVICE2, - SERVICE3, - SERVICE4 - } - - public TestIccServiceTable(byte[] table) { - super(table); - } - - public boolean isAvailable(TestIccService service) { - return super.isAvailable(service.ordinal()); - } - - @Override - protected String getTag() { - return "TestIccServiceTable"; - } - - @Override - protected Object[] getValues() { - return TestIccService.values(); - } - } - - @SmallTest - public void testIccServiceTable() { - byte[] noServices = {0x00}; - byte[] service1 = {0x01}; - byte[] service4 = {0x08}; - byte[] allServices = {0x0f}; - - TestIccServiceTable testTable1 = new TestIccServiceTable(noServices); - assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1)); - assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2)); - assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3)); - assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4)); - - TestIccServiceTable testTable2 = new TestIccServiceTable(service1); - assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1)); - assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2)); - assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3)); - assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4)); - - TestIccServiceTable testTable3 = new TestIccServiceTable(service4); - assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1)); - assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2)); - assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3)); - assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4)); - - TestIccServiceTable testTable4 = new TestIccServiceTable(allServices); - assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1)); - assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2)); - assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3)); - assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4)); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java deleted file mode 100644 index 79dca39f156b..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (C) 2011 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.test.AndroidTestCase; - -import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; - -import java.util.ArrayList; - -/** - * Test cases for the IntRangeManager class. - */ -public class IntRangeManagerTest extends AndroidTestCase { - - private static final int SMS_CB_CODE_SCHEME_MIN = 0; - private static final int SMS_CB_CODE_SCHEME_MAX = 255; - - private static final int FLAG_START_UPDATE_CALLED = 0x01; - private static final int FLAG_ADD_RANGE_CALLED = 0x02; - private static final int FLAG_FINISH_UPDATE_CALLED = 0x04; - - private static final int ALL_FLAGS_SET = FLAG_START_UPDATE_CALLED | FLAG_ADD_RANGE_CALLED | - FLAG_FINISH_UPDATE_CALLED; - - /** Dummy IntRangeManager for testing. */ - class TestIntRangeManager extends IntRangeManager { - ArrayList mConfigList = - new ArrayList(); - - int flags; - boolean finishUpdateReturnValue = true; - - /** - * Called when the list of enabled ranges has changed. This will be - * followed by zero or more calls to {@link #addRange} followed by - * a call to {@link #finishUpdate}. - */ - protected void startUpdate() { - mConfigList.clear(); - flags |= FLAG_START_UPDATE_CALLED; - } - - /** - * Called after {@link #startUpdate} to indicate a range of enabled - * values. - * @param startId the first id included in the range - * @param endId the last id included in the range - */ - protected void addRange(int startId, int endId, boolean selected) { - mConfigList.add(new SmsBroadcastConfigInfo(startId, endId, - SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected)); - flags |= FLAG_ADD_RANGE_CALLED; - } - - /** - * Called to indicate the end of a range update started by the - * previous call to {@link #startUpdate}. - */ - protected boolean finishUpdate() { - flags |= FLAG_FINISH_UPDATE_CALLED; - return finishUpdateReturnValue; - } - - /** Reset the object for the next test case. */ - void reset() { - flags = 0; - mConfigList.clear(); - } - } - - public void testEmptyRangeManager() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("expecting empty configlist", 0, testManager.mConfigList.size()); - } - - private void checkConfigInfo(SmsBroadcastConfigInfo info, int fromServiceId, - int toServiceId, int fromCodeScheme, int toCodeScheme, boolean selected) { - assertEquals("fromServiceId", fromServiceId, info.getFromServiceId()); - assertEquals("toServiceId", toServiceId, info.getToServiceId()); - assertEquals("fromCodeScheme", fromCodeScheme, info.getFromCodeScheme()); - assertEquals("toCodeScheme", toCodeScheme, info.getToCodeScheme()); - assertEquals("selected", selected, info.isSelected()); - } - - public void testAddSingleChannel() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("flags before test", 0, testManager.flags); - assertTrue("enabling range", testManager.enableRange(123, 123, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - } - - public void testRemoveSingleChannel() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertTrue("enabling range", testManager.enableRange(123, 123, "client1")); - assertEquals("flags after enable", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - testManager.reset(); - assertTrue("disabling range", testManager.disableRange(123, 123, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED, - testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - } - - public void testRemoveBadChannel() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertFalse("disabling missing range", testManager.disableRange(123, 123, "client1")); - assertEquals("flags after test", 0, testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - } - - public void testAddTwoChannels() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("flags before test", 0, testManager.flags); - assertTrue("enabling range 1", testManager.enableRange(100, 120, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 2", testManager.enableRange(200, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 200, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 2, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 200, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - } - - public void testOverlappingChannels() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("flags before test", 0, testManager.flags); - assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 149, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED, - testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - } - - public void testOverlappingChannels2() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("flags before test", 0, testManager.flags); - assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - } - - public void testMultipleOverlappingChannels() { - TestIntRangeManager testManager = new TestIntRangeManager(); - assertEquals("flags before test", 0, testManager.flags); - assertTrue("enabling range 1", testManager.enableRange(67, 9999, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 67, 9999, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2")); - assertEquals("flags after test", 0, testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - testManager.reset(); - assertTrue("enabling range 3", testManager.enableRange(25, 75, "client3")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 66, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 4", testManager.enableRange(12, 500, "client4")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("enabling range 5", testManager.enableRange(8000, 9998, "client5")); - assertEquals("flags after test", 0, testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - testManager.reset(); - assertTrue("enabling range 6", testManager.enableRange(50000, 65535, "client6")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 2, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 12, 9999, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 1", testManager.disableRange(67, 9999, "client1")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 2, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 501, 7999, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - checkConfigInfo(testManager.mConfigList.get(1), 9999, 9999, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 3, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 12, 500, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 8000, 9998, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 4", testManager.disableRange(12, 500, "client4")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 3, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - checkConfigInfo(testManager.mConfigList.get(1), 76, 149, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - checkConfigInfo(testManager.mConfigList.get(2), 251, 500, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 4, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(2), 8000, 9998, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(3), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 5", testManager.disableRange(8000, 9998, "client5")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 8000, 9998, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 3, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 6", testManager.disableRange(50000, 65535, "client6")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 2, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, true); - testManager.reset(); - assertTrue("disabling range 3", testManager.disableRange(25, 75, "client3")); - assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags); - assertEquals("configlist size", 1, testManager.mConfigList.size()); - checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN, - SMS_CB_CODE_SCHEME_MAX, false); - testManager.reset(); - assertTrue("updating ranges", testManager.updateRanges()); - assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED, - testManager.flags); - assertEquals("configlist size", 0, testManager.mConfigList.size()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java deleted file mode 100644 index 868c76d5b248..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java +++ /dev/null @@ -1,75 +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; - -import com.android.internal.telephony.MccTable; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import android.util.Log; - -public class MccTableTest extends AndroidTestCase { - private final static String LOG_TAG = "GSM"; - - @SmallTest - public void testTimeZone() throws Exception { - assertEquals(MccTable.defaultTimeZoneForMcc(208), "ECT"); - assertEquals(MccTable.defaultTimeZoneForMcc(232), "Europe/Vienna"); - assertEquals(MccTable.defaultTimeZoneForMcc(655), "Africa/Johannesburg"); - assertEquals(MccTable.defaultTimeZoneForMcc(440), "Asia/Tokyo"); - assertEquals(MccTable.defaultTimeZoneForMcc(441), "Asia/Tokyo"); - assertEquals(MccTable.defaultTimeZoneForMcc(525), "Asia/Singapore"); - assertEquals(MccTable.defaultTimeZoneForMcc(240), null); // tz not defined, hence default - assertEquals(MccTable.defaultTimeZoneForMcc(0), null); // mcc not defined, hence default - assertEquals(MccTable.defaultTimeZoneForMcc(2000), null); // mcc not defined, hence default - } - - @SmallTest - public void testCountryCode() throws Exception { - assertEquals(MccTable.countryCodeForMcc(270), "lu"); - assertEquals(MccTable.countryCodeForMcc(202), "gr"); - assertEquals(MccTable.countryCodeForMcc(750), "fk"); - assertEquals(MccTable.countryCodeForMcc(646), "mg"); - assertEquals(MccTable.countryCodeForMcc(314), "us"); - assertEquals(MccTable.countryCodeForMcc(300), ""); // mcc not defined, hence default - assertEquals(MccTable.countryCodeForMcc(0), ""); // mcc not defined, hence default - assertEquals(MccTable.countryCodeForMcc(2000), ""); // mcc not defined, hence default - } - - @SmallTest - public void testLang() throws Exception { - assertEquals(MccTable.defaultLanguageForMcc(311), "en"); - assertEquals(MccTable.defaultLanguageForMcc(232), "de"); - assertEquals(MccTable.defaultLanguageForMcc(230), "cs"); - assertEquals(MccTable.defaultLanguageForMcc(204), "nl"); - assertEquals(MccTable.defaultLanguageForMcc(274), null); // lang not defined, hence default - assertEquals(MccTable.defaultLanguageForMcc(0), null); // mcc not defined, hence default - assertEquals(MccTable.defaultLanguageForMcc(2000), null); // mcc not defined, hence default - } - - @SmallTest - public void testSmDigits() throws Exception { - assertEquals(MccTable.smallestDigitsMccForMnc(312), 3); - assertEquals(MccTable.smallestDigitsMccForMnc(430), 2); - assertEquals(MccTable.smallestDigitsMccForMnc(365), 3); - assertEquals(MccTable.smallestDigitsMccForMnc(536), 2); - assertEquals(MccTable.smallestDigitsMccForMnc(352), 2); // sd not defined, hence default - assertEquals(MccTable.smallestDigitsMccForMnc(0), 2); // mcc not defined, hence default - assertEquals(MccTable.smallestDigitsMccForMnc(2000), 2); // mcc not defined, hence default - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java deleted file mode 100644 index b63dc71b45fc..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.internal.telephony; - -import android.os.Parcel; -import android.test.AndroidTestCase; -import android.telephony.NeighboringCellInfo; -import android.test. suitebuilder.annotation.SmallTest; - -import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; -import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE; -import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS; -import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS; - -public class NeighboringCellInfoTest extends AndroidTestCase { - @SmallTest - public void testConstructor() { - int rssi = 31; - NeighboringCellInfo nc; - - nc = new NeighboringCellInfo(rssi, "FFFFFFF", NETWORK_TYPE_EDGE); - assertEquals(NETWORK_TYPE_EDGE, nc.getNetworkType()); - assertEquals(rssi, nc.getRssi()); - assertEquals(0xfff, nc.getLac()); - assertEquals(0xffff, nc.getCid()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc()); - - nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UMTS); - assertEquals(NETWORK_TYPE_UMTS, nc.getNetworkType()); - assertEquals(rssi, nc.getRssi()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac()); - assertEquals(0x1ff, nc.getPsc()); - - nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UNKNOWN); - assertEquals(NETWORK_TYPE_UNKNOWN, nc.getNetworkType()); - assertEquals(rssi, nc.getRssi()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc()); - } - - @SmallTest - public void testParcel() { - int rssi = 20; - - NeighboringCellInfo nc = new NeighboringCellInfo(rssi, "12345678", NETWORK_TYPE_GPRS); - assertEquals(NETWORK_TYPE_GPRS, nc.getNetworkType()); - assertEquals(rssi, nc.getRssi()); - assertEquals(0x1234, nc.getLac()); - assertEquals(0x5678, nc.getCid()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc()); - - Parcel p = Parcel.obtain(); - p.setDataPosition(0); - nc.writeToParcel(p, 0); - - p.setDataPosition(0); - NeighboringCellInfo nw = new NeighboringCellInfo(p); - assertEquals(NETWORK_TYPE_GPRS, nw.getNetworkType()); - assertEquals(rssi, nw.getRssi()); - assertEquals(0x1234, nw.getLac()); - assertEquals(0x5678, nw.getCid()); - assertEquals(NeighboringCellInfo.UNKNOWN_CID, nw.getPsc()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java deleted file mode 100644 index db670f8919de..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java +++ /dev/null @@ -1,657 +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; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.text.SpannableStringBuilder; -import android.telephony.PhoneNumberUtils; - -public class PhoneNumberUtilsTest extends AndroidTestCase { - - @SmallTest - public void testExtractNetworkPortion() throws Exception { - assertEquals( - "+17005554141", - PhoneNumberUtils.extractNetworkPortion("+17005554141") - ); - - assertEquals( - "+17005554141", - PhoneNumberUtils.extractNetworkPortion("+1 (700).555-4141") - ); - - assertEquals( - "17005554141", - PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141") - ); - - // This may seem wrong, but it's probably ok - assertEquals( - "17005554141*#", - PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141*#") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN,1234") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN;1234") - ); - - // An MMI string is unperterbed, even though it contains a - // (valid in this case) embedded + - assertEquals( - "**21**17005554141#", - PhoneNumberUtils.extractNetworkPortion("**21**+17005554141#") - //TODO this is the correct result, although the above - //result has been returned since change 31776 - //"**21**+17005554141#" - ); - - assertEquals("", PhoneNumberUtils.extractNetworkPortion("")); - - assertEquals("", PhoneNumberUtils.extractNetworkPortion(",1234")); - - byte [] b = new byte[20]; - b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; - assertEquals("17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; - assertEquals("17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; - assertEquals("+17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; - assertEquals("+17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - byte[] bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("+17005550020"); - assertEquals(7, bRet.length); - for (int i = 0; i < 7; i++) { - assertEquals(b[i], bRet[i]); - } - - bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020"); - assertEquals(8, bRet.length); - assertEquals(bRet[0], 7); - for (int i = 1; i < 8; i++) { - assertEquals(b[i - 1], bRet[i]); - } - - bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020"); - assertEquals("7005550020", - PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length)); - - b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0; - assertEquals("17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; - b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0; - assertEquals("+17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); - - b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1; - assertEquals("*21#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 3)); - - b[0] = (byte) 0x81; b[1] = (byte) 0x2B; b[2] = (byte) 0xB1; - assertEquals("#21#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 3)); - - b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1; - assertEquals("*21#+", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 3)); - - b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB; - assertEquals("**21#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 4)); - - b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB; - assertEquals("**21#+", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 4)); - - b[0] = (byte) 0x81; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71; - b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20; - b[8] = (byte) 0xB0; - assertEquals("*99*17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 9)); - - b[0] = (byte) 0x91; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71; - b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20; - b[8] = (byte) 0xB0; - assertEquals("*99*+17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 9)); - - b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A; - b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00; - b[8] = (byte) 0x02; b[9] = (byte) 0xFB; - assertEquals("**21*17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 10)); - - b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A; - b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00; - b[8] = (byte) 0x02; b[9] = (byte) 0xFB; - assertEquals("**21*+17005550020#", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 10)); - - b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xA1; b[3] = (byte) 0x71; - b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20; - b[8] = (byte) 0xF0; - assertEquals("*21*17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 9)); - - b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1; b[3] = (byte) 0x71; - b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20; - b[8] = (byte) 0xF0; - assertEquals("*21#+17005550020", - PhoneNumberUtils.calledPartyBCDToString(b, 0, 9)); - - assertNull(PhoneNumberUtils.extractNetworkPortion(null)); - assertNull(PhoneNumberUtils.extractPostDialPortion(null)); - assertTrue(PhoneNumberUtils.compare(null, null)); - assertFalse(PhoneNumberUtils.compare(null, "123")); - assertFalse(PhoneNumberUtils.compare("123", null)); - assertNull(PhoneNumberUtils.toCallerIDMinMatch(null)); - assertNull(PhoneNumberUtils.getStrippedReversed(null)); - assertNull(PhoneNumberUtils.stringFromStringAndTOA(null, 1)); - } - - @SmallTest - public void testExtractNetworkPortionAlt() throws Exception { - assertEquals( - "+17005554141", - PhoneNumberUtils.extractNetworkPortionAlt("+17005554141") - ); - - assertEquals( - "+17005554141", - PhoneNumberUtils.extractNetworkPortionAlt("+1 (700).555-4141") - ); - - assertEquals( - "17005554141", - PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141") - ); - - // This may seem wrong, but it's probably ok - assertEquals( - "17005554141*#", - PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141*#") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN,1234") - ); - - assertEquals( - "170055541NN", - PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN;1234") - ); - - // An MMI string is unperterbed, even though it contains a - // (valid in this case) embedded + - assertEquals( - "**21**+17005554141#", - PhoneNumberUtils.extractNetworkPortionAlt("**21**+17005554141#") - ); - - assertEquals( - "*31#+447966164208", - PhoneNumberUtils.extractNetworkPortionAlt("*31#+447966164208") - ); - - assertEquals( - "*31#+447966164208", - PhoneNumberUtils.extractNetworkPortionAlt("*31# (+44) 79 6616 4208") - ); - - assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt("")); - - assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt(",1234")); - - assertNull(PhoneNumberUtils.extractNetworkPortionAlt(null)); - } - - @SmallTest - public void testB() throws Exception { - assertEquals("", PhoneNumberUtils.extractPostDialPortion("+17005554141")); - assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-4141")); - assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN")); - assertEquals(",1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN,1234")); - assertEquals(";1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1234")); - assertEquals(";1234,;N", - PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1-2.34 ,;N")); - } - - @SmallTest - public void testCompare() throws Exception { - // this is odd - assertFalse(PhoneNumberUtils.compare("", "")); - - assertTrue(PhoneNumberUtils.compare("911", "911")); - assertFalse(PhoneNumberUtils.compare("911", "18005550911")); - assertTrue(PhoneNumberUtils.compare("5555", "5555")); - assertFalse(PhoneNumberUtils.compare("5555", "180055555555")); - - assertTrue(PhoneNumberUtils.compare("+17005554141", "+17005554141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141,1234")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "17005554141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "7005554141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "5554141")); - assertTrue(PhoneNumberUtils.compare("17005554141", "5554141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "01117005554141")); - assertTrue(PhoneNumberUtils.compare("+17005554141", "0017005554141")); - assertTrue(PhoneNumberUtils.compare("17005554141", "0017005554141")); - - - assertTrue(PhoneNumberUtils.compare("+17005554141", "**31#+17005554141")); - - assertFalse(PhoneNumberUtils.compare("+1 999 7005554141", "+1 7005554141")); - assertTrue(PhoneNumberUtils.compare("011 1 7005554141", "7005554141")); - - assertFalse(PhoneNumberUtils.compare("011 11 7005554141", "+17005554141")); - - assertFalse(PhoneNumberUtils.compare("+17005554141", "7085882300")); - - assertTrue(PhoneNumberUtils.compare("+44 207 792 3490", "0 207 792 3490")); - - assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "00 207 792 3490")); - assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "011 207 792 3490")); - - /***** FIXME's ******/ - // - // MMI header should be ignored - assertFalse(PhoneNumberUtils.compare("+17005554141", "**31#17005554141")); - - // It's too bad this is false - // +44 (0) 207 792 3490 is not a dialable number - // but it is commonly how European phone numbers are written - assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "+44 (0) 207 792 3490")); - - // The japanese international prefix, for example, messes us up - // But who uses a GSM phone in Japan? - assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "010 44 207 792 3490")); - - // The Australian one messes us up too - assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "0011 44 207 792 3490")); - - // The Russian trunk prefix messes us up, as does current - // Russian area codes (which bein with 0) - - assertFalse(PhoneNumberUtils.compare("+7(095)9100766", "8(095)9100766")); - - // 444 is not a valid country code, but - // matchIntlPrefixAndCC doesnt know this - assertTrue(PhoneNumberUtils.compare("+444 207 792 3490", "0 207 792 3490")); - - // compare SMS short code - assertTrue(PhoneNumberUtils.compare("404-04", "40404")); - } - - - @SmallTest - public void testToCallerIDIndexable() throws Exception { - assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141")); - assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141")); - assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234")); - assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234")); - - //this seems wrong, or at least useless - assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN")); - - // -- these are all not useful, but not terribly wrong - assertEquals("", PhoneNumberUtils.toCallerIDMinMatch("")); - assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300")); - assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300")); - assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#")); - } - - @SmallTest - public void testGetIndexable() throws Exception { - assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141")); - assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141,1234")); - assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141;1234")); - - //this seems wrong, or at least useless - assertEquals("NN145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-41NN")); - - // -- these are all not useful, but not terribly wrong - assertEquals("", PhoneNumberUtils.getStrippedReversed("")); - assertEquals("0032", PhoneNumberUtils.getStrippedReversed("2300")); - assertEquals("0032+", PhoneNumberUtils.getStrippedReversed("+2300")); - assertEquals("#130#*", PhoneNumberUtils.getStrippedReversed("*#031#")); - } - - @SmallTest - public void testNanpFormatting() { - SpannableStringBuilder number = new SpannableStringBuilder(); - number.append("8005551212"); - PhoneNumberUtils.formatNanpNumber(number); - assertEquals("800-555-1212", number.toString()); - - number.clear(); - number.append("800555121"); - PhoneNumberUtils.formatNanpNumber(number); - assertEquals("800-555-121", number.toString()); - - number.clear(); - number.append("555-1212"); - PhoneNumberUtils.formatNanpNumber(number); - assertEquals("555-1212", number.toString()); - - number.clear(); - number.append("800-55512"); - PhoneNumberUtils.formatNanpNumber(number); - assertEquals("800-555-12", number.toString()); - - number.clear(); - number.append("46645"); - PhoneNumberUtils.formatNanpNumber(number); - assertEquals("46645", number.toString()); - } - - @SmallTest - public void testConvertKeypadLettersToDigits() { - assertEquals("1-800-4664-411", - PhoneNumberUtils.convertKeypadLettersToDigits("1-800-GOOG-411")); - assertEquals("18004664411", - PhoneNumberUtils.convertKeypadLettersToDigits("1800GOOG411")); - assertEquals("1-800-466-4411", - PhoneNumberUtils.convertKeypadLettersToDigits("1-800-466-4411")); - assertEquals("18004664411", - PhoneNumberUtils.convertKeypadLettersToDigits("18004664411")); - assertEquals("222-333-444-555-666-7777-888-9999", - PhoneNumberUtils.convertKeypadLettersToDigits( - "ABC-DEF-GHI-JKL-MNO-PQRS-TUV-WXYZ")); - assertEquals("222-333-444-555-666-7777-888-9999", - PhoneNumberUtils.convertKeypadLettersToDigits( - "abc-def-ghi-jkl-mno-pqrs-tuv-wxyz")); - assertEquals("(800) 222-3334", - PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG")); - } - - // To run this test, the device has to be registered with network - public void testCheckAndProcessPlusCode() { - assertEquals("0118475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000")); - assertEquals("18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+18475797000")); - assertEquals("0111234567", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+1234567")); - assertEquals("01123456700000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+23456700000")); - assertEquals("01111875767800", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+11875767800")); - assertEquals("8475797000,18475231753", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+18475231753")); - assertEquals("0118475797000,18475231753", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000,+18475231753")); - assertEquals("8475797000;0118469312345", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;+8469312345")); - assertEquals("8475797000,0111234567", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+1234567")); - assertEquals("847597000;01111875767000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847597000;+11875767000")); - assertEquals("8475797000,,0118469312345", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,+8469312345")); - assertEquals("8475797000;,0118469312345", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+8469312345")); - assertEquals("8475797000,;18475231753", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+18475231753")); - assertEquals("8475797000;,01111875767000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+11875767000")); - assertEquals("8475797000,;01111875767000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+11875767000")); - assertEquals("8475797000,,,01111875767000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,,+11875767000")); - assertEquals("8475797000;,,01111875767000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,,+11875767000")); - assertEquals("+;,8475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+;,8475797000")); - assertEquals("8475797000,", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,")); - assertEquals("847+579-7000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847+579-7000")); - assertEquals(",8475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode(",8475797000")); - assertEquals(";;8475797000,,", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode(";;8475797000,,")); - assertEquals("+this+is$weird;,+", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+this+is$weird;,+")); - assertEquals("", - PhoneNumberUtils.cdmaCheckAndProcessPlusCode("")); - assertNull(PhoneNumberUtils.cdmaCheckAndProcessPlusCode(null)); - } - - @SmallTest - public void testCheckAndProcessPlusCodeByNumberFormat() { - assertEquals("18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000", - PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_NANP)); - assertEquals("+18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000", - PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_JAPAN)); - assertEquals("+18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000", - PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_UNKNOWN)); - assertEquals("+18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000", - PhoneNumberUtils.FORMAT_JAPAN,PhoneNumberUtils.FORMAT_JAPAN)); - assertEquals("+18475797000", - PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000", - PhoneNumberUtils.FORMAT_UNKNOWN,PhoneNumberUtils.FORMAT_UNKNOWN)); - } - - /** - * Basic checks for the VoiceMail number. - */ - @SmallTest - public void testWithNumberNotEqualToVoiceMail() throws Exception { - assertFalse(PhoneNumberUtils.isVoiceMailNumber("911")); - assertFalse(PhoneNumberUtils.isVoiceMailNumber("tel:911")); - assertFalse(PhoneNumberUtils.isVoiceMailNumber("+18001234567")); - assertFalse(PhoneNumberUtils.isVoiceMailNumber("")); - assertFalse(PhoneNumberUtils.isVoiceMailNumber(null)); - // This test fails on a device without a sim card - /*TelephonyManager mTelephonyManager = - (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE); - String mVoiceMailNumber = mTelephonyManager.getDefault().getVoiceMailNumber(); - assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber)); - */ - } - - @SmallTest - public void testFormatNumberToE164() { - // Note: ISO 3166-1 only allows upper case country codes. - assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US")); - assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US")); - assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US")); - } - - @SmallTest - public void testFormatNumber() { - assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "US")); - assertEquals("223-4567", PhoneNumberUtils.formatNumber("2234567", "US")); - assertEquals("011 86 10 8888 0000", - PhoneNumberUtils.formatNumber("011861088880000", "US")); - assertEquals("010 8888 0000", PhoneNumberUtils.formatNumber("01088880000", "CN")); - // formatNumber doesn't format alpha numbers, but keep them as they are. - assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US")); - } - - @SmallTest - public void testFormatNumber_LeadingStarAndHash() { - // Numbers with a leading '*' or '#' should be left unchanged. - assertEquals("*650 2910000", PhoneNumberUtils.formatNumber("*650 2910000", "US")); - assertEquals("#650 2910000", PhoneNumberUtils.formatNumber("#650 2910000", "US")); - assertEquals("*#650 2910000", PhoneNumberUtils.formatNumber("*#650 2910000", "US")); - assertEquals("#*650 2910000", PhoneNumberUtils.formatNumber("#*650 2910000", "US")); - assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US")); - assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US")); - assertEquals("##650 2910000", PhoneNumberUtils.formatNumber("##650 2910000", "US")); - assertEquals("**650 2910000", PhoneNumberUtils.formatNumber("**650 2910000", "US")); - } - - @SmallTest - public void testNormalizeNumber() { - assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000")); - assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567")); - assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114")); - assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000")); - } - - @SmallTest - public void testFormatDailabeNumber() { - // Using the phoneNumberE164's country code - assertEquals("(650) 291-0000", - PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN")); - // Using the default country code for a phone number containing the IDD - assertEquals("011 86 10 8888 0000", - PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "US")); - assertEquals("00 86 10 8888 0000", - PhoneNumberUtils.formatNumber("00861088880000", "+861088880000", "GB")); - assertEquals("+86 10 8888 0000", - PhoneNumberUtils.formatNumber("+861088880000", "+861088880000", "GB")); - // Wrong default country, so no formatting is done - assertEquals("011861088880000", - PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "GB")); - // The phoneNumberE164 is null - assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US")); - // The given number has a country code. - assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN")); - // The given number was formatted. - assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US")); - // A valid Polish number should be formatted. - assertEquals("506 128 687", PhoneNumberUtils.formatNumber("506128687", null, "PL")); - // An invalid Polish number should be left as it is. Note Poland doesn't use '0' as a - // national prefix; therefore, the leading '0' makes the number invalid. - assertEquals("0506128687", PhoneNumberUtils.formatNumber("0506128687", null, "PL")); - // Wrong default country, so no formatting is done - assertEquals("011861088880000", - PhoneNumberUtils.formatNumber("011861088880000", "", "GB")); - } - - @SmallTest - public void testIsEmergencyNumber() { - // There are two parallel sets of tests here: one for the - // regular isEmergencyNumber() method, and the other for - // isPotentialEmergencyNumber(). - // - // (The difference is that isEmergencyNumber() will return true - // only if the specified number exactly matches an actual - // emergency number, but isPotentialEmergencyNumber() will - // return true if the specified number simply starts with the - // same digits as any actual emergency number.) - - // Tests for isEmergencyNumber(): - assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US")); - assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US")); - // The next two numbers are not valid phone numbers in the US, - // so do not count as emergency numbers (but they *are* "potential" - // emergency numbers; see below.) - assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US")); - assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US")); - // A valid mobile phone number from Singapore shouldn't be classified as an emergency number - // in Singapore, as 911 is not an emergency number there. - assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG")); - // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number - // in Brazil, as 112 is not an emergency number there. - assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR")); - // A valid local phone number from Brazil shouldn't be classified as an emergency number in - // Brazil. - assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR")); - - // Tests for isPotentialEmergencyNumber(): - // These first two are obviously emergency numbers: - assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US")); - assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US")); - // The next two numbers are not valid phone numbers in the US, but can be used to trick the - // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of - // addressing that, they are also classified as "potential" emergency numbers in the US. - assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US")); - assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US")); - - // A valid mobile phone number from Singapore shouldn't be classified as an emergency number - // in Singapore, as 911 is not an emergency number there. - // This test fails on devices that have ecclist property preloaded with 911. - // assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG")); - - // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number - // in Brazil, as 112 is not an emergency number there. - assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR")); - // A valid local phone number from Brazil shouldn't be classified as an emergency number in - // Brazil. - assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR")); - } - - @SmallTest - public void testStripSeparators() { - // Smoke tests which should never fail. - assertEquals("1234567890", PhoneNumberUtils.stripSeparators("1234567890")); - assertEquals("911", PhoneNumberUtils.stripSeparators("911")); - assertEquals("112", PhoneNumberUtils.stripSeparators("112")); - - // Separators should be removed, while '+' or any other digits should not. - assertEquals("+16502910000", PhoneNumberUtils.stripSeparators("+1 (650) 291-0000")); - - // WAIT, PAUSE should *not* be stripped - assertEquals("+16502910000,300;", - PhoneNumberUtils.stripSeparators("+1 (650) 291-0000, 300;")); - } - - @SmallTest - public void testConvertAndStrip() { - // Smoke tests which should never fail. - assertEquals("1234567890", PhoneNumberUtils.convertAndStrip("1234567890")); - assertEquals("911", PhoneNumberUtils.convertAndStrip("911")); - assertEquals("112", PhoneNumberUtils.convertAndStrip("112")); - - // It should convert keypad characters into digits, and strip separators - assertEquals("22233344455566677778889999", - PhoneNumberUtils.convertAndStrip("ABC DEF GHI JKL MNO PQR STUV WXYZ")); - - // Test real cases. - assertEquals("18004664411", PhoneNumberUtils.convertAndStrip("1-800-GOOG-411")); - assertEquals("8002223334", PhoneNumberUtils.convertAndStrip("(800) ABC-DEFG")); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java deleted file mode 100644 index a6a0fce398b9..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.internal.telephony; - -import android.telephony.PhoneNumberFormattingTextWatcher; -import android.test.AndroidTestCase; -import android.text.Editable; -import android.text.Selection; -import android.text.SpannableStringBuilder; -import android.text.TextWatcher; - -public class PhoneNumberWatcherTest extends AndroidTestCase { - public void testAppendChars() { - final String multiChars = "65012345"; - final String formatted1 = "(650) 123-45"; - TextWatcher textWatcher = getTextWatcher(); - SpannableStringBuilder number = new SpannableStringBuilder(); - // Append more than one chars - textWatcher.beforeTextChanged(number, 0, 0, multiChars.length()); - number.append(multiChars); - Selection.setSelection(number, number.length()); - textWatcher.onTextChanged(number, 0, 0, number.length()); - textWatcher.afterTextChanged(number); - assertEquals(formatted1, number.toString()); - assertEquals(formatted1.length(), Selection.getSelectionEnd(number)); - // Append one chars - final char appendChar = '6'; - final String formatted2 = "(650) 123-456"; - int len = number.length(); - textWatcher.beforeTextChanged(number, number.length(), 0, 1); - number.append(appendChar); - Selection.setSelection(number, number.length()); - textWatcher.onTextChanged(number, len, 0, 1); - textWatcher.afterTextChanged(number); - assertEquals(formatted2, number.toString()); - assertEquals(formatted2.length(), Selection.getSelectionEnd(number)); - } - - public void testRemoveLastChars() { - final String init = "65012345678"; - final String result1 = "(650) 123-4567"; - TextWatcher textWatcher = getTextWatcher(); - // Remove the last char. - SpannableStringBuilder number = new SpannableStringBuilder(init); - int len = number.length(); - textWatcher.beforeTextChanged(number, len - 1, 1, 0); - number.delete(len - 1, len); - Selection.setSelection(number, number.length()); - textWatcher.onTextChanged(number, number.length() - 1, 1, 0); - textWatcher.afterTextChanged(number); - assertEquals(result1, number.toString()); - assertEquals(result1.length(), Selection.getSelectionEnd(number)); - // Remove last 5 chars - final String result2 = "650-123"; - textWatcher.beforeTextChanged(number, number.length() - 4, 4, 0); - number.delete(number.length() - 5, number.length()); - Selection.setSelection(number, number.length()); - textWatcher.onTextChanged(number, number.length(), 4, 0); - textWatcher.afterTextChanged(number); - assertEquals(result2, number.toString()); - assertEquals(result2.length(), Selection.getSelectionEnd(number)); - } - - public void testInsertChars() { - final String init = "650-23"; - final String expected1 = "650-123"; - TextWatcher textWatcher = getTextWatcher(); - - // Insert one char - SpannableStringBuilder number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 3, 0, 1); - number.insert(3, "1"); // 6501-23 - Selection.setSelection(number, 4); // make the cursor at right of 1 - textWatcher.onTextChanged(number, 3, 0, 1); - textWatcher.afterTextChanged(number); - assertEquals(expected1, number.toString()); - // the cursor should still at the right of '1' - assertEquals(5, Selection.getSelectionEnd(number)); - - // Insert multiple chars - final String expected2 = "(650) 145-6723"; - textWatcher.beforeTextChanged(number, 5, 0, 4); - number.insert(5, "4567"); // change to 650-1456723 - Selection.setSelection(number, 9); // the cursor is at the right of '7'. - textWatcher.onTextChanged(number, 7, 0, 4); - textWatcher.afterTextChanged(number); - assertEquals(expected2, number.toString()); - // the cursor should be still at the right of '7' - assertEquals(12, Selection.getSelectionEnd(number)); - } - - public void testStopFormatting() { - final String init = "(650) 123"; - final String expected1 = "(650) 123 4"; - TextWatcher textWatcher = getTextWatcher(); - - // Append space - SpannableStringBuilder number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 9, 0, 2); - number.insert(9, " 4"); // (6501) 23 4 - Selection.setSelection(number, number.length()); // make the cursor at right of 4 - textWatcher.onTextChanged(number, 9, 0, 2); - textWatcher.afterTextChanged(number); - assertEquals(expected1, number.toString()); - // the cursor should still at the right of '1' - assertEquals(expected1.length(), Selection.getSelectionEnd(number)); - - // Delete a ')' - final String expected2 ="(650 123"; - textWatcher = getTextWatcher(); - number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 4, 1, 0); - number.delete(4, 5); // (6501 23 4 - Selection.setSelection(number, 5); // make the cursor at right of 1 - textWatcher.onTextChanged(number, 4, 1, 0); - textWatcher.afterTextChanged(number); - assertEquals(expected2, number.toString()); - // the cursor should still at the right of '1' - assertEquals(5, Selection.getSelectionEnd(number)); - - // Insert a hyphen - final String expected3 ="(650) 12-3"; - textWatcher = getTextWatcher(); - number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 8, 0, 1); - number.insert(8, "-"); // (650) 12-3 - Selection.setSelection(number, 9); // make the cursor at right of - - textWatcher.onTextChanged(number, 8, 0, 1); - textWatcher.afterTextChanged(number); - assertEquals(expected3, number.toString()); - // the cursor should still at the right of '-' - assertEquals(9, Selection.getSelectionEnd(number)); - } - - public void testRestartFormatting() { - final String init = "(650) 123"; - final String expected1 = "(650) 123 4"; - TextWatcher textWatcher = getTextWatcher(); - - // Append space - SpannableStringBuilder number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 9, 0, 2); - number.insert(9, " 4"); // (650) 123 4 - Selection.setSelection(number, number.length()); // make the cursor at right of 4 - textWatcher.onTextChanged(number, 9, 0, 2); - textWatcher.afterTextChanged(number); - assertEquals(expected1, number.toString()); - // the cursor should still at the right of '4' - assertEquals(expected1.length(), Selection.getSelectionEnd(number)); - - // Clear the current string, and start formatting again. - int len = number.length(); - textWatcher.beforeTextChanged(number, 0, len, 0); - number.delete(0, len); - textWatcher.onTextChanged(number, 0, len, 0); - textWatcher.afterTextChanged(number); - - final String expected2 = "650-1234"; - number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 9, 0, 1); - number.insert(9, "4"); // (650) 1234 - Selection.setSelection(number, number.length()); // make the cursor at right of 4 - textWatcher.onTextChanged(number, 9, 0, 1); - textWatcher.afterTextChanged(number); - assertEquals(expected2, number.toString()); - // the cursor should still at the right of '4' - assertEquals(expected2.length(), Selection.getSelectionEnd(number)); - } - - public void testTextChangedByOtherTextWatcher() { - final TextWatcher cleanupTextWatcher = new TextWatcher() { - @Override - public void afterTextChanged(Editable s) { - s.clear(); - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - } - }; - final String init = "(650) 123"; - final String expected1 = ""; - TextWatcher textWatcher = getTextWatcher(); - - SpannableStringBuilder number = new SpannableStringBuilder(init); - textWatcher.beforeTextChanged(number, 5, 0, 1); - number.insert(5, "4"); // (6504) 123 - Selection.setSelection(number, 5); // make the cursor at right of 4 - textWatcher.onTextChanged(number, 5, 0, 1); - number.setSpan(cleanupTextWatcher, 0, number.length(), 0); - textWatcher.afterTextChanged(number); - assertEquals(expected1, number.toString()); - } - - /** - * Test the case where some other component is auto-completing what the user is typing - */ - public void testAutoCompleteWithFormattedNumber() { - String init = "650-1"; - String expected = "+1-650-123-4567"; // Different formatting than ours - testReplacement(init, expected, expected); - } - - /** - * Test the case where some other component is auto-completing what the user is typing - */ - public void testAutoCompleteWithFormattedNameAndNumber() { - String init = "650-1"; - String expected = "Test User <650-123-4567>"; - testReplacement(init, expected, expected); - } - - /** - * Test the case where some other component is auto-completing what the user is typing - */ - public void testAutoCompleteWithNumericNameAndNumber() { - String init = "650"; - String expected = "2nd Test User <650-123-4567>"; - testReplacement(init, expected, expected); - } - - /** - * Test the case where some other component is auto-completing what the user is typing - */ - public void testAutoCompleteWithUnformattedNumber() { - String init = "650-1"; - String expected = "6501234567"; - testReplacement(init, expected, expected); - } - - /** - * Test the case where some other component is auto-completing what the user is typing, where - * the deleted text doesn't have any formatting and neither does the replacement text: in this - * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher. - */ - public void testAutoCompleteUnformattedWithUnformattedNumber() { - String init = "650"; - String replacement = "6501234567"; - String expected = "(650) 123-4567"; - testReplacement(init, replacement, expected); - - String init2 = "650"; - String replacement2 = "16501234567"; - String expected2 = "1 650-123-4567"; - testReplacement(init2, replacement2, expected2); - } - - /** - * Helper method for testing replacing the entire string with another string - * @param init The initial string - * @param expected - */ - private void testReplacement(String init, String replacement, String expected) { - TextWatcher textWatcher = getTextWatcher(); - - SpannableStringBuilder number = new SpannableStringBuilder(init); - - // Replace entire text with the given values - textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length()); - number.replace(0, init.length(), replacement, 0, replacement.length()); - Selection.setSelection(number, replacement.length()); // move the cursor to the end - textWatcher.onTextChanged(number, 0, init.length(), replacement.length()); - textWatcher.afterTextChanged(number); - - assertEquals(expected, number.toString()); - // the cursor should be still at the end - assertEquals(expected.length(), Selection.getSelectionEnd(number)); - } - - private TextWatcher getTextWatcher() { - return new PhoneNumberFormattingTextWatcher("US"); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java deleted file mode 100644 index 8a66614af0bd..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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; - -import android.test.suitebuilder.annotation.MediumTest; -import com.android.internal.telephony.TestPhoneNotifier; -import com.android.internal.telephony.gsm.SmsMessage; -import com.android.internal.telephony.test.SimulatedCommands; -import com.android.internal.telephony.test.SimulatedRadioControl; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.Suppress; - -import java.util.Iterator; - -/** - * {@hide} - */ -public class SMSDispatcherTest extends AndroidTestCase { - @MediumTest - public void testCMT1() throws Exception { - SmsMessage sms; - SmsHeader header; - - String[] lines = new String[2]; - - lines[0] = "+CMT: ,158"; - lines[1] = "07914140279510F6440A8111110301003BF56080426101748A8C0B05040B" - + "8423F000035502010106276170706C69636174696F6E2F766E642E776170" - + "2E6D6D732D6D65737361676500AF848D0185B4848C8298524F347839776F" - + "7547514D4141424C3641414141536741415A4B554141414141008D908918" - + "802B31363530323438363137392F545950453D504C4D4E008A808E028000" - + "88058103093A8083687474703A2F2F36"; - - sms = SmsMessage.newFromCMT(lines); - header = sms.getUserDataHeader(); - assertNotNull(header); - assertNotNull(sms.getUserData()); - assertNotNull(header.concatRef); - assertEquals(header.concatRef.refNumber, 85); - assertEquals(header.concatRef.msgCount, 2); - assertEquals(header.concatRef.seqNumber, 1); - assertEquals(header.concatRef.isEightBits, true); - assertNotNull(header.portAddrs); - assertEquals(header.portAddrs.destPort, 2948); - assertEquals(header.portAddrs.origPort, 9200); - assertEquals(header.portAddrs.areEightBits, false); - } - - @MediumTest - public void testCMT2() throws Exception { - SmsMessage sms; - SmsHeader header; - - String[] lines = new String[2]; - - lines[0] = "+CMT: ,77"; - lines[1] = "07914140279510F6440A8111110301003BF56080426101848A3B0B05040B8423F" - + "00003550202362E3130322E3137312E3135302F524F347839776F7547514D4141" - + "424C3641414141536741415A4B55414141414100"; - - sms = SmsMessage.newFromCMT(lines); - header = sms.getUserDataHeader(); - assertNotNull(header); - assertNotNull(sms.getUserData()); - assertNotNull(header.concatRef); - assertEquals(header.concatRef.refNumber, 85); - assertEquals(header.concatRef.msgCount, 2); - assertEquals(header.concatRef.seqNumber, 2); - assertEquals(header.concatRef.isEightBits, true); - assertNotNull(header.portAddrs); - assertEquals(header.portAddrs.destPort, 2948); - assertEquals(header.portAddrs.origPort, 9200); - assertEquals(header.portAddrs.areEightBits, false); - } - - @MediumTest - public void testEfRecord() throws Exception { - SmsMessage sms; - - String s = "03029111000c9194981492631000f269206190022000a053e4534a05358bd3" - + "69f05804259da0219418a40641536a110a0aea408080604028180e888462c1" - + "50341c0f484432a1542c174c46b3e1743c9f9068442a994ea8946ac56ab95e" - + "b0986c46abd96eb89c6ec7ebf97ec0a070482c1a8fc8a472c96c3a9fd0a874" - + "4aad5aafd8ac76cbed7abfe0b0784c2e9bcfe8b47acd6ebbdff0b87c4eafdb" - + "eff8bc7ecfeffbffffffffffffffffffffffffffff"; - byte[] data = IccUtils.hexStringToBytes(s); - - sms = SmsMessage.createFromEfRecord(1, data); - assertNotNull(sms.getMessageBody()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java deleted file mode 100644 index 609e76879033..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java +++ /dev/null @@ -1,106 +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; - -import android.os.ServiceManager; -import android.test.suitebuilder.annotation.Suppress; - -import java.util.List; - -import junit.framework.TestCase; - -@Suppress -public class SimPhoneBookTest extends TestCase { - - public void testBasic() throws Exception { - IIccPhoneBook simPhoneBook = - IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook")); - assertNotNull(simPhoneBook); - - int size[] = simPhoneBook.getAdnRecordsSize(IccConstants.EF_ADN); - assertNotNull(size); - assertEquals(3, size.length); - assertEquals(size[0] * size[2], size[1]); - assertTrue(size[2] >= 100); - - List adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - // do it twice cause the second time shall read from cache only - adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - assertNotNull(adnRecordList); - - // Test for phone book update - int adnIndex, listIndex = 0; - AdnRecord originalAdn = null; - // We need to maintain the state of the SIM before and after the test. - // Since this test doesn't mock the SIM we try to get a valid ADN record, - // for 3 tries and if this fails, we bail out. - for (adnIndex = 3 ; adnIndex >= 1; adnIndex--) { - listIndex = adnIndex - 1; // listIndex is zero based. - originalAdn = adnRecordList.get(listIndex); - assertNotNull("Original Adn is Null.", originalAdn); - assertNotNull("Original Adn alpha tag is null.", originalAdn.getAlphaTag()); - assertNotNull("Original Adn number is null.", originalAdn.getNumber()); - - if (originalAdn.getNumber().length() > 0 && - originalAdn.getAlphaTag().length() > 0) { - break; - } - } - if (adnIndex == 0) return; - - AdnRecord emptyAdn = new AdnRecord("", ""); - AdnRecord firstAdn = new AdnRecord("John", "4085550101"); - AdnRecord secondAdn = new AdnRecord("Andy", "6505550102"); - String pin2 = null; - - // udpate by index - boolean success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN, - firstAdn.getAlphaTag(), firstAdn.getNumber(), adnIndex, pin2); - adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - AdnRecord tmpAdn = adnRecordList.get(listIndex); - assertTrue(success); - assertTrue(firstAdn.isEqual(tmpAdn)); - - // replace by search - success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN, - firstAdn.getAlphaTag(), firstAdn.getNumber(), - secondAdn.getAlphaTag(), secondAdn.getNumber(), pin2); - adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - tmpAdn = adnRecordList.get(listIndex); - assertTrue(success); - assertFalse(firstAdn.isEqual(tmpAdn)); - assertTrue(secondAdn.isEqual(tmpAdn)); - - // erase be search - success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN, - secondAdn.getAlphaTag(), secondAdn.getNumber(), - emptyAdn.getAlphaTag(), emptyAdn.getNumber(), pin2); - adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - tmpAdn = adnRecordList.get(listIndex); - assertTrue(success); - assertTrue(tmpAdn.isEmpty()); - - // restore the orginial adn - success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN, - originalAdn.getAlphaTag(), originalAdn.getNumber(), adnIndex, - pin2); - adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN); - tmpAdn = adnRecordList.get(listIndex); - assertTrue(success); - assertTrue(originalAdn.isEqual(tmpAdn)); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java deleted file mode 100644 index 1609680c0697..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java +++ /dev/null @@ -1,60 +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; - -import android.os.ServiceManager; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; - -import java.util.List; - -import junit.framework.TestCase; - -public class SimSmsTest extends TestCase { - - @MediumTest - @Suppress // TODO: suppress this test for now since it doesn't work on the emulator - public void testBasic() throws Exception { - - ISms sms = ISms.Stub.asInterface(ServiceManager.getService("isms")); - assertNotNull(sms); - - List records = sms.getAllMessagesFromIccEf(); - assertNotNull(records); - assertTrue(records.size() >= 0); - - int firstNullIndex = -1; - int firstValidIndex = -1; - byte[] pdu = null; - for (int i = 0; i < records.size(); i++) { - SmsRawData data = records.get(i); - if (data != null && firstValidIndex == -1) { - firstValidIndex = i; - pdu = data.getBytes(); - } - if (data == null && firstNullIndex == -1) { - firstNullIndex = i; - } - if (firstNullIndex != -1 && firstValidIndex != -1) { - break; - } - } - if (firstNullIndex == -1 || firstValidIndex == -1) - return; - assertNotNull(pdu); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java deleted file mode 100644 index ef62d8538d2d..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java +++ /dev/null @@ -1,91 +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; - -import com.android.internal.telephony.gsm.SimTlv; -import com.android.internal.telephony.IccUtils; -import junit.framework.TestCase; -import android.test.suitebuilder.annotation.SmallTest; - - -public class SimUtilsTest extends TestCase { - - @SmallTest - public void testBasic() throws Exception { - byte[] data, data2; - - /* - * bcdToString() - */ - - // An EF[ICCID] record - data = IccUtils.hexStringToBytes("981062400510444868f2"); - assertEquals("8901260450014484862", IccUtils.bcdToString(data, 0, data.length)); - - // skip the first and last bytes - assertEquals("0126045001448486", IccUtils.bcdToString(data, 1, data.length - 2)); - - // Stops on invalid BCD value - data = IccUtils.hexStringToBytes("98E062400510444868f2"); - assertEquals("890", IccUtils.bcdToString(data, 0, data.length)); - - // skip the high nibble 'F' since some PLMNs have it - data = IccUtils.hexStringToBytes("98F062400510444868f2"); - assertEquals("890260450014484862", IccUtils.bcdToString(data, 0, data.length)); - - /* - * gsmBcdByteToInt() - */ - - assertEquals(98, IccUtils.gsmBcdByteToInt((byte) 0x89)); - - // Out of range is treated as 0 - assertEquals(8, IccUtils.gsmBcdByteToInt((byte) 0x8c)); - - /* - * cdmaBcdByteToInt() - */ - - assertEquals(89, IccUtils.cdmaBcdByteToInt((byte) 0x89)); - - // Out of range is treated as 0 - assertEquals(80, IccUtils.cdmaBcdByteToInt((byte) 0x8c)); - - /* - * adnStringFieldToString() - */ - - - data = IccUtils.hexStringToBytes("00566f696365204d61696c07918150367742f3ffffffffffff"); - // Again, skip prepended 0 - // (this is an EF[ADN] record) - assertEquals("Voice Mail", IccUtils.adnStringFieldToString(data, 1, data.length - 15)); - - data = IccUtils.hexStringToBytes("809673539A5764002F004DFFFFFFFFFF"); - // (this is from an EF[ADN] record) - assertEquals("\u9673\u539A\u5764/M", IccUtils.adnStringFieldToString(data, 0, data.length)); - - data = IccUtils.hexStringToBytes("810A01566fec6365204de0696cFFFFFF"); - // (this is made up to test since I don't have a real one) - assertEquals("Vo\u00ECce M\u00E0il", IccUtils.adnStringFieldToString(data, 0, data.length)); - - data = IccUtils.hexStringToBytes("820505302D82d32d31"); - // Example from 3GPP TS 11.11 V18.1.3.0 annex B - assertEquals("-\u0532\u0583-1", IccUtils.adnStringFieldToString(data, 0, data.length)); - } - -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java deleted file mode 100644 index 170bd9b9216d..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.telephony.SmsMessage; -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; - -import java.util.Random; - -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; - -/** - * Test cases to verify selection of the optimal 7 bit encoding tables - * (for all combinations of enabled national language tables) for messages - * containing Turkish, Spanish, Portuguese, Greek, and other symbols - * present in the GSM default and national language tables defined in - * 3GPP TS 23.038. Also verifies correct SMS encoding for CDMA, which only - * supports the GSM 7 bit default alphabet, ASCII 8 bit, and UCS-2. - * Tests both encoding variations: unsupported characters mapped to space, - * and unsupported characters force entire message to UCS-2. - */ -public class SmsMessageBodyTest extends AndroidTestCase { - private static final String TAG = "SmsMessageBodyTest"; - - // ASCII chars in the GSM 7 bit default alphabet - private static final String sAsciiChars = "@$_ !\"#%&'()*+,-./0123456789" + - ":;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\r"; - - // Unicode chars in the GSM 7 bit default alphabet and both locking shift tables - private static final String sGsmDefaultChars = "\u00a3\u00a5\u00e9\u00c7\u0394\u00c9" + - "\u00dc\u00a7\u00fc\u00e0"; - - // Unicode chars in the GSM 7 bit default table and Turkish locking shift tables - private static final String sGsmDefaultAndTurkishTables = "\u00f9\u00f2\u00c5\u00e5\u00df" + - "\u00a4\u00c4\u00d6\u00d1\u00e4\u00f6\u00f1"; - - // Unicode chars in the GSM 7 bit default table but not the locking shift tables - private static final String sGsmDefaultTableOnly = "\u00e8\u00ec\u00d8\u00f8\u00c6\u00e6" + - "\u00a1\u00bf"; - - // ASCII chars in the GSM default extension table - private static final String sGsmExtendedAsciiChars = "{}[]\f"; - - // chars in GSM default extension table and Portuguese locking shift table - private static final String sGsmExtendedPortugueseLocking = "^\\|~"; - - // Euro currency symbol - private static final String sGsmExtendedEuroSymbol = "\u20ac"; - - // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc. - private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" + - "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" + - "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" + - "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" + - "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" + - "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" + - "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" + - "\u00a2\u00a9\u00ae\u2122"; - - // chars in Turkish single shift and locking shift tables - private static final String sTurkishChars = "\u0131\u011e\u011f\u015e\u015f\u0130"; - - // chars in Spanish single shift table and Portuguese single and locking shift tables - private static final String sPortugueseAndSpanishChars = "\u00c1\u00e1\u00cd\u00ed" - + "\u00d3\u00f3\u00da\u00fa"; - - // chars in all national language tables but not in the standard GSM alphabets - private static final String sNationalLanguageTablesOnly = "\u00e7"; - - // chars in Portuguese single shift and locking shift tables - private static final String sPortugueseChars = "\u00ea\u00d4\u00f4\u00c0\u00c2\u00e2" - + "\u00ca\u00c3\u00d5\u00e3\u00f5"; - - // chars in Portuguese locking shift table only - private static final String sPortugueseLockingShiftChars = "\u00aa\u221e\u00ba`"; - - // Greek letters in GSM alphabet missing from Portuguese locking and single shift tables - private static final String sGreekLettersNotInPortugueseTables = "\u039b\u039e"; - - // Greek letters in GSM alphabet and Portuguese single shift (but not locking shift) table - private static final String sGreekLettersInPortugueseShiftTable = - "\u03a6\u0393\u03a9\u03a0\u03a8\u03a3\u0398"; - - // List of classes of characters in SMS tables - private static final String[] sCharacterClasses = { - sGsmExtendedAsciiChars, - sGsmExtendedPortugueseLocking, - sGsmDefaultChars, - sGsmDefaultAndTurkishTables, - sGsmDefaultTableOnly, - sGsmExtendedEuroSymbol, - sUnicodeChars, - sTurkishChars, - sPortugueseChars, - sPortugueseLockingShiftChars, - sPortugueseAndSpanishChars, - sGreekLettersNotInPortugueseTables, - sGreekLettersInPortugueseShiftTable, - sNationalLanguageTablesOnly, - sAsciiChars - }; - - private static final int sNumCharacterClasses = sCharacterClasses.length; - - // For each character class, whether it is present in a particular char table. - // First three entries are locking shift tables, followed by four single shift tables - private static final boolean[][] sCharClassPresenceInTables = { - // ASCII chars in all GSM extension tables - {false, false, false, true, true, true, true}, - // ASCII chars in all GSM extension tables and Portuguese locking shift table - {false, false, true, true, true, true, true}, - // non-ASCII chars in GSM default alphabet and all locking tables - {true, true, true, false, false, false, false}, - // non-ASCII chars in GSM default alphabet and Turkish locking shift table - {true, true, false, false, false, false, false}, - // non-ASCII chars in GSM default alphabet table only - {true, false, false, false, false, false, false}, - // Euro symbol is present in several tables - {false, true, true, true, true, true, true}, - // Unicode characters not present in any 7 bit tables - {false, false, false, false, false, false, false}, - // Characters specific to Turkish language - {false, true, false, false, true, false, false}, - // Characters in Portuguese single shift and locking shift tables - {false, false, true, false, false, false, true}, - // Characters in Portuguese locking shift table only - {false, false, true, false, false, false, false}, - // Chars in Spanish single shift and Portuguese single and locking shift tables - {false, false, true, false, false, true, true}, - // Greek letters in GSM default alphabet missing from Portuguese tables - {true, true, false, false, false, false, false}, - // Greek letters in GSM alphabet and Portuguese single shift table - {true, true, false, false, false, false, true}, - // Chars in all national language tables but not the standard GSM tables - {false, true, true, false, true, true, true}, - // ASCII chars in GSM default alphabet - {true, true, true, false, false, false, false} - }; - - private static final int sTestLengthCount = 12; - - private static final int[] sSeptetTestLengths = - { 0, 1, 2, 80, 159, 160, 161, 240, 305, 306, 307, 320}; - - private static final int[] sUnicodeTestLengths = - { 0, 1, 2, 35, 69, 70, 71, 100, 133, 134, 135, 160}; - - private static final int[] sTestMsgCounts = - { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3}; - - private static final int[] sSeptetUnitsRemaining = - {160, 159, 158, 80, 1, 0, 145, 66, 1, 0, 152, 139}; - - private static final int[] sUnicodeUnitsRemaining = - { 70, 69, 68, 35, 1, 0, 63, 34, 1, 0, 66, 41}; - - // Combinations of enabled GSM national language single shift tables - private static final int[][] sEnabledSingleShiftTables = { - {}, // GSM default alphabet only - {1}, // Turkish (single shift only) - {1}, // Turkish (single and locking shift) - {2}, // Spanish - {3}, // Portuguese (single shift only) - {3}, // Portuguese (single and locking shift) - {1, 2}, // Turkish + Spanish (single shift only) - {1, 2}, // Turkish + Spanish (single and locking shift) - {1, 3}, // Turkish + Portuguese (single shift only) - {1, 3}, // Turkish + Portuguese (single and locking shift) - {2, 3}, // Spanish + Portuguese (single shift only) - {2, 3}, // Spanish + Portuguese (single and locking shift) - {1, 2, 3}, // Turkish, Spanish, Portuguese (single shift only) - {1, 2, 3}, // Turkish, Spanish, Portuguese (single and locking shift) - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables - }; - - // Combinations of enabled GSM national language locking shift tables - private static final int[][] sEnabledLockingShiftTables = { - {}, // GSM default alphabet only - {}, // Turkish (single shift only) - {1}, // Turkish (single and locking shift) - {}, // Spanish (no locking shift table) - {}, // Portuguese (single shift only) - {3}, // Portuguese (single and locking shift) - {}, // Turkish + Spanish (single shift only) - {1}, // Turkish + Spanish (single and locking shift) - {}, // Turkish + Portuguese (single shift only) - {1, 3}, // Turkish + Portuguese (single and locking shift) - {}, // Spanish + Portuguese (single shift only) - {3}, // Spanish + Portuguese (single and locking shift) - {}, // Turkish, Spanish, Portuguese (single shift only) - {1, 3}, // Turkish, Spanish, Portuguese (single and locking shift) - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables - }; - - // LanguagePair counter indexes to check for each entry above - private static final int[][] sLanguagePairIndexesByEnabledIndex = { - {0}, // default tables only - {0, 1}, // Turkish (single shift only) - {0, 1, 4, 5}, // Turkish (single and locking shift) - {0, 2}, // Spanish - {0, 3}, // Portuguese (single shift only) - {0, 3, 8, 11}, // Portuguese (single and locking shift) - {0, 1, 2}, // Turkish + Spanish (single shift only) - {0, 1, 2, 4, 5, 6}, // Turkish + Spanish (single and locking shift) - {0, 1, 3}, // Turkish + Portuguese (single shift only) - {0, 1, 3, 4, 5, 7, 8, 9, 11}, // Turkish + Portuguese (single and locking shift) - {0, 2, 3}, // Spanish + Portuguese (single shift only) - {0, 2, 3, 8, 10, 11}, // Spanish + Portuguese (single and locking shift) - {0, 1, 2, 3}, // all languages (single shift only) - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, // all languages (single and locking shift) - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} // all languages (no Indic chars in test) - }; - - /** - * User data header requires one octet for length. Count as one septet, because - * all combinations of header elements below will have at least one free bit - * when padding to the nearest septet boundary. - */ - private static final int UDH_SEPTET_COST_LENGTH = 1; - - /** - * Using a non-default language locking shift table OR single shift table - * requires a user data header of 3 octets, or 4 septets, plus UDH length. - */ - private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; - - /** - * Using a non-default language locking shift table AND single shift table - * requires a user data header of 6 octets, or 7 septets, plus UDH length. - */ - private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; - - /** - * Multi-part messages require a user data header of 5 octets, or 6 septets, - * plus UDH length. - */ - private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; - - @SmallTest - public void testCalcLengthAscii() throws Exception { - StringBuilder sb = new StringBuilder(320); - int[] values = {0, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0}; - int startPos = 0; - int asciiCharsLen = sAsciiChars.length(); - - for (int i = 0; i < sTestLengthCount; i++) { - int len = sSeptetTestLengths[i]; - assertTrue(sb.length() <= len); - - while (sb.length() < len) { - int addCount = len - sb.length(); - int endPos = (asciiCharsLen - startPos > addCount) ? - (startPos + addCount) : asciiCharsLen; - sb.append(sAsciiChars, startPos, endPos); - startPos = (endPos == asciiCharsLen) ? 0 : endPos; - } - assertEquals(len, sb.length()); - - String testStr = sb.toString(); - values[0] = sTestMsgCounts[i]; - values[1] = len; - values[2] = sSeptetUnitsRemaining[i]; - - callGsmLengthMethods(testStr, false, values); - callGsmLengthMethods(testStr, true, values); - callCdmaLengthMethods(testStr, false, values); - callCdmaLengthMethods(testStr, true, values); - } - } - - @SmallTest - public void testCalcLengthUnicode() throws Exception { - StringBuilder sb = new StringBuilder(160); - int[] values = {0, 0, 0, SmsMessage.ENCODING_16BIT, 0, 0}; - int[] values7bit = {1, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0}; - int startPos = 0; - int unicodeCharsLen = sUnicodeChars.length(); - - // start with length 1: empty string uses ENCODING_7BIT - for (int i = 1; i < sTestLengthCount; i++) { - int len = sUnicodeTestLengths[i]; - assertTrue(sb.length() <= len); - - while (sb.length() < len) { - int addCount = len - sb.length(); - int endPos = (unicodeCharsLen - startPos > addCount) ? - (startPos + addCount) : unicodeCharsLen; - sb.append(sUnicodeChars, startPos, endPos); - startPos = (endPos == unicodeCharsLen) ? 0 : endPos; - } - assertEquals(len, sb.length()); - - String testStr = sb.toString(); - values[0] = sTestMsgCounts[i]; - values[1] = len; - values[2] = sUnicodeUnitsRemaining[i]; - values7bit[1] = len; - values7bit[2] = MAX_USER_DATA_SEPTETS - len; - - callGsmLengthMethods(testStr, false, values); - callCdmaLengthMethods(testStr, false, values); - callGsmLengthMethods(testStr, true, values7bit); - callCdmaLengthMethods(testStr, true, values7bit); - } - } - - private static class LanguagePair { - // index is 2 for Portuguese locking shift because there is no Spanish locking shift table - private final int langTableIndex; - private final int langShiftTableIndex; - int length; - int missingChars7bit; - - LanguagePair(int langTable, int langShiftTable) { - langTableIndex = langTable; - langShiftTableIndex = langShiftTable; - } - - void clear() { - length = 0; - missingChars7bit = 0; - } - - void addChar(boolean[] charClassTableRow) { - if (charClassTableRow[langTableIndex]) { - length++; - } else if (charClassTableRow[3 + langShiftTableIndex]) { - length += 2; - } else { - length++; // use ' ' for unmapped char in 7 bit only mode - missingChars7bit++; - } - } - } - - private static class CounterHelper { - LanguagePair[] mCounters; - int[] mStatsCounters; - int mUnicodeCounter; - - CounterHelper() { - mCounters = new LanguagePair[12]; - mStatsCounters = new int[12]; - for (int i = 0; i < 12; i++) { - mCounters[i] = new LanguagePair(i/4, i%4); - } - } - - void clear() { - // Note: don't clear stats counters - for (int i = 0; i < 12; i++) { - mCounters[i].clear(); - } - } - - void addChar(int charClass) { - boolean[] charClassTableRow = sCharClassPresenceInTables[charClass]; - for (int i = 0; i < 12; i++) { - mCounters[i].addChar(charClassTableRow); - } - } - - void fillData(int enabledLangsIndex, boolean use7bitOnly, int[] values, int length) { - int[] languagePairs = sLanguagePairIndexesByEnabledIndex[enabledLangsIndex]; - int minNumSeptets = Integer.MAX_VALUE; - int minNumSeptetsWithHeader = Integer.MAX_VALUE; - int minNumMissingChars = Integer.MAX_VALUE; - int langIndex = -1; - int langShiftIndex = -1; - for (int i : languagePairs) { - LanguagePair pair = mCounters[i]; - int udhLength = 0; - if (i != 0) { - udhLength = UDH_SEPTET_COST_LENGTH; - if (i < 4 || i % 4 == 0) { - udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE; - } else { - udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES; - } - } - int numSeptetsWithHeader; - if (pair.length > (MAX_USER_DATA_SEPTETS - udhLength)) { - if (udhLength == 0) { - udhLength = UDH_SEPTET_COST_LENGTH; - } - udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE; - int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength; - int msgCount = (pair.length + septetsPerPart - 1) / septetsPerPart; - numSeptetsWithHeader = udhLength * msgCount + pair.length; - } else { - numSeptetsWithHeader = udhLength + pair.length; - } - - if (use7bitOnly) { - if (pair.missingChars7bit < minNumMissingChars || (pair.missingChars7bit == - minNumMissingChars && numSeptetsWithHeader < minNumSeptetsWithHeader)) { - minNumSeptets = pair.length; - minNumSeptetsWithHeader = numSeptetsWithHeader; - minNumMissingChars = pair.missingChars7bit; - langIndex = pair.langTableIndex; - langShiftIndex = pair.langShiftTableIndex; - } - } else { - if (pair.missingChars7bit == 0 && numSeptetsWithHeader < minNumSeptetsWithHeader) { - minNumSeptets = pair.length; - minNumSeptetsWithHeader = numSeptetsWithHeader; - langIndex = pair.langTableIndex; - langShiftIndex = pair.langShiftTableIndex; - } - } - } - if (langIndex == -1) { - // nothing matches, use values for Unicode - int byteCount = length * 2; - if (byteCount > MAX_USER_DATA_BYTES) { - values[0] = (byteCount + MAX_USER_DATA_BYTES_WITH_HEADER - 1) / - MAX_USER_DATA_BYTES_WITH_HEADER; - values[2] = ((values[0] * MAX_USER_DATA_BYTES_WITH_HEADER) - byteCount) / 2; - } else { - values[0] = 1; - values[2] = (MAX_USER_DATA_BYTES - byteCount) / 2; - } - values[1] = length; - values[3] = SmsMessage.ENCODING_16BIT; - values[4] = 0; - values[5] = 0; - mUnicodeCounter++; - } else { - int udhLength = 0; - if (langIndex != 0 || langShiftIndex != 0) { - udhLength = UDH_SEPTET_COST_LENGTH; - if (langIndex == 0 || langShiftIndex == 0) { - udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE; - } else { - udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES; - } - } - int msgCount; - if (minNumSeptets > (MAX_USER_DATA_SEPTETS - udhLength)) { - if (udhLength == 0) { - udhLength = UDH_SEPTET_COST_LENGTH; - } - udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE; - int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength; - msgCount = (minNumSeptets + septetsPerPart - 1) / septetsPerPart; - } else { - msgCount = 1; - } - values[0] = msgCount; - values[1] = minNumSeptets; - values[2] = (values[0] * (MAX_USER_DATA_SEPTETS - udhLength)) - minNumSeptets; - values[3] = SmsMessage.ENCODING_7BIT; - values[4] = (langIndex == 2 ? 3 : langIndex); // Portuguese is code 3, index 2 - values[5] = langShiftIndex; - assertEquals("minNumSeptetsWithHeader", minNumSeptetsWithHeader, - udhLength * msgCount + minNumSeptets); - mStatsCounters[langIndex * 4 + langShiftIndex]++; - } - } - - void printStats() { - Log.d(TAG, "Unicode selection count: " + mUnicodeCounter); - for (int i = 0; i < 12; i++) { - Log.d(TAG, "Language pair index " + i + " count: " + mStatsCounters[i]); - } - } - } - - @LargeTest - public void testCalcLengthMixed7bit() throws Exception { - StringBuilder sb = new StringBuilder(320); - CounterHelper ch = new CounterHelper(); - Random r = new Random(0x4321); // use the same seed for reproducibility - int[] expectedValues = new int[6]; - int[] origLockingShiftTables = GsmAlphabet.getEnabledLockingShiftTables(); - int[] origSingleShiftTables = GsmAlphabet.getEnabledSingleShiftTables(); - int enabledLanguagesTestCases = sEnabledSingleShiftTables.length; - long startTime = System.currentTimeMillis(); - - // Repeat for 10 test runs - for (int run = 0; run < 10; run++) { - sb.setLength(0); - ch.clear(); - int unicodeOnlyCount = 0; - - // Test incrementally from 1 to 320 character random messages - for (int i = 1; i < 320; i++) { - // 1% chance to add from each special character class, else add an ASCII char - int charClass = r.nextInt(100); - if (charClass >= sNumCharacterClasses) { - charClass = sNumCharacterClasses - 1; // last class is ASCII - } - int classLength = sCharacterClasses[charClass].length(); - char nextChar = sCharacterClasses[charClass].charAt(r.nextInt(classLength)); - sb.append(nextChar); - ch.addChar(charClass); - -// if (i % 20 == 0) { -// Log.d(TAG, "test string: " + sb); -// } - - // Test string against all combinations of enabled languages - boolean unicodeOnly = true; - for (int j = 0; j < enabledLanguagesTestCases; j++) { - GsmAlphabet.setEnabledSingleShiftTables(sEnabledSingleShiftTables[j]); - GsmAlphabet.setEnabledLockingShiftTables(sEnabledLockingShiftTables[j]); - ch.fillData(j, false, expectedValues, i); - if (expectedValues[3] == SmsMessage.ENCODING_7BIT) { - unicodeOnly = false; - } - callGsmLengthMethods(sb, false, expectedValues); - // test 7 bit only mode - ch.fillData(j, true, expectedValues, i); - callGsmLengthMethods(sb, true, expectedValues); - } - // after 10 iterations with a Unicode-only string, skip to next test string - // so we can spend more time testing strings that do encode into 7 bits. - if (unicodeOnly && ++unicodeOnlyCount == 10) { -// Log.d(TAG, "Unicode only: skipping to next test string"); - break; - } - } - } - ch.printStats(); - Log.d(TAG, "Completed in " + (System.currentTimeMillis() - startTime) + " ms"); - GsmAlphabet.setEnabledLockingShiftTables(origLockingShiftTables); - GsmAlphabet.setEnabledSingleShiftTables(origSingleShiftTables); - } - - private void callGsmLengthMethods(CharSequence msgBody, boolean use7bitOnly, - int[] expectedValues) - { - // deprecated GSM-specific method - int[] values = android.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], values[0]); - assertEquals("codeUnitCount", expectedValues[1], values[1]); - assertEquals("codeUnitsRemaining", expectedValues[2], values[2]); - assertEquals("codeUnitSize", expectedValues[3], values[3]); - - int activePhone = TelephonyManager.getDefault().getPhoneType(); - if (TelephonyManager.PHONE_TYPE_GSM == activePhone) { - values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], values[0]); - assertEquals("codeUnitCount", expectedValues[1], values[1]); - assertEquals("codeUnitsRemaining", expectedValues[2], values[2]); - assertEquals("codeUnitSize", expectedValues[3], values[3]); - } - - SmsMessageBase.TextEncodingDetails ted = - com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], ted.msgCount); - assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount); - assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining); - assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize); - assertEquals("languageTable", expectedValues[4], ted.languageTable); - assertEquals("languageShiftTable", expectedValues[5], ted.languageShiftTable); - } - - private void callCdmaLengthMethods(CharSequence msgBody, boolean use7bitOnly, - int[] expectedValues) - { - int activePhone = TelephonyManager.getDefault().getPhoneType(); - if (TelephonyManager.PHONE_TYPE_CDMA == activePhone) { - int[] values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], values[0]); - assertEquals("codeUnitCount", expectedValues[1], values[1]); - assertEquals("codeUnitsRemaining", expectedValues[2], values[2]); - assertEquals("codeUnitSize", expectedValues[3], values[3]); - } - - SmsMessageBase.TextEncodingDetails ted = - com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], ted.msgCount); - assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount); - assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining); - assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize); - - ted = com.android.internal.telephony.cdma.sms.BearerData.calcTextEncodingDetails(msgBody, use7bitOnly); - assertEquals("msgCount", expectedValues[0], ted.msgCount); - assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount); - assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining); - assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java deleted file mode 100644 index 3757017a8ca3..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import com.android.internal.telephony.RetryManager; -import junit.framework.TestCase; -import android.test.suitebuilder.annotation.SmallTest; - -public class TelephonyUtilsTest extends TestCase { - - /** - * After first creating the RetryManager - * isRetryNeeded should be false and the time 0 - */ - @SmallTest - public void testRetryManagerEmpty() throws Exception { - RetryManager rm = new RetryManager(); - - assertEquals(0, rm.getRetryCount()); - assertFalse(rm.isRetryForever()); - assertFalse(rm.isRetryNeeded()); - assertEquals(0, rm.getRetryCount()); - assertEquals(0, rm.getRetryTimer()); - - rm.increaseRetryCount(); - assertFalse(rm.isRetryForever()); - assertFalse(rm.isRetryNeeded()); - assertEquals(0, rm.getRetryCount()); - assertEquals(0, rm.getRetryTimer()); - - rm.setRetryCount(123); - assertFalse(rm.isRetryForever()); - assertFalse(rm.isRetryNeeded()); - assertEquals(0, rm.getRetryCount()); - assertEquals(0, rm.getRetryTimer()); - - rm.retryForeverUsingLastTimeout(); - assertTrue(rm.isRetryForever()); - assertTrue(rm.isRetryNeeded()); - assertEquals(0, rm.getRetryCount()); - assertEquals(0, rm.getRetryTimer()); - - rm.setRetryCount(2); - assertFalse(rm.isRetryForever()); - assertFalse(rm.isRetryNeeded()); - assertEquals(0, rm.getRetryCount()); - assertEquals(0, rm.getRetryTimer()); - } - - /** - * A simple test and that randomization is doing something. - */ - @SmallTest - public void testRetryManagerSimplest() throws Exception { - RetryManager rm = new RetryManager(); - - assertTrue(rm.configure(1, 500, 10)); - int loops = 10; - int count = 0; - for (int i = 0; i < loops; i++) { - assertTrue(rm.isRetryNeeded()); - int time = rm.getRetryTimer(); - assertTrue((time >= 500) && (time < 600)); - if (time == 500) { - count++; - } - } - assertFalse(count == loops); - rm.increaseRetryCount(); - assertFalse(rm.isRetryNeeded()); - rm.setRetryCount(0); - assertTrue(rm.isRetryNeeded()); - } - - /** - * Test multiple values using simple configuration. - */ - @SmallTest - public void testRetryManagerSimple() throws Exception { - RetryManager rm = new RetryManager(); - - assertTrue(rm.configure(3, 1000, 0)); - assertTrue(rm.isRetryNeeded()); - assertEquals(1000, rm.getRetryTimer()); - assertEquals(rm.getRetryTimer(), 1000); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - assertEquals(1000, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - assertEquals(1000, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertFalse(rm.isRetryNeeded()); - assertEquals(1000, rm.getRetryTimer()); - } - - /** - * Test string configuration, simplest - */ - @SmallTest - public void testRetryManageSimpleString() throws Exception { - RetryManager rm = new RetryManager(); - - assertTrue(rm.configure("101")); - assertTrue(rm.isRetryNeeded()); - assertEquals(101, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertFalse(rm.isRetryNeeded()); - } - - /** - * Test infinite retires - */ - @SmallTest - public void testRetryManageInfinite() throws Exception { - RetryManager rm = new RetryManager(); - - assertTrue(rm.configure("1000,2000,3000,max_retries=infinite")); - assertTrue(rm.isRetryNeeded()); - assertEquals(1000, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - assertEquals(2000, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - // All others are 3000 and isRetryNeeded is always true - for (int i=0; i < 100; i++) { - assertEquals(3000, rm.getRetryTimer()); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - } - } - - /** - * Test string configuration using all options and with quotes. - */ - @SmallTest - public void testRetryManageString() throws Exception { - RetryManager rm = new RetryManager(); - int time; - - assertTrue(rm.configure( - "\"max_retries=4, default_randomization=100,1000, 2000 :200 , 3000\"")); - assertTrue(rm.isRetryNeeded()); - time = rm.getRetryTimer(); - assertTrue((time >= 1000) && (time < 1100)); - - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - time = rm.getRetryTimer(); - assertTrue((time >= 2000) && (time < 2200)); - - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - time = rm.getRetryTimer(); - assertTrue((time >= 3000) && (time < 3100)); - - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - time = rm.getRetryTimer(); - assertTrue((time >= 3000) && (time < 3100)); - - rm.increaseRetryCount(); - assertFalse(rm.isRetryNeeded()); - } - - /** - * Test string configuration using all options. - */ - @SmallTest - public void testRetryManageForever() throws Exception { - RetryManager rm = new RetryManager(); - int time; - - assertTrue(rm.configure("1000, 2000, 3000")); - assertTrue(rm.isRetryNeeded()); - assertFalse(rm.isRetryForever()); - assertEquals(0, rm.getRetryCount()); - assertEquals(1000, rm.getRetryTimer()); - - rm.retryForeverUsingLastTimeout(); - rm.increaseRetryCount(); - rm.increaseRetryCount(); - rm.increaseRetryCount(); - assertTrue(rm.isRetryNeeded()); - assertTrue(rm.isRetryForever()); - assertEquals(3, rm.getRetryCount()); - assertEquals(3000, rm.getRetryTimer()); - - rm.setRetryCount(1); - assertTrue(rm.isRetryNeeded()); - assertFalse(rm.isRetryForever()); - assertEquals(1, rm.getRetryCount()); - assertEquals(2000, rm.getRetryTimer()); - - rm.retryForeverUsingLastTimeout(); - assertTrue(rm.isRetryNeeded()); - assertTrue(rm.isRetryForever()); - rm.resetRetryCount(); - assertTrue(rm.isRetryNeeded()); - assertFalse(rm.isRetryForever()); - assertEquals(0, rm.getRetryCount()); - assertEquals(1000, rm.getRetryTimer()); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java deleted file mode 100644 index cb67a93f159b..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java +++ /dev/null @@ -1,66 +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; - -import com.android.internal.telephony.Phone; -import android.telephony.CellInfo; - -/** - * Stub class used for unit tests - */ - -public class TestPhoneNotifier implements PhoneNotifier { - public TestPhoneNotifier() { - } - - public void notifyPhoneState(Phone sender) { - } - - public void notifyServiceState(Phone sender) { - } - - public void notifyCellLocation(Phone sender) { - } - - public void notifySignalStrength(Phone sender) { - } - - public void notifyMessageWaitingChanged(Phone sender) { - } - - public void notifyCallForwardingChanged(Phone sender) { - } - - public void notifyDataConnection(Phone sender, String reason, String apnType) { - } - - public void notifyDataConnection(Phone sender, String reason, String apnType, - Phone.DataState state) { - } - - public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { - } - - public void notifyDataActivity(Phone sender) { - } - - public void notifyOtaspChanged(Phone sender, int otaspMode) { - } - - public void notifyCellInfo(Phone sender, CellInfo cellInfo) { - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java deleted file mode 100644 index d31b29430834..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import com.android.internal.telephony.WspTypeDecoder; -import com.android.internal.util.HexDump; - -import java.io.ByteArrayOutputStream; -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestCase; - -public class Wap230WspContentTypeTest extends TestCase { - - public static final Map WELL_KNOWN_SHORT_MIME_TYPES - = new HashMap(); - public static final Map WELL_KNOWN_LONG_MIME_TYPES - = new HashMap(); - public static final Map WELL_KNOWN_PARAMETERS - = new HashMap(); - - static { - WELL_KNOWN_SHORT_MIME_TYPES.put(0x00, "*/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x01, "text/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x02, "text/html"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x03, "text/plain"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x04, "text/x-hdml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x05, "text/x-ttml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x06, "text/x-vCalendar"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x07, "text/x-vCard"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x08, "text/vnd.wap.wml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0B, "multipart/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0C, "multipart/mixed"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0D, "multipart/form-data"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0E, "multipart/byterantes"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x0F, "multipart/alternative"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x10, "application/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x11, "application/java-vm"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x13, "application/x-hdmlc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1B, "application/x-x509-user-cert"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1C, "image/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1D, "image/gif"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1E, "image/jpeg"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x1F, "image/tiff"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x20, "image/png"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x27, "application/xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x28, "text/xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2C, "application/x-x968-user-cert"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2D, "text/vnd.wap.si"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2E, "application/vnd.wap.sic"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x2F, "text/vnd.wap.sl"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x30, "application/vnd.wap.slc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x31, "text/vnd.wap.co"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x32, "application/vnd.wap.coc"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x34, "application/vnd.wap.sia"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x37, "application/pkcs7-mime"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3B, "application/xhtml+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3C, "application/wml+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3D, "text/css"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x44, "application/vnd.syncml.notification"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x4F, "audio/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x50, "video/*"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x52, "application/mikey"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x53, "application/vnd.oma.dcd"); - WELL_KNOWN_SHORT_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc"); - - WELL_KNOWN_LONG_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x020C, "image/x-up-wpng"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0301, "application/iota.mmc-xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0305, "text/calendar"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0309, "text/directory;profile=vCard"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0314, "application/oma-directory+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid"); - WELL_KNOWN_LONG_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger"); - - WELL_KNOWN_PARAMETERS.put(0x00, "Q"); - WELL_KNOWN_PARAMETERS.put(0x01, "Charset"); - WELL_KNOWN_PARAMETERS.put(0x02, "Level"); - WELL_KNOWN_PARAMETERS.put(0x03, "Type"); - WELL_KNOWN_PARAMETERS.put(0x07, "Differences"); - WELL_KNOWN_PARAMETERS.put(0x08, "Padding"); - WELL_KNOWN_PARAMETERS.put(0x09, "Type"); - WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age"); - WELL_KNOWN_PARAMETERS.put(0x10, "Secure"); - WELL_KNOWN_PARAMETERS.put(0x11, "SEC"); - WELL_KNOWN_PARAMETERS.put(0x12, "MAC"); - WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date"); - WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date"); - WELL_KNOWN_PARAMETERS.put(0x15, "Read-date"); - WELL_KNOWN_PARAMETERS.put(0x16, "Size"); - WELL_KNOWN_PARAMETERS.put(0x17, "Name"); - WELL_KNOWN_PARAMETERS.put(0x18, "Filename"); - WELL_KNOWN_PARAMETERS.put(0x19, "Start"); - WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info"); - WELL_KNOWN_PARAMETERS.put(0x1B, "Comment"); - WELL_KNOWN_PARAMETERS.put(0x1C, "Domain"); - WELL_KNOWN_PARAMETERS.put(0x1D, "Path"); - - } - - final int WSP_DEFINED_SHORT_MIME_TYPE_COUNT = 85; - final int WSP_DEFINED_LONG_MIME_TYPE_COUNT = 85; - - private static final byte WSP_STRING_TERMINATOR = 0x00; - private static final byte WSP_SHORT_INTEGER_MASK = (byte) 0x80; - private static final byte WSP_LENGTH_QUOTE = 0x1F; - private static final byte WSP_QUOTE = 0x22; - - private static final short LONG_MIME_TYPE_OMA_DIRECTORY_XML = 0x0314; - private static final short LONG_MIME_TYPE_UNASSIGNED = 0x052C; - - private static final byte SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE = 0x3F; - private static final byte SHORT_MIME_TYPE_UNASSIGNED = 0x60; - - private static final String STRING_MIME_TYPE_ROLLOVER_CERTIFICATE - = "application/vnd.wap.rollover-certificate"; - - private static final byte TYPED_PARAM_Q = 0x00; - private static final byte TYPED_PARAM_DOMAIN = 0x1C; - private static final byte PARAM_UNASSIGNED = 0x42; - private static final byte PARAM_NO_VALUE = 0x00; - private static final byte TYPED_PARAM_SEC = 0x11; - private static final byte TYPED_PARAM_MAC = 0x12; - - public void testHasExpectedNumberOfShortMimeTypes() { - assertEquals(WSP_DEFINED_SHORT_MIME_TYPE_COUNT, WELL_KNOWN_SHORT_MIME_TYPES.size()); - } - - public void testHasExpectedNumberOfLongMimeTypes() { - assertEquals(WSP_DEFINED_LONG_MIME_TYPE_COUNT, WELL_KNOWN_LONG_MIME_TYPES.size()); - } - - public void testWellKnownShortIntegerMimeTypeValues() { - - for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) { - WspTypeDecoder unit = new WspTypeDecoder( - HexDump.toByteArray((byte) (value | WSP_SHORT_INTEGER_MASK))); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - int wellKnownValue = (int) unit.getValue32(); - assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType); - assertEquals(value, wellKnownValue); - assertEquals(1, unit.getDecodedDataLength()); - } - } - - public void testWellKnownLongIntegerMimeTypeValues() { - byte headerLength = 3; - byte typeLength = 2; - for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) { - byte[] data = new byte[10]; - data[0] = headerLength; - data[1] = typeLength; - data[2] = (byte) (value >> 8); - data[3] = (byte) (value & 0xFF); - WspTypeDecoder unit = new WspTypeDecoder(data); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - int wellKnownValue = (int) unit.getValue32(); - assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType); - assertEquals(value, wellKnownValue); - assertEquals(4, unit.getDecodedDataLength()); - } - } - - public void testDecodeReturnsFalse_WhenOnlyAZeroBytePresent() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x00); - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertFalse(unit.decodeContentType(0)); - } - - public void testConstrainedMediaExtensionMedia() throws Exception { - - String testType = "application/wibble"; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(testType.getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - assertEquals(testType, mimeType); - assertEquals(-1, unit.getValue32()); - assertEquals(19, unit.getDecodedDataLength()); - } - - public void testGeneralFormShortLengthExtensionMedia() throws Exception { - - String testType = "12345678901234567890123456789"; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(testType.length() + 1); - out.write(testType.getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - assertEquals(testType, mimeType); - assertEquals(-1, unit.getValue32()); - assertEquals(31, unit.getDecodedDataLength()); - } - - public void testGeneralFormShortLengthWellKnownShortInteger() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x01); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(2, unit.getDecodedDataLength()); - - } - - public void testGeneralFormShortLengthWellKnownShortIntegerWithUnknownValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x01); - out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - assertNull(mimeType); - assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32()); - assertEquals(2, unit.getDecodedDataLength()); - - } - - public void testGeneralFormShortLengthWellKnownLongInteger() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(0x03); // header length - out.write(0x02); // type length (2 octets) - out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8); - out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals("application/oma-directory+xml", mimeType); - assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32()); - assertEquals(4, unit.getDecodedDataLength()); - } - - public void testGeneralFormShortLengthWellKnownLongIntegerWithUnknownValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(0x03); // Value-length, short-length - out.write(0x02); // long-integer length (2 octets) - out.write(LONG_MIME_TYPE_UNASSIGNED >> 8); - out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertNull(mimeType); - assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32()); - assertEquals(4, unit.getDecodedDataLength()); - - } - - public void testGeneralFormLengthQuoteWellKnownShortInteger() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(0x01); // Length as UINTVAR - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(3, unit.getDecodedDataLength()); - - } - - public void testGeneralFormLengthQuoteWellKnownShortIntegerWithUnknownValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(0x01); // Length as UINTVAR - out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - assertNull(mimeType); - assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32()); - assertEquals(3, unit.getDecodedDataLength()); - } - - public void testGeneralFormLengthQuoteWellKnownLongInteger() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(0x03); // Length as UINTVAR - out.write(0x02); // long-integer length (2 octets) - out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8); - out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals("application/oma-directory+xml", mimeType); - assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32()); - assertEquals(5, unit.getDecodedDataLength()); - - } - - public void testGeneralFormLengthQuoteWellKnownLongIntegerWithUnknownValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(0x03); // Length as UINTVAR - out.write(0x02); // long-integer length (2 octets) - out.write(LONG_MIME_TYPE_UNASSIGNED >> 8); - out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertNull(mimeType); - assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32()); - assertEquals(5, unit.getDecodedDataLength()); - - } - - public void testGeneralFormLengthQuoteExtensionMedia() throws Exception { - - String testType = "application/wibble"; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(testType.length() + 1); // Length as UINTVAR - - out.write(testType.getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(testType, mimeType); - assertEquals(-1, unit.getValue32()); - assertEquals(21, unit.getDecodedDataLength()); - - } - - public void testGeneralFormLengthQuoteExtensionMediaWithNiceLongMimeType() throws Exception { - - String testType = - "01234567890123456789012345678901234567890123456789012345678901234567890123456789" - +"01234567890123456789012345678901234567890123456789012345678901234567890123456789"; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - out.write(WSP_LENGTH_QUOTE); - out.write(0x81); // Length as UINTVAR (161 decimal, 0xA1), 2 bytes - out.write(0x21); - - out.write(testType.getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(testType, mimeType); - assertEquals(-1, unit.getValue32()); - assertEquals(164, unit.getDecodedDataLength()); - - } - - public void testConstrainedMediaExtensionMediaWithSpace() throws Exception { - - String testType = " application/wibble"; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(testType.getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(testType, mimeType); - assertEquals(-1, unit.getValue32()); - assertEquals(20, unit.getDecodedDataLength()); - - } - - public void testTypedParamWellKnownShortIntegerNoValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x03); // Value-length, short-length - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK); - out.write(PARAM_NO_VALUE); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - - assertEquals(4, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals(null, params.get("Domain")); - - } - - public void testTypedParamWellKnownShortIntegerTokenText() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x14); // Value-length, short-length - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK); - out.write("wdstechnology.com".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - - assertEquals(out.toByteArray().length, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("wdstechnology.com", params.get("Domain")); - - } - - public void testTypedParamWellKnownLongIntegerTokenText() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x15); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(0x01); - out.write(TYPED_PARAM_DOMAIN); - out.write("wdstechnology.com".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - - assertEquals(22, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("wdstechnology.com", params.get("Domain")); - - } - - public void testTypedParamWellKnownShortIntegerQuotedText() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x15); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK); - out.write(WSP_QUOTE); - out.write("wdstechnology.com".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(0x3F, unit.getValue32()); - assertEquals(22, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("wdstechnology.com", params.get("Domain")); - - } - - public void testTypedParamWellKnownShortIntegerCompactIntegerValue() { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x3); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK); - out.write(0x01 | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(0x3F, unit.getValue32()); - assertEquals(4, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("1", params.get("SEC")); - - } - - public void testTypedParamWellKnownShortIntegerMultipleParameters() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x0B); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK); - out.write(0x01 | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_MAC | WSP_SHORT_INTEGER_MASK); - out.write(WSP_QUOTE); - out.write("imapc".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(12, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("1", params.get("SEC")); - assertEquals("imapc", params.get("MAC")); - } - - public void testUntypedParamIntegerValueShortInteger() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x0A); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); // EOS - out.write(0x45 | WSP_SHORT_INTEGER_MASK); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(11, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("69", params.get("MYPARAM")); - } - - public void testUntypedParamIntegerValueLongInteger() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x0C); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - out.write(0x02); // Short Length - out.write(0x42); // Long Integer byte 1 - out.write(0x69); // Long Integer byte 2 - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(0x3F, unit.getValue32()); - assertEquals(13, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("17001", params.get("MYPARAM")); - } - - public void testUntypedParamTextNoValue() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x0A); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - out.write(PARAM_NO_VALUE); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(11, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals(null, params.get("MYPARAM")); - - } - - public void testUntypedParamTextTokenText() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x11); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - out.write("myvalue".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(18, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("myvalue", params.get("MYPARAM")); - } - - public void testUntypedParamTextQuotedString() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x11); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - out.write(WSP_QUOTE); - out.write("myvalue".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - assertEquals(19, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("myvalue", params.get("MYPARAM")); - - } - - public void testDecodesReturnsFalse_ForParamWithMissingValue() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x09); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write("MYPARAM".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertFalse(unit.decodeContentType(0)); - } - - public void testTypedParamTextQValue() { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x04); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(TYPED_PARAM_Q); - out.write(0x83); // Q value byte 1 - out.write(0x31); // Q value byte 2 - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(0x3F, unit.getValue32()); - assertEquals(5, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("433", params.get("Q")); - - } - - public void testTypedParamUnassignedWellKnownShortIntegerTokenText() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x14); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(PARAM_UNASSIGNED | WSP_SHORT_INTEGER_MASK); - out.write("wdstechnology.com".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - - assertEquals(21, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("wdstechnology.com", params.get("unassigned/0x42")); - - } - - public void testTypedParamUnassignedWellKnownLongIntegerTokenText() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x15); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(0x01); // Short-length of well-known parameter token - out.write(PARAM_UNASSIGNED); - out.write("wdstechnology.com".getBytes("US-ASCII")); - out.write(WSP_STRING_TERMINATOR); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertTrue(unit.decodeContentType(0)); - - String mimeType = unit.getValueString(); - - assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType); - assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32()); - - assertEquals(22, unit.getDecodedDataLength()); - - Map params = unit.getContentParameters(); - assertEquals("wdstechnology.com", params.get("unassigned/0x42")); - } - - public void testDecodesReturnsFalse_WhenParamValueNotTerminated() throws Exception { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(0x15); - out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK); - out.write(0x01); - out.write(PARAM_UNASSIGNED); - out.write("wdstechnology.com".getBytes("US-ASCII")); - - WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray()); - assertFalse(unit.decodeContentType(0)); - } -} \ No newline at end of file diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java deleted file mode 100644 index d2facebffb6a..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright (C) 2012 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.Parcel; -import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbMessage; -import android.telephony.cdma.CdmaSmsCbProgramData; -import android.test.AndroidTestCase; -import android.util.Log; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.cdma.sms.BearerData; -import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; -import com.android.internal.telephony.cdma.sms.SmsEnvelope; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.BitwiseOutputStream; - -import java.util.Arrays; -import java.util.List; -import java.util.Random; - -/** - * Test cases for basic SmsCbMessage operation for CDMA. - */ -public class CdmaSmsCbTest extends AndroidTestCase { - - /* Copy of private subparameter identifier constants from BearerData class. */ - private static final byte SUBPARAM_MESSAGE_IDENTIFIER = (byte) 0x00; - private static final byte SUBPARAM_USER_DATA = (byte) 0x01; - private static final byte SUBPARAM_PRIORITY_INDICATOR = (byte) 0x08; - private static final byte SUBPARAM_LANGUAGE_INDICATOR = (byte) 0x0D; - private static final byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12; - - /** - * Initialize a Parcel for an incoming CDMA cell broadcast. The caller will write the - * bearer data and then convert it to an SmsMessage. - * @param serviceCategory the CDMA service category - * @return the initialized Parcel - */ - private static Parcel createBroadcastParcel(int serviceCategory) { - Parcel p = Parcel.obtain(); - - p.writeInt(SmsEnvelope.TELESERVICE_NOT_SET); - p.writeByte((byte) 1); // non-zero for MESSAGE_TYPE_BROADCAST - p.writeInt(serviceCategory); - - // dummy address (RIL may generate a different dummy address for broadcasts) - p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); // sAddress.digit_mode - p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); // sAddress.number_mode - p.writeInt(CdmaSmsAddress.TON_UNKNOWN); // sAddress.number_type - p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY); // sAddress.number_plan - p.writeByte((byte) 0); // sAddress.number_of_digits - p.writeInt((byte) 0); // sSubAddress.subaddressType - p.writeByte((byte) 0); // sSubAddress.odd - p.writeByte((byte) 0); // sSubAddress.number_of_digits - return p; - } - - /** - * Initialize a BitwiseOutputStream with the CDMA bearer data subparameters except for - * user data. The caller will append the user data and add it to the parcel. - * @param messageId the 16-bit message identifier - * @param priority message priority - * @param language message language code - * @return the initialized BitwiseOutputStream - */ - private static BitwiseOutputStream createBearerDataStream(int messageId, int priority, - int language) throws BitwiseOutputStream.AccessException { - BitwiseOutputStream bos = new BitwiseOutputStream(10); - bos.write(8, SUBPARAM_MESSAGE_IDENTIFIER); - bos.write(8, 3); // length: 3 bytes - bos.write(4, BearerData.MESSAGE_TYPE_DELIVER); - bos.write(8, ((messageId >>> 8) & 0xff)); - bos.write(8, (messageId & 0xff)); - bos.write(1, 0); // no User Data Header - bos.write(3, 0); // reserved - - if (priority != -1) { - bos.write(8, SUBPARAM_PRIORITY_INDICATOR); - bos.write(8, 1); // length: 1 byte - bos.write(2, (priority & 0x03)); - bos.write(6, 0); // reserved - } - - if (language != -1) { - bos.write(8, SUBPARAM_LANGUAGE_INDICATOR); - bos.write(8, 1); // length: 1 byte - bos.write(8, (language & 0xff)); - } - - return bos; - } - - /** - * Write the bearer data array to the parcel, then return a new SmsMessage from the parcel. - * @param p the parcel containing the CDMA SMS headers - * @param bearerData the bearer data byte array to append to the parcel - * @return the new SmsMessage created from the parcel - */ - private static SmsMessage createMessageFromParcel(Parcel p, byte[] bearerData) { - p.writeInt(bearerData.length); - for (byte b : bearerData) { - p.writeByte(b); - } - p.setDataPosition(0); // reset position for reading - SmsMessage message = SmsMessage.newFromParcel(p); - p.recycle(); - return message; - } - - /** - * Create a parcel for an incoming CMAS broadcast, then return a new SmsMessage created - * from the parcel. - * @param serviceCategory the CDMA service category - * @param messageId the 16-bit message identifier - * @param priority message priority - * @param language message language code - * @param body message body - * @param cmasCategory CMAS category (or -1 to skip adding CMAS type 1 elements record) - * @param responseType CMAS response type - * @param severity CMAS severity - * @param urgency CMAS urgency - * @param certainty CMAS certainty - * @return the newly created SmsMessage object - */ - private static SmsMessage createCmasSmsMessage(int serviceCategory, int messageId, int priority, - int language, int encoding, String body, int cmasCategory, int responseType, - int severity, int urgency, int certainty) throws Exception { - BitwiseOutputStream cmasBos = new BitwiseOutputStream(10); - cmasBos.write(8, 0); // CMAE protocol version 0 - - if (body != null) { - cmasBos.write(8, 0); // Type 0 elements (alert text) - encodeBody(encoding, body, true, cmasBos); - } - - if (cmasCategory != SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN) { - cmasBos.write(8, 1); // Type 1 elements - cmasBos.write(8, 4); // length: 4 bytes - cmasBos.write(8, (cmasCategory & 0xff)); - cmasBos.write(8, (responseType & 0xff)); - cmasBos.write(4, (severity & 0x0f)); - cmasBos.write(4, (urgency & 0x0f)); - cmasBos.write(4, (certainty & 0x0f)); - cmasBos.write(4, 0); // pad to octet boundary - } - - byte[] cmasUserData = cmasBos.toByteArray(); - - Parcel p = createBroadcastParcel(serviceCategory); - BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language); - - bos.write(8, SUBPARAM_USER_DATA); - bos.write(8, cmasUserData.length + 2); // add 2 bytes for msg_encoding and num_fields - bos.write(5, UserData.ENCODING_OCTET); - bos.write(8, cmasUserData.length); - bos.writeByteArray(cmasUserData.length * 8, cmasUserData); - bos.write(3, 0); // pad to byte boundary - - return createMessageFromParcel(p, bos.toByteArray()); - } - - /** - * Create a parcel for an incoming CDMA cell broadcast, then return a new SmsMessage created - * from the parcel. - * @param serviceCategory the CDMA service category - * @param messageId the 16-bit message identifier - * @param priority message priority - * @param language message language code - * @param encoding user data encoding method - * @param body the message body - * @return the newly created SmsMessage object - */ - private static SmsMessage createBroadcastSmsMessage(int serviceCategory, int messageId, - int priority, int language, int encoding, String body) throws Exception { - Parcel p = createBroadcastParcel(serviceCategory); - BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language); - - bos.write(8, SUBPARAM_USER_DATA); - encodeBody(encoding, body, false, bos); - - return createMessageFromParcel(p, bos.toByteArray()); - } - - /** - * Append the message length, encoding, and body to the BearerData output stream. - * This is used for writing the User Data subparameter for non-CMAS broadcasts and for - * writing the alert text for CMAS broadcasts. - * @param encoding one of the CDMA UserData encoding values - * @param body the message body - * @param isCmasRecord true if this is a CMAS type 0 elements record; false for user data - * @param bos the BitwiseOutputStream to write to - * @throws Exception on any encoding error - */ - private static void encodeBody(int encoding, String body, boolean isCmasRecord, - BitwiseOutputStream bos) throws Exception { - if (encoding == UserData.ENCODING_7BIT_ASCII || encoding == UserData.ENCODING_IA5) { - int charCount = body.length(); - int recordBits = (charCount * 7) + 5; // add 5 bits for char set field - int recordOctets = (recordBits + 7) / 8; // round up to octet boundary - int padBits = (recordOctets * 8) - recordBits; - - if (!isCmasRecord) { - recordOctets++; // add 8 bits for num_fields - } - - bos.write(8, recordOctets); - bos.write(5, (encoding & 0x1f)); - - if (!isCmasRecord) { - bos.write(8, charCount); - } - - for (int i = 0; i < charCount; i++) { - bos.write(7, body.charAt(i)); - } - - bos.write(padBits, 0); // pad to octet boundary - } else if (encoding == UserData.ENCODING_GSM_7BIT_ALPHABET - || encoding == UserData.ENCODING_GSM_DCS) { - // convert to 7-bit packed encoding with septet count in index 0 of byte array - byte[] encodedBody = GsmAlphabet.stringToGsm7BitPacked(body); - - int charCount = encodedBody[0]; // septet count - int recordBits = (charCount * 7) + 5; // add 5 bits for char set field - int recordOctets = (recordBits + 7) / 8; // round up to octet boundary - int padBits = (recordOctets * 8) - recordBits; - - if (!isCmasRecord) { - recordOctets++; // add 8 bits for num_fields - if (encoding == UserData.ENCODING_GSM_DCS) { - recordOctets++; // add 8 bits for DCS (message type) - } - } - - bos.write(8, recordOctets); - bos.write(5, (encoding & 0x1f)); - - if (!isCmasRecord && encoding == UserData.ENCODING_GSM_DCS) { - bos.write(8, 0); // GSM DCS: 7 bit default alphabet, no msg class - } - - if (!isCmasRecord) { - bos.write(8, charCount); - } - byte[] bodySeptets = Arrays.copyOfRange(encodedBody, 1, encodedBody.length); - bos.writeByteArray(charCount * 7, bodySeptets); - bos.write(padBits, 0); // pad to octet boundary - } else if (encoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) { - // 6 bit packed encoding with 0x20 offset (ASCII 0x20 - 0x60) - int charCount = body.length(); - int recordBits = (charCount * 6) + 21; // add 21 bits for header fields - int recordOctets = (recordBits + 7) / 8; // round up to octet boundary - int padBits = (recordOctets * 8) - recordBits; - - bos.write(8, recordOctets); - - bos.write(5, (encoding & 0x1f)); - bos.write(8, UserData.IS91_MSG_TYPE_SHORT_MESSAGE); - bos.write(8, charCount); - - for (int i = 0; i < charCount; i++) { - bos.write(6, ((int) body.charAt(i) - 0x20)); - } - - bos.write(padBits, 0); // pad to octet boundary - } else { - byte[] encodedBody; - switch (encoding) { - case UserData.ENCODING_UNICODE_16: - encodedBody = body.getBytes("UTF-16BE"); - break; - - case UserData.ENCODING_SHIFT_JIS: - encodedBody = body.getBytes("Shift_JIS"); - break; - - case UserData.ENCODING_KOREAN: - encodedBody = body.getBytes("KSC5601"); - break; - - case UserData.ENCODING_LATIN_HEBREW: - encodedBody = body.getBytes("ISO-8859-8"); - break; - - case UserData.ENCODING_LATIN: - default: - encodedBody = body.getBytes("ISO-8859-1"); - break; - } - int charCount = body.length(); // use actual char count for num fields - int recordOctets = encodedBody.length + 1; // add 1 byte for encoding and pad bits - if (!isCmasRecord) { - recordOctets++; // add 8 bits for num_fields - } - bos.write(8, recordOctets); - bos.write(5, (encoding & 0x1f)); - if (!isCmasRecord) { - bos.write(8, charCount); - } - bos.writeByteArray(encodedBody.length * 8, encodedBody); - bos.write(3, 0); // pad to octet boundary - } - } - - private static final String TEST_TEXT = "This is a test CDMA cell broadcast message..." - + "678901234567890123456789012345678901234567890"; - - private static final String PRES_ALERT = - "THE PRESIDENT HAS ISSUED AN EMERGENCY ALERT. CHECK LOCAL MEDIA FOR MORE DETAILS"; - - private static final String EXTREME_ALERT = "FLASH FLOOD WARNING FOR SOUTH COCONINO COUNTY" - + " - NORTH CENTRAL ARIZONA UNTIL 415 PM MST"; - - private static final String SEVERE_ALERT = "SEVERE WEATHER WARNING FOR SOMERSET COUNTY" - + " - NEW JERSEY UNTIL 415 PM MST"; - - private static final String AMBER_ALERT = - "AMBER ALERT:Mountain View,CA VEH'07 Blue Honda Civic CA LIC 5ABC123"; - - private static final String MONTHLY_TEST_ALERT = "This is a test of the emergency alert system." - + " This is only a test. 89012345678901234567890"; - - private static final String IS91_TEXT = "IS91 SHORT MSG"; // max length 14 chars - - /** - * Verify that the SmsCbMessage has the correct values for CDMA. - * @param cbMessage the message to test - */ - private static void verifyCbValues(SmsCbMessage cbMessage) { - assertEquals(SmsCbMessage.MESSAGE_FORMAT_3GPP2, cbMessage.getMessageFormat()); - assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, cbMessage.getGeographicalScope()); - assertEquals(false, cbMessage.isEtwsMessage()); // ETWS on CDMA not currently supported - } - - private static void doTestNonEmergencyBroadcast(int encoding) throws Exception { - SmsMessage msg = createBroadcastSmsMessage(123, 456, BearerData.PRIORITY_NORMAL, - BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - verifyCbValues(cbMessage); - assertEquals(123, cbMessage.getServiceCategory()); - assertEquals(456, cbMessage.getSerialNumber()); - assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority()); - assertEquals("en", cbMessage.getLanguageCode()); - assertEquals(TEST_TEXT, cbMessage.getMessageBody()); - assertEquals(false, cbMessage.isEmergencyMessage()); - assertEquals(false, cbMessage.isCmasMessage()); - } - - public void testNonEmergencyBroadcast7bitAscii() throws Exception { - doTestNonEmergencyBroadcast(UserData.ENCODING_7BIT_ASCII); - } - - public void testNonEmergencyBroadcast7bitGsm() throws Exception { - doTestNonEmergencyBroadcast(UserData.ENCODING_GSM_7BIT_ALPHABET); - } - - public void testNonEmergencyBroadcast16bitUnicode() throws Exception { - doTestNonEmergencyBroadcast(UserData.ENCODING_UNICODE_16); - } - - public void testNonEmergencyBroadcastIs91Extended() throws Exception { - // IS-91 doesn't support language or priority subparameters, max 14 chars text - SmsMessage msg = createBroadcastSmsMessage(987, 654, -1, -1, - UserData.ENCODING_IS91_EXTENDED_PROTOCOL, IS91_TEXT); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - verifyCbValues(cbMessage); - assertEquals(987, cbMessage.getServiceCategory()); - assertEquals(654, cbMessage.getSerialNumber()); - assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority()); - assertEquals(null, cbMessage.getLanguageCode()); - assertEquals(IS91_TEXT, cbMessage.getMessageBody()); - assertEquals(false, cbMessage.isEmergencyMessage()); - assertEquals(false, cbMessage.isCmasMessage()); - } - - private static void doTestCmasBroadcast(int serviceCategory, int messageClass, String body) - throws Exception { - SmsMessage msg = createCmasSmsMessage( - serviceCategory, 1234, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH, - UserData.ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - verifyCbValues(cbMessage); - assertEquals(serviceCategory, cbMessage.getServiceCategory()); - assertEquals(1234, cbMessage.getSerialNumber()); - assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority()); - assertEquals("en", cbMessage.getLanguageCode()); - assertEquals(body, cbMessage.getMessageBody()); - assertEquals(true, cbMessage.isEmergencyMessage()); - assertEquals(true, cbMessage.isCmasMessage()); - SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo(); - assertEquals(messageClass, cmasInfo.getMessageClass()); - assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory()); - assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType()); - assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity()); - assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency()); - assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty()); - } - - public void testCmasPresidentialAlert() throws Exception { - doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, - SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, PRES_ALERT); - } - - public void testCmasExtremeAlert() throws Exception { - doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, EXTREME_ALERT); - } - - public void testCmasSevereAlert() throws Exception { - doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, - SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT, SEVERE_ALERT); - } - - public void testCmasAmberAlert() throws Exception { - doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, - SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY, AMBER_ALERT); - } - - public void testCmasTestMessage() throws Exception { - doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE, - SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST, MONTHLY_TEST_ALERT); - } - - public void testCmasExtremeAlertType1Elements() throws Exception { - SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - 5678, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH, - UserData.ENCODING_7BIT_ASCII, EXTREME_ALERT, SmsCbCmasInfo.CMAS_CATEGORY_ENV, - SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, - SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - verifyCbValues(cbMessage); - assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - cbMessage.getServiceCategory()); - assertEquals(5678, cbMessage.getSerialNumber()); - assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority()); - assertEquals("en", cbMessage.getLanguageCode()); - assertEquals(EXTREME_ALERT, cbMessage.getMessageBody()); - assertEquals(true, cbMessage.isEmergencyMessage()); - assertEquals(true, cbMessage.isCmasMessage()); - SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo(); - assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass()); - assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_ENV, cmasInfo.getCategory()); - assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, cmasInfo.getResponseType()); - assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, cmasInfo.getSeverity()); - assertEquals(SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, cmasInfo.getUrgency()); - assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, cmasInfo.getCertainty()); - } - - // VZW requirement is to discard message with unsupported charset. Verify that we return null - // for this unsupported character set. - public void testCmasUnsupportedCharSet() throws Exception { - SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - 12345, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH, - UserData.ENCODING_GSM_DCS, EXTREME_ALERT, -1, -1, -1, -1, -1); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - assertNull("expected null for unsupported charset", cbMessage); - } - - // VZW requirement is to discard message with unsupported charset. Verify that we return null - // for this unsupported character set. - public void testCmasUnsupportedCharSet2() throws Exception { - SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - 67890, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH, - UserData.ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - assertNull("expected null for unsupported charset", cbMessage); - } - - // VZW requirement is to discard message without record type 0. The framework will decode it - // and the app will discard it. - public void testCmasNoRecordType0() throws Exception { - SmsMessage msg = createCmasSmsMessage( - SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, 1234, - BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH, - UserData.ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - verifyCbValues(cbMessage); - assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, - cbMessage.getServiceCategory()); - assertEquals(1234, cbMessage.getSerialNumber()); - assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority()); - assertEquals("en", cbMessage.getLanguageCode()); - assertEquals(null, cbMessage.getMessageBody()); - assertEquals(true, cbMessage.isEmergencyMessage()); - assertEquals(true, cbMessage.isCmasMessage()); - SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo(); - assertEquals(SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, cmasInfo.getMessageClass()); - assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory()); - assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType()); - assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity()); - assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency()); - assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty()); - } - - // Make sure we don't throw an exception if we feed completely random data to BearerStream. - public void testRandomBearerStreamData() { - Random r = new Random(54321); - for (int run = 0; run < 1000; run++) { - int len = r.nextInt(140); - byte[] data = new byte[len]; - for (int i = 0; i < len; i++) { - data[i] = (byte) r.nextInt(256); - } - // Log.d("CdmaSmsCbTest", "trying random bearer data run " + run + " length " + len); - try { - int category = 0x0ff0 + r.nextInt(32); // half CMAS, half non-CMAS - Parcel p = createBroadcastParcel(category); - SmsMessage msg = createMessageFromParcel(p, data); - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - // with random input, cbMessage will almost always be null (log when it isn't) - if (cbMessage != null) { - Log.d("CdmaSmsCbTest", "success: " + cbMessage); - } - } catch (Exception e) { - Log.d("CdmaSmsCbTest", "exception thrown", e); - fail("Exception in decoder at run " + run + " length " + len + ": " + e); - } - } - } - - // Make sure we don't throw an exception if we put random data in the UserData subparam. - public void testRandomUserData() { - Random r = new Random(94040); - for (int run = 0; run < 1000; run++) { - int category = 0x0ff0 + r.nextInt(32); // half CMAS, half non-CMAS - Parcel p = createBroadcastParcel(category); - int len = r.nextInt(140); - // Log.d("CdmaSmsCbTest", "trying random user data run " + run + " length " + len); - - try { - BitwiseOutputStream bos = createBearerDataStream(r.nextInt(65536), r.nextInt(4), - r.nextInt(256)); - - bos.write(8, SUBPARAM_USER_DATA); - bos.write(8, len); - - for (int i = 0; i < len; i++) { - bos.write(8, r.nextInt(256)); - } - - SmsMessage msg = createMessageFromParcel(p, bos.toByteArray()); - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - } catch (Exception e) { - Log.d("CdmaSmsCbTest", "exception thrown", e); - fail("Exception in decoder at run " + run + " length " + len + ": " + e); - } - } - } - - /** - * Initialize a Parcel for incoming Service Category Program Data teleservice. The caller will - * write the bearer data and then convert it to an SmsMessage. - * @return the initialized Parcel - */ - private static Parcel createServiceCategoryProgramDataParcel() { - Parcel p = Parcel.obtain(); - - p.writeInt(SmsEnvelope.TELESERVICE_SCPT); - p.writeByte((byte) 0); // non-zero for MESSAGE_TYPE_BROADCAST - p.writeInt(0); - - // dummy address (RIL may generate a different dummy address for broadcasts) - p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); // sAddress.digit_mode - p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); // sAddress.number_mode - p.writeInt(CdmaSmsAddress.TON_UNKNOWN); // sAddress.number_type - p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY); // sAddress.number_plan - p.writeByte((byte) 0); // sAddress.number_of_digits - p.writeInt((byte) 0); // sSubAddress.subaddressType - p.writeByte((byte) 0); // sSubAddress.odd - p.writeByte((byte) 0); // sSubAddress.number_of_digits - return p; - } - - private static final String CAT_EXTREME_THREAT = "Extreme Threat to Life and Property"; - private static final String CAT_SEVERE_THREAT = "Severe Threat to Life and Property"; - private static final String CAT_AMBER_ALERTS = "AMBER Alerts"; - - public void testServiceCategoryProgramDataAddCategory() throws Exception { - Parcel p = createServiceCategoryProgramDataParcel(); - BitwiseOutputStream bos = createBearerDataStream(123, -1, -1); - - int categoryNameLength = CAT_EXTREME_THREAT.length(); - int subparamLengthBits = (53 + (categoryNameLength * 7)); - int subparamLengthBytes = (subparamLengthBits + 7) / 8; - int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits; - - bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA); - bos.write(8, subparamLengthBytes); - bos.write(5, UserData.ENCODING_7BIT_ASCII); - - bos.write(4, CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT >>> 8)); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT & 0xff)); - bos.write(8, BearerData.LANGUAGE_ENGLISH); - bos.write(8, 100); // max messages - bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT); - - bos.write(8, categoryNameLength); - for (int i = 0; i < categoryNameLength; i++) { - bos.write(7, CAT_EXTREME_THREAT.charAt(i)); - } - bos.write(subparamPadBits, 0); - - SmsMessage msg = createMessageFromParcel(p, bos.toByteArray()); - assertNotNull(msg); - msg.parseSms(); - List programDataList = msg.getSmsCbProgramData(); - assertNotNull(programDataList); - assertEquals(1, programDataList.size()); - CdmaSmsCbProgramData programData = programDataList.get(0); - assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation()); - assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory()); - assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); - assertEquals(100, programData.getMaxMessages()); - assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption()); - } - - public void testServiceCategoryProgramDataDeleteTwoCategories() throws Exception { - Parcel p = createServiceCategoryProgramDataParcel(); - BitwiseOutputStream bos = createBearerDataStream(456, -1, -1); - - int category1NameLength = CAT_SEVERE_THREAT.length(); - int category2NameLength = CAT_AMBER_ALERTS.length(); - - int subparamLengthBits = (101 + (category1NameLength * 7) + (category2NameLength * 7)); - int subparamLengthBytes = (subparamLengthBits + 7) / 8; - int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits; - - bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA); - bos.write(8, subparamLengthBytes); - bos.write(5, UserData.ENCODING_7BIT_ASCII); - - bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT >>> 8)); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT & 0xff)); - bos.write(8, BearerData.LANGUAGE_ENGLISH); - bos.write(8, 0); // max messages - bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT); - - bos.write(8, category1NameLength); - for (int i = 0; i < category1NameLength; i++) { - bos.write(7, CAT_SEVERE_THREAT.charAt(i)); - } - - bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY >>> 8)); - bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY & 0xff)); - bos.write(8, BearerData.LANGUAGE_ENGLISH); - bos.write(8, 0); // max messages - bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT); - - bos.write(8, category2NameLength); - for (int i = 0; i < category2NameLength; i++) { - bos.write(7, CAT_AMBER_ALERTS.charAt(i)); - } - - bos.write(subparamPadBits, 0); - - SmsMessage msg = createMessageFromParcel(p, bos.toByteArray()); - assertNotNull(msg); - msg.parseSms(); - List programDataList = msg.getSmsCbProgramData(); - assertNotNull(programDataList); - assertEquals(2, programDataList.size()); - - CdmaSmsCbProgramData programData = programDataList.get(0); - assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation()); - assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory()); - assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); - assertEquals(0, programData.getMaxMessages()); - assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); - - programData = programDataList.get(1); - assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation()); - assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, - programData.getCategory()); - assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); - assertEquals(0, programData.getMaxMessages()); - assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); - } - - private static final byte[] CMAS_TEST_BEARER_DATA = { - 0x00, 0x03, 0x1C, 0x78, 0x00, 0x01, 0x59, 0x02, (byte) 0xB8, 0x00, 0x02, 0x10, (byte) 0xAA, - 0x68, (byte) 0xD3, (byte) 0xCD, 0x06, (byte) 0x9E, 0x68, 0x30, (byte) 0xA0, (byte) 0xE9, - (byte) 0x97, (byte) 0x9F, 0x44, 0x1B, (byte) 0xF3, 0x20, (byte) 0xE9, (byte) 0xA3, - 0x2A, 0x08, 0x7B, (byte) 0xF6, (byte) 0xED, (byte) 0xCB, (byte) 0xCB, 0x1E, (byte) 0x9C, - 0x3B, 0x10, 0x4D, (byte) 0xDF, (byte) 0x8B, 0x4E, - (byte) 0xCC, (byte) 0xA8, 0x20, (byte) 0xEC, (byte) 0xCB, (byte) 0xCB, (byte) 0xA2, 0x0A, - 0x7E, 0x79, (byte) 0xF4, (byte) 0xCB, (byte) 0xB5, 0x72, 0x0A, (byte) 0x9A, 0x34, - (byte) 0xF3, 0x41, (byte) 0xA7, (byte) 0x9A, 0x0D, (byte) 0xFB, (byte) 0xB6, 0x79, 0x41, - (byte) 0x85, 0x07, 0x4C, (byte) 0xBC, (byte) 0xFA, 0x2E, 0x00, 0x08, 0x20, 0x58, 0x38, - (byte) 0x88, (byte) 0x80, 0x10, 0x54, 0x06, 0x38, 0x20, 0x60, - 0x30, (byte) 0xA8, (byte) 0x81, (byte) 0x90, 0x20, 0x08 - }; - - // Test case for CMAS test message received on the Sprint network. - public void testDecodeRawBearerData() throws Exception { - Parcel p = createBroadcastParcel(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE); - SmsMessage msg = createMessageFromParcel(p, CMAS_TEST_BEARER_DATA); - - SmsCbMessage cbMessage = msg.parseBroadcastSms(); - assertNotNull("expected non-null for bearer data", cbMessage); - assertEquals("geoScope", cbMessage.getGeographicalScope(), 1); - assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072); - assertEquals("serviceCategory", cbMessage.getServiceCategory(), - SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE); - assertEquals("payload", cbMessage.getMessageBody(), - "This is a test of the Commercial Mobile Alert System. This is only a test."); - - SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo(); - assertNotNull("expected non-null for CMAS info", cmasInfo); - assertEquals("category", cmasInfo.getCategory(), SmsCbCmasInfo.CMAS_CATEGORY_OTHER); - assertEquals("responseType", cmasInfo.getResponseType(), - SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE); - assertEquals("severity", cmasInfo.getSeverity(), SmsCbCmasInfo.CMAS_SEVERITY_SEVERE); - assertEquals("urgency", cmasInfo.getUrgency(), SmsCbCmasInfo.CMAS_URGENCY_EXPECTED); - assertEquals("certainty", cmasInfo.getCertainty(), SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java deleted file mode 100644 index 58e73e0dabbc..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java +++ /dev/null @@ -1,887 +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.cdma.sms; - -import android.telephony.TelephonyManager; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.SmsHeader; -import com.android.internal.telephony.cdma.SmsMessage; -import com.android.internal.telephony.cdma.sms.BearerData; -import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; -import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; -import com.android.internal.util.BitwiseInputStream; -import com.android.internal.util.BitwiseOutputStream; -import com.android.internal.util.HexDump; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import android.util.Log; - -import java.util.ArrayList; - -public class CdmaSmsTest extends AndroidTestCase { - private final static String LOG_TAG = "XXX CdmaSmsTest XXX"; - - @SmallTest - public void testCdmaSmsAddrParsing() throws Exception { - CdmaSmsAddress addr = CdmaSmsAddress.parse("6502531000"); - assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 10); - assertEquals(addr.origBytes.length, 10); - byte[] data = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10}; - for (int i = 0; i < data.length; i++) { - assertEquals(addr.origBytes[i], data[i]); - } - addr = CdmaSmsAddress.parse("(650) 253-1000"); - assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 10); - assertEquals(addr.origBytes.length, 10); - byte[] data2 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10}; - for (int i = 0; i < data2.length; i++) { - assertEquals(addr.origBytes[i], data2[i]); - } - addr = CdmaSmsAddress.parse("650.253.1000"); - assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 10); - assertEquals(addr.origBytes.length, 10); - byte[] data5 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10}; - for (int i = 0; i < data2.length; i++) { - assertEquals(addr.origBytes[i], data5[i]); - } - addr = CdmaSmsAddress.parse("(+886) 917 222 555"); - assertEquals(addr.ton, CdmaSmsAddress.TON_INTERNATIONAL_OR_IP); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 12); - assertEquals(addr.origBytes.length, 12); - byte[] data3 = {8, 8, 6, 9, 1, 7, 2, 2, 2, 5, 5, 5}; - for (int i = 0; i < data3.length; i++) { - assertEquals(addr.origBytes[i], data3[i]); - } - addr = CdmaSmsAddress.parse("(650) *253-1000 #600"); - byte[] data4 = {6, 5, 10, 11, 2, 5, 3, 1, 10, 10, 10, 12, 6, 10, 10}; - for (int i = 0; i < data4.length; i++) { - assertEquals(addr.origBytes[i], data4[i]); - } - String input = "x@y.com,a@b.com"; - addr = CdmaSmsAddress.parse(input); - assertEquals(addr.ton, CdmaSmsAddress.TON_NATIONAL_OR_EMAIL); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 15); - assertEquals(addr.origBytes.length, 15); - assertEquals(new String(addr.origBytes), input); - addr = CdmaSmsAddress.parse("foo bar"); - assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR); - assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK); - assertEquals(addr.numberOfDigits, 6); - assertEquals(addr.origBytes.length, 6); - assertEquals(new String(addr.origBytes), "foobar"); - addr = CdmaSmsAddress.parse("f\noo\tb a\rr"); - assertEquals(new String(addr.origBytes), "foobar"); - assertEquals(CdmaSmsAddress.parse("f\u0000oo bar"), null); - assertEquals(CdmaSmsAddress.parse("f\u0007oo bar"), null); - assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null); - assertEquals(CdmaSmsAddress.parse("f\u1ECFboo\u001fbar"), null); - assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null); - } - - @SmallTest - public void testUserData7bitGsm() throws Exception { - String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals("Test standard SMS", bearerData.userData.payloadStr); - } - - @SmallTest - public void testUserData7bitAscii() throws Exception { - String pdu = "0003100160010610262d5ab500"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals("bjjj", bearerData.userData.payloadStr); - } - - @SmallTest - public void testUserData7bitAsciiTwo() throws Exception { - String pdu = "00031001d00109104539b4d052ebb3d0"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals("SMS Rulz", bearerData.userData.payloadStr); - } - - @SmallTest - public void testUserDataIa5() throws Exception { - String pdu = "00031002100109184539b4d052ebb3d0"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals("SMS Rulz", bearerData.userData.payloadStr); - } - - @SmallTest - public void testUserData7bitAsciiFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "Test standard SMS"; - userData.msgEncoding = UserData.ENCODING_7BIT_ASCII; - userData.msgEncodingSet = true; - bearerData.userData = userData; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType); - assertEquals(0, revBearerData.messageId); - assertEquals(false, revBearerData.hasUserDataHeader); - assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding); - assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = "Test \u007f standard \u0000 SMS"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals("Test standard SMS", revBearerData.userData.payloadStr); - userData.payloadStr = "Test \n standard \r SMS"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = ""; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - } - - @SmallTest - public void testUserData7bitGsmFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "Test standard SMS"; - userData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; - userData.msgEncodingSet = true; - bearerData.userData = userData; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType); - assertEquals(0, revBearerData.messageId); - assertEquals(false, revBearerData.hasUserDataHeader); - assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding); - assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = "1234567"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = ""; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = "12345678901234567890123456789012345678901234567890" + - "12345678901234567890123456789012345678901234567890" + - "12345678901234567890123456789012345678901234567890" + - "1234567890"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = "Test \u007f illegal \u0000 SMS chars"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals("Test illegal SMS chars", revBearerData.userData.payloadStr); - userData.payloadStr = "More @ testing\nis great^|^~woohoo"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 0xEE; - concatRef.msgCount = 2; - concatRef.seqNumber = 2; - concatRef.isEightBits = true; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); - userData.userDataHeader = smsHeader; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - SmsHeader decodedHeader = revBearerData.userData.userDataHeader; - assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); - assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); - assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); - } - - @SmallTest - public void testUserDataUtf16Feedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "\u0160u\u1E5B\u0301r\u1ECFg\uD835\uDC1At\u00E9\u4E002\u3042"; - userData.msgEncoding = UserData.ENCODING_UNICODE_16; - userData.msgEncodingSet = true; - bearerData.userData = userData; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType); - assertEquals(0, revBearerData.messageId); - assertEquals(false, revBearerData.hasUserDataHeader); - assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding); - assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.msgEncoding = UserData.ENCODING_OCTET; - userData.msgEncodingSet = false; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType); - assertEquals(0, revBearerData.messageId); - assertEquals(false, revBearerData.hasUserDataHeader); - assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding); - assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = "1234567"; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - userData.payloadStr = ""; - revBearerData = BearerData.decode(BearerData.encode(bearerData)); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - } - - @SmallTest - public void testMonolithicOne() throws Exception { - String pdu = "0003200010010410168d2002010503060812011101590501c706069706180000000701c108" + - "01c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT); - assertEquals(bearerData.messageId, 1); - assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY); - assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL); - assertEquals(bearerData.userAckReq, true); - assertEquals(bearerData.readAckReq, true); - assertEquals(bearerData.deliveryAckReq, true); - assertEquals(bearerData.reportReq, false); - assertEquals(bearerData.numberOfMessages, 3); - assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO); - assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW); - assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(bearerData.callbackNumber.numberMode, - CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN); - assertEquals(bearerData.callbackNumber.numberOfDigits, 7); - assertEquals(bearerData.callbackNumber.address, "3598271"); - assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER); - assertEquals(bearerData.depositIndex, 1382); - assertEquals(bearerData.userResponseCode, 5); - assertEquals(bearerData.msgCenterTimeStamp.year, 2008); - assertEquals(bearerData.msgCenterTimeStamp.month, 11); - assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1); - assertEquals(bearerData.msgCenterTimeStamp.hour, 11); - assertEquals(bearerData.msgCenterTimeStamp.minute, 1); - assertEquals(bearerData.msgCenterTimeStamp.second, 59); - assertEquals(bearerData.validityPeriodAbsolute, null); - assertEquals(bearerData.validityPeriodRelative, 193); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0); - assertEquals(bearerData.deferredDeliveryTimeRelative, 199); - assertEquals(bearerData.hasUserDataHeader, false); - assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII); - assertEquals(bearerData.userData.numFields, 2); - assertEquals(bearerData.userData.payloadStr, "hi"); - } - - @SmallTest - public void testMonolithicTwo() throws Exception { - String pdu = "0003200010010410168d200201050306081201110159050192060697061800000007013d0" + - "801c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566"; - BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); - assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT); - assertEquals(bearerData.messageId, 1); - assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY); - assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL); - assertEquals(bearerData.userAckReq, true); - assertEquals(bearerData.readAckReq, true); - assertEquals(bearerData.deliveryAckReq, true); - assertEquals(bearerData.reportReq, false); - assertEquals(bearerData.numberOfMessages, 3); - assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO); - assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW); - assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); - assertEquals(bearerData.callbackNumber.numberMode, - CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); - assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN); - assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN); - assertEquals(bearerData.callbackNumber.numberOfDigits, 7); - assertEquals(bearerData.callbackNumber.address, "3598271"); - assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER); - assertEquals(bearerData.depositIndex, 1382); - assertEquals(bearerData.userResponseCode, 5); - assertEquals(bearerData.msgCenterTimeStamp.year, 2008); - assertEquals(bearerData.msgCenterTimeStamp.month, 11); - assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1); - assertEquals(bearerData.msgCenterTimeStamp.hour, 11); - assertEquals(bearerData.msgCenterTimeStamp.minute, 1); - assertEquals(bearerData.msgCenterTimeStamp.second, 59); - assertEquals(bearerData.validityPeriodAbsolute, null); - assertEquals(bearerData.validityPeriodRelative, 61); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0); - assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0); - assertEquals(bearerData.deferredDeliveryTimeRelative, 146); - assertEquals(bearerData.hasUserDataHeader, false); - assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII); - assertEquals(bearerData.userData.numFields, 2); - assertEquals(bearerData.userData.payloadStr, "hi"); - } - - @SmallTest - public void testUserDataHeaderConcatRefFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 55; - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 0xEE; - concatRef.msgCount = 2; - concatRef.seqNumber = 2; - concatRef.isEightBits = true; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); - SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); - assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); - assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); - assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); - assertEquals(decodedHeader.portAddrs, null); - UserData userData = new UserData(); - userData.payloadStr = "User Data Header (UDH) feedback test"; - userData.userDataHeader = smsHeader; - bearerData.userData = userData; - byte[] encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - decodedHeader = revBearerData.userData.userDataHeader; - assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); - assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); - assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); - assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); - assertEquals(decodedHeader.portAddrs, null); - } - - @SmallTest - public void testUserDataHeaderIllegalConcatRef() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 55; - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 0x10; - concatRef.msgCount = 0; - concatRef.seqNumber = 2; - concatRef.isEightBits = true; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); - SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef, null); - concatRef.isEightBits = false; - encodedHeader = SmsHeader.toByteArray(smsHeader); - decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef, null); - concatRef.msgCount = 1; - concatRef.seqNumber = 2; - encodedHeader = SmsHeader.toByteArray(smsHeader); - decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef, null); - concatRef.msgCount = 1; - concatRef.seqNumber = 0; - encodedHeader = SmsHeader.toByteArray(smsHeader); - decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef, null); - concatRef.msgCount = 2; - concatRef.seqNumber = 1; - encodedHeader = SmsHeader.toByteArray(smsHeader); - decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef.msgCount, 2); - assertEquals(decodedHeader.concatRef.seqNumber, 1); - } - - @SmallTest - public void testUserDataHeaderMixedFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 42; - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 0x34; - concatRef.msgCount = 5; - concatRef.seqNumber = 2; - concatRef.isEightBits = false; - SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); - portAddrs.destPort = 88; - portAddrs.origPort = 66; - portAddrs.areEightBits = false; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - smsHeader.portAddrs = portAddrs; - byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); - SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); - assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); - assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); - assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); - assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); - assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort); - assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort); - assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits); - UserData userData = new UserData(); - userData.payloadStr = "User Data Header (UDH) feedback test"; - userData.userDataHeader = smsHeader; - bearerData.userData = userData; - byte[] encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - decodedHeader = revBearerData.userData.userDataHeader; - assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); - assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); - assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); - assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); - assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort); - assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort); - assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits); - } - - @SmallTest - public void testReplyOption() throws Exception { - String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals("Test Acknowledgement 1", bd1.userData.payloadStr); - assertEquals(true, bd1.userAckReq); - assertEquals(false, bd1.deliveryAckReq); - assertEquals(false, bd1.readAckReq); - assertEquals(false, bd1.reportReq); - String pdu2 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87490080a0140"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals("Test Acknowledgement 2", bd2.userData.payloadStr); - assertEquals(false, bd2.userAckReq); - assertEquals(true, bd2.deliveryAckReq); - assertEquals(false, bd2.readAckReq); - assertEquals(false, bd2.reportReq); - String pdu3 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d874d0080a0120"; - BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); - assertEquals("Test Acknowledgement 3", bd3.userData.payloadStr); - assertEquals(false, bd3.userAckReq); - assertEquals(false, bd3.deliveryAckReq); - assertEquals(true, bd3.readAckReq); - assertEquals(false, bd3.reportReq); - String pdu4 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87510080a0110"; - BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); - assertEquals("Test Acknowledgement 4", bd4.userData.payloadStr); - assertEquals(false, bd4.userAckReq); - assertEquals(false, bd4.deliveryAckReq); - assertEquals(false, bd4.readAckReq); - assertEquals(true, bd4.reportReq); - } - - @SmallTest - public void testReplyOptionFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test reply option"; - bearerData.userData = userData; - bearerData.userAckReq = true; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(true, revBearerData.userAckReq); - assertEquals(false, revBearerData.deliveryAckReq); - assertEquals(false, revBearerData.readAckReq); - assertEquals(false, revBearerData.reportReq); - bearerData.userAckReq = false; - bearerData.deliveryAckReq = true; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(false, revBearerData.userAckReq); - assertEquals(true, revBearerData.deliveryAckReq); - assertEquals(false, revBearerData.readAckReq); - assertEquals(false, revBearerData.reportReq); - bearerData.deliveryAckReq = false; - bearerData.readAckReq = true; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(false, revBearerData.userAckReq); - assertEquals(false, revBearerData.deliveryAckReq); - assertEquals(true, revBearerData.readAckReq); - assertEquals(false, revBearerData.reportReq); - bearerData.readAckReq = false; - bearerData.reportReq = true; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(false, revBearerData.userAckReq); - assertEquals(false, revBearerData.deliveryAckReq); - assertEquals(false, revBearerData.readAckReq); - assertEquals(true, revBearerData.reportReq); - } - - @SmallTest - public void testNumberOfMessages() throws Exception { - // Note that the message text below does not properly reflect - // the message count. The author of these messages was - // apparently unaware that the values are bcd encoded, and the - // values being tested against (not the ones in the message - // text) are actually correct. - String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals("Test Voice mail 99", bd1.userData.payloadStr); - assertEquals(63, bd1.numberOfMessages); - String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals("Test Voice mail 100", bd2.userData.payloadStr); - assertEquals(64, bd2.numberOfMessages); - } - - @SmallTest - public void testCallbackNum() throws Exception { - String pdu1 = "00031040900112488ea794e070d436cb638bc5e035ce2f97900e06910431323334"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals("Test Callback nbr", bd1.userData.payloadStr); - assertEquals(CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR, bd1.callbackNumber.digitMode); - assertEquals(CdmaSmsAddress.TON_INTERNATIONAL_OR_IP, bd1.callbackNumber.ton); - assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode); - assertEquals(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY, bd1.callbackNumber.numberPlan); - assertEquals("1234", bd1.callbackNumber.address); - } - - @SmallTest - public void testCallbackNumDtmf() throws Exception { - String pdu1 = "00031002300109104539b4d052ebb3d00e07052d4c90a55080"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals("SMS Rulz", bd1.userData.payloadStr); - assertEquals(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF, bd1.callbackNumber.digitMode); - assertEquals(CdmaSmsAddress.TON_UNKNOWN, bd1.callbackNumber.ton); - assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode); - assertEquals(CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN, bd1.callbackNumber.numberPlan); - assertEquals("5099214001", bd1.callbackNumber.address); - } - - @SmallTest - public void testCallbackNumFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test callback number"; - bearerData.userData = userData; - CdmaSmsAddress addr = new CdmaSmsAddress(); - addr.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR; - addr.ton = CdmaSmsAddress.TON_NATIONAL_OR_EMAIL; - addr.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK; - addr.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN; - addr.address = "8005551212"; - addr.numberOfDigits = (byte)addr.address.length(); - bearerData.callbackNumber = addr; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - CdmaSmsAddress revAddr = revBearerData.callbackNumber; - assertEquals(addr.digitMode, revAddr.digitMode); - assertEquals(addr.ton, revAddr.ton); - assertEquals(addr.numberMode, revAddr.numberMode); - assertEquals(addr.numberPlan, revAddr.numberPlan); - assertEquals(addr.numberOfDigits, revAddr.numberOfDigits); - assertEquals(addr.address, revAddr.address); - addr.address = "8*55#1012"; - addr.numberOfDigits = (byte)addr.address.length(); - addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - revAddr = revBearerData.callbackNumber; - assertEquals(addr.digitMode, revAddr.digitMode); - assertEquals(addr.numberOfDigits, revAddr.numberOfDigits); - assertEquals(addr.address, revAddr.address); - } - - @SmallTest - public void testPrivacyIndicator() throws Exception { - String pdu1 = "0003104090010c485f4194dfea34becf61b840090140"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.privacy, BearerData.PRIVACY_RESTRICTED); - String pdu2 = "0003104090010c485f4194dfea34becf61b840090180"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals(bd2.privacy, BearerData.PRIVACY_CONFIDENTIAL); - String pdu3 = "0003104090010c485f4194dfea34becf61b8400901c0"; - BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); - assertEquals(bd3.privacy, BearerData.PRIVACY_SECRET); - } - - @SmallTest - public void testPrivacyIndicatorFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test privacy indicator"; - bearerData.userData = userData; - bearerData.privacy = BearerData.PRIVACY_SECRET; - bearerData.privacyIndicatorSet = true; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.privacyIndicatorSet, true); - assertEquals(revBearerData.privacy, BearerData.PRIVACY_SECRET); - bearerData.privacy = BearerData.PRIVACY_RESTRICTED; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.privacy, BearerData.PRIVACY_RESTRICTED); - } - - @SmallTest - public void testMsgDeliveryAlert() throws Exception { - String pdu1 = "0003104090010d4866a794e07055965b91d040300c0100"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.alert, 0); - assertEquals(bd1.userData.payloadStr, "Test Alert 0"); - String pdu2 = "0003104090010d4866a794e07055965b91d140300c0140"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals(bd2.alert, 1); - assertEquals(bd2.userData.payloadStr, "Test Alert 1"); - String pdu3 = "0003104090010d4866a794e07055965b91d240300c0180"; - BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); - assertEquals(bd3.alert, 2); - assertEquals(bd3.userData.payloadStr, "Test Alert 2"); - String pdu4 = "0003104090010d4866a794e07055965b91d340300c01c0"; - BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); - assertEquals(bd4.alert, 3); - assertEquals(bd4.userData.payloadStr, "Test Alert 3"); - String pdu5 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" + - "69ED979794187665E5D1028EFA7A6840E1062D3D39A900C028000"; - BearerData bd5 = BearerData.decode(HexDump.hexStringToByteArray(pdu5)); - assertEquals(bd5.alert, BearerData.ALERT_MEDIUM_PRIO); - assertEquals(bd5.userData.payloadStr, "test message delivery alert (with 8 bits)"); - String pdu6 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" + - "69ED979794187665E5D1028EFA7A6840C1062D3D39A900C00"; - BearerData bd6 = BearerData.decode(HexDump.hexStringToByteArray(pdu6)); - assertEquals(bd6.userData.payloadStr, "test message delivery alert (with 0 bits)"); - assertEquals(bd6.alertIndicatorSet, false); - } - - @SmallTest - public void testMiscParams() throws Exception { - String pdu1 = "00031002400109104539b4d052ebb3d00c0180"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.alert, BearerData.ALERT_MEDIUM_PRIO); - assertEquals(bd1.userData.payloadStr, "SMS Rulz"); - String pdu2 = "00031002500109104539b4d052ebb3d00801800901c0"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals(bd2.priority, BearerData.PRIORITY_URGENT); - assertEquals(bd2.privacy, BearerData.PRIVACY_SECRET); - assertEquals(bd2.userData.payloadStr, "SMS Rulz"); - String pdu3 = "00031002600109104539b4d052ebb3d00901400c01c0"; - BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); - assertEquals(bd3.privacy, BearerData.PRIVACY_RESTRICTED); - assertEquals(bd3.alert, BearerData.ALERT_HIGH_PRIO); - assertEquals(bd3.userData.payloadStr, "SMS Rulz"); - String pdu4 = "00031002700109104539b4d052ebb3d00f0105"; - BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); - assertEquals(bd4.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE); - assertEquals(bd4.userData.payloadStr, "SMS Rulz"); - } - @SmallTest - public void testMsgDeliveryAlertFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test message delivery alert"; - bearerData.userData = userData; - bearerData.alert = BearerData.ALERT_MEDIUM_PRIO; - bearerData.alertIndicatorSet = true; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.alertIndicatorSet, true); - assertEquals(revBearerData.alert, bearerData.alert); - bearerData.alert = BearerData.ALERT_HIGH_PRIO; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.alertIndicatorSet, true); - assertEquals(revBearerData.alert, bearerData.alert); - } - - @SmallTest - public void testLanguageIndicator() throws Exception { - String pdu1 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0101"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.userData.payloadStr, "Test Language indicator"); - assertEquals(bd1.language, BearerData.LANGUAGE_ENGLISH); - String pdu2 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0106"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals(bd2.userData.payloadStr, "Test Language indicator"); - assertEquals(bd2.language, BearerData.LANGUAGE_CHINESE); - } - - @SmallTest - public void testLanguageIndicatorFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test language indicator"; - bearerData.userData = userData; - bearerData.language = BearerData.LANGUAGE_ENGLISH; - bearerData.languageIndicatorSet = true; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.languageIndicatorSet, true); - assertEquals(revBearerData.language, bearerData.language); - bearerData.language = BearerData.LANGUAGE_KOREAN; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.languageIndicatorSet, true); - assertEquals(revBearerData.language, bearerData.language); - } - - @SmallTest - public void testDisplayMode() throws Exception { - String pdu1 = "0003104090010c485f4194dfea34becf61b8400f0100"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE); - String pdu2 = "0003104090010c485f4194dfea34becf61b8400f0140"; - BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); - assertEquals(bd2.displayMode, BearerData.DISPLAY_MODE_DEFAULT); - String pdu3 = "0003104090010c485f4194dfea34becf61b8400f0180"; - BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); - assertEquals(bd3.displayMode, BearerData.DISPLAY_MODE_USER); - } - - @SmallTest - public void testDisplayModeFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test display mode"; - bearerData.userData = userData; - bearerData.displayMode = BearerData.DISPLAY_MODE_IMMEDIATE; - bearerData.displayModeSet = true; - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.displayModeSet, true); - assertEquals(revBearerData.displayMode, bearerData.displayMode); - bearerData.displayMode = BearerData.DISPLAY_MODE_USER; - encodedSms = BearerData.encode(bearerData); - revBearerData = BearerData.decode(encodedSms); - assertEquals(revBearerData.userData.payloadStr, userData.payloadStr); - assertEquals(revBearerData.displayModeSet, true); - assertEquals(revBearerData.displayMode, bearerData.displayMode); - } - - @SmallTest - public void testIs91() throws Exception { - String pdu1 = "000320001001070c2039acc13880"; - BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); - assertEquals(bd1.callbackNumber.address, "3598271"); - String pdu4 = "000320001001080c283c314724b34e"; - BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); - assertEquals(bd4.userData.payloadStr, "ABCDEFG"); - } - - @SmallTest - public void testUserDataHeaderWithEightCharMsg() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 55; - SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); - concatRef.refNumber = 0xEE; - concatRef.msgCount = 2; - concatRef.seqNumber = 2; - concatRef.isEightBits = true; - SmsHeader smsHeader = new SmsHeader(); - smsHeader.concatRef = concatRef; - UserData userData = new UserData(); - userData.payloadStr = "01234567"; - userData.userDataHeader = smsHeader; - bearerData.userData = userData; - byte[] encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); - } - - @SmallTest - public void testFragmentText() throws Exception { - boolean isCdmaPhone = (TelephonyManager.getDefault().getPhoneType() == - TelephonyManager.PHONE_TYPE_CDMA); - // Valid 160 character ASCII text. - String text1 = "123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901234567890123456789012345678901234567890" + - "12345678901234567890123456789["; - TextEncodingDetails ted = SmsMessage.calculateLength(text1, false); - assertEquals(ted.msgCount, 1); - assertEquals(ted.codeUnitCount, 160); - assertEquals(ted.codeUnitSize, 1); - if (isCdmaPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text1); - assertEquals(fragments.size(), 1); - } - - /* - This is not a valid test: we will never encode a single-segment - EMS message. Leaving this here, since we may try to support - this in the future. - - // Valid 160 character GSM text -- the last character is - // non-ASCII, and so this will currently generate a singleton - // EMS message, which is not necessarily supported by Verizon. - String text2 = "123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901234567890123456789012345678901234567890" + - "12345678901234567890123456789\u00a3"; // Trailing pound-currency sign. - ted = SmsMessage.calculateLength(text2, false); - assertEquals(ted.msgCount, 1); - assertEquals(ted.codeUnitCount, 160); - assertEquals(ted.codeUnitSize, 1); - if (isCdmaPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text2); - assertEquals(fragments.size(), 1); - } - */ - - // *IF* we supported single-segment EMS, this text would result in a - // single fragment with 7-bit encoding. But we don't, so this text - // results in three fragments of 16-bit encoding. - String text2 = "123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789012345678901234567890123456789012345678901234567890" + - "12345678901234567890123456789\u00a3"; // Trailing pound-currency sign. - ted = SmsMessage.calculateLength(text2, false); - assertEquals(3, ted.msgCount); - assertEquals(160, ted.codeUnitCount); - assertEquals(3, ted.codeUnitSize); - if (isCdmaPhone) { - ArrayList fragments = android.telephony.SmsMessage.fragmentText(text2); - assertEquals(3, fragments.size()); - } - - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java deleted file mode 100644 index 485542b2aa86..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java +++ /dev/null @@ -1,1932 +0,0 @@ -/* - * 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 GSMTestHandler.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.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.telephony.ServiceState; -import android.test.AndroidTestCase; -import android.test.PerformanceTestCase; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.MmiCode; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.gsm.CallFailCause; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.gsm.GSMTestHandler; -import com.android.internal.telephony.gsm.GsmMmiCode; -import com.android.internal.telephony.gsm.SuppServiceNotification; -import com.android.internal.telephony.test.SimulatedRadioControl; - -import java.util.List; - - -public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase { - private SimulatedRadioControl mRadioControl; - private GSMPhone mGSMPhone; - private GSMTestHandler mGSMTestHandler; - private Handler mHandler; - - private static final int EVENT_PHONE_STATE_CHANGED = 1; - private static final int EVENT_DISCONNECT = 2; - private static final int EVENT_RINGING = 3; - private static final int EVENT_CHANNEL_OPENED = 4; - private static final int EVENT_POST_DIAL = 5; - private static final int EVENT_DONE = 6; - private static final int EVENT_SSN = 7; - private static final int EVENT_MMI_INITIATE = 8; - private static final int EVENT_MMI_COMPLETE = 9; - private static final int EVENT_IN_SERVICE = 10; - private static final int SUPP_SERVICE_FAILED = 11; - private static final int SERVICE_STATE_CHANGED = 12; - private static final int EVENT_OEM_RIL_MESSAGE = 13; - public static final int ANY_MESSAGE = -1; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mGSMTestHandler = new GSMTestHandler(mContext); - - mGSMTestHandler.start(); - synchronized (mGSMTestHandler) { - do { - mGSMTestHandler.wait(); - } while (mGSMTestHandler.getGSMPhone() == null); - } - - mGSMPhone = mGSMTestHandler.getGSMPhone(); - mRadioControl = mGSMTestHandler.getSimulatedCommands(); - - mHandler = mGSMTestHandler.getHandler(); - mGSMPhone.registerForPreciseCallStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null); - mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null); - mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null); - - mGSMPhone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL, null); - - mGSMPhone.registerForSuppServiceNotification(mHandler, EVENT_SSN, null); - mGSMPhone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null); - mGSMPhone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null); - mGSMPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null); - - mGSMPhone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null); - - // wait until we get phone in both voice and data service - Message msg; - ServiceState state; - - do { - msg = mGSMTestHandler.waitForMessage(SERVICE_STATE_CHANGED); - assertNotNull("Message Time Out", msg); - state = (ServiceState) ((AsyncResult) msg.obj).result; - } while (state.getState() != ServiceState.STATE_IN_SERVICE); - } - - @Override - protected void tearDown() throws Exception { - mRadioControl.shutdown(); - - mGSMPhone.unregisterForPreciseCallStateChanged(mHandler); - mGSMPhone.unregisterForNewRingingConnection(mHandler); - mGSMPhone.unregisterForDisconnect(mHandler); - mGSMPhone.setOnPostDialCharacter(mHandler, 0, null); - mGSMPhone.unregisterForSuppServiceNotification(mHandler); - mGSMPhone.unregisterForMmiInitiate(mHandler); - mGSMPhone.unregisterForMmiComplete(mHandler); - - mGSMPhone = null; - mRadioControl = null; - mHandler = null; - mGSMTestHandler.cleanup(); - - super.tearDown(); - } - - // These test can only be run once. - public int startPerformance(Intermediates intermediates) { - return 1; - } - - public boolean isPerformanceOnly() { - return false; - } - - - //This test is causing the emulator screen to turn off. I don't understand - //why, but I'm removing it until we can figure it out. - public void brokenTestGeneral() throws Exception { - Connection cn; - Message msg; - AsyncResult ar; - - // IDLE state - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - assertFalse(mGSMPhone.canConference()); - - // One DIALING connection - - mRadioControl.setAutoProgressConnectingCall(false); - - mGSMPhone.dial("+13125551212"); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - - msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertEquals(Call.State.DIALING, mGSMPhone.getForegroundCall().getState()); - assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - /*do { - mGSMTestHandler.waitForMessage(ANY_MESSAGE); - } while (mGSMPhone.getForegroundCall().getConnections().size() == 0);*/ - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DIALING, - mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - cn = mGSMPhone.getForegroundCall().getConnections().get(0); - assertTrue(!cn.isIncoming()); - assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState()); - - assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause()); - - assertFalse(mGSMPhone.canConference()); - - // One ALERTING connection - - mRadioControl.progressConnectingCallState(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } - while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ALERTING, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - cn = mGSMPhone.getForegroundCall().getConnections().get(0); - assertTrue(!cn.isIncoming()); - assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState()); - assertFalse(mGSMPhone.canConference()); - - // One ACTIVE connection - - mRadioControl.progressConnectingCallState(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0); - - cn = mGSMPhone.getForegroundCall().getConnections().get(0); - assertTrue(!cn.isIncoming()); - assertEquals(Connection.PostDialState.COMPLETE, cn.getPostDialState()); - assertFalse(mGSMPhone.canConference()); - - // One disconnected connection - mGSMPhone.getForegroundCall().hangup(); - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0); - - assertFalse(mGSMPhone.canConference()); - - cn = mGSMPhone.getForegroundCall().getEarliestConnection(); - - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - // Back to idle state - - mGSMPhone.clearDisconnected(); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - assertFalse(mGSMPhone.canConference()); - - // cn left over from before phone.clearDisconnected(); - - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - // One ringing (INCOMING) call - - mRadioControl.triggerRing("18005551212"); - - msg = mGSMTestHandler.waitForMessage(EVENT_RINGING); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - ar = (AsyncResult) msg.obj; - cn = (Connection) ar.result; - assertTrue(cn.isRinging()); - assertEquals(mGSMPhone.getRingingCall(), cn.getCall()); - - assertEquals(1, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - cn = mGSMPhone.getRingingCall().getConnections().get(0); - assertTrue(cn.isIncoming()); - assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState()); - - assertFalse(mGSMPhone.canConference()); - - // One mobile terminated active call - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getConnections().size() == 1); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, - mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0); - - cn = mGSMPhone.getForegroundCall().getConnections().get(0); - assertTrue(cn.isIncoming()); - assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState()); - - assertFalse(mGSMPhone.canConference()); - - // One disconnected (local hangup) call - - try { - Connection conn; - conn = mGSMPhone.getForegroundCall().getConnections().get(0); - conn.hangup(); - } catch (CallStateException ex) { - ex.printStackTrace(); - fail("unexpected ex"); - } - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, - mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0); - - cn = mGSMPhone.getForegroundCall().getEarliestConnection(); - - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause()); - - assertFalse(mGSMPhone.canConference()); - - // Back to idle state - - mGSMPhone.clearDisconnected(); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - assertFalse(mGSMPhone.canConference()); - - // cn left over from before phone.clearDisconnected(); - - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - // One ringing call - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getConnections().isEmpty()); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(1, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - assertFalse(mGSMPhone.canConference()); - - // One rejected call - mGSMPhone.rejectCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.IDLE); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(1, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - cn = mGSMPhone.getRingingCall().getEarliestConnection(); - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause()); - - assertFalse(mGSMPhone.canConference()); - - // Back to idle state - - mGSMPhone.clearDisconnected(); - - assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime()); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - assertFalse(mGSMPhone.canConference()); - assertEquals(Call.State.DISCONNECTED, cn.getState()); - - // One ringing call - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getConnections().isEmpty()); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - cn = mGSMPhone.getRingingCall().getEarliestConnection(); - - // Ringing call disconnects - - mRadioControl.triggerHangupForeground(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.IDLE); - - assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause()); - - // One Ringing Call - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.RINGING); - - - cn = mGSMPhone.getRingingCall().getEarliestConnection(); - - // One answered call - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // one holding call - mGSMPhone.switchHoldingAndActive(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE); - - - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // one active call - mGSMPhone.switchHoldingAndActive(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } - while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // One disconnected call in the foreground slot - - mRadioControl.triggerHangupAll(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.IDLE); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause()); - - // Test missed calls - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.RINGING); - - mGSMPhone.rejectCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (msg.what != EVENT_DISCONNECT); - - ar = (AsyncResult) msg.obj; - cn = (Connection) ar.result; - - assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause()); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState()); - - // Test incoming not missed calls - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.RINGING); - - cn = mGSMPhone.getRingingCall().getEarliestConnection(); - - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause()); - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - - try { - mGSMPhone.getForegroundCall().hangup(); - } catch (CallStateException ex) { - ex.printStackTrace(); - fail("unexpected ex"); - } - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() - != Call.State.DISCONNECTED); - - assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause()); - - // - // Test held and hangup held calls - // - - // One ALERTING call - mGSMPhone.dial("+13125551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - mRadioControl.progressConnectingCallState(); - mRadioControl.progressConnectingCallState(); - - // One ACTIVE call - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - // One ACTIVE call, one ringing call - - mRadioControl.triggerRing("18005551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.RINGING); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - // One HOLDING call, one ACTIVE call - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertTrue(mGSMPhone.canConference()); - - // Conference the two - mGSMPhone.conference(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertTrue(mGSMPhone.getForegroundCall().isMultiparty()); - assertFalse(mGSMPhone.canConference()); - - // Hold the multiparty call - mGSMPhone.switchHoldingAndActive(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } - while (mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertTrue(mGSMPhone.getBackgroundCall().isMultiparty()); - assertFalse(mGSMPhone.canConference()); - - // Multiparty call on hold, call waiting added - - mRadioControl.triggerRing("18005558355"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.RINGING); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertTrue(mGSMPhone.getBackgroundCall().isMultiparty()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertFalse(mGSMPhone.canConference()); - - // Hangup conference call, ringing call still around - mGSMPhone.getBackgroundCall().hangup(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.DISCONNECTED); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState()); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - - // Reject waiting call - mGSMPhone.rejectCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.IDLE); - - assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - } - - public void testOutgoingCallFailImmediately() throws Exception { - Message msg; - - // Test outgoing call fail-immediately edge case - // This happens when a call terminated before ever appearing in a - // call list - // This should land the immediately-failing call in the - // ForegroundCall list as an IDLE call - mRadioControl.setNextDialFailImmediately(true); - - Connection cn = mGSMPhone.dial("+13125551212"); - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - } - - public void testHangupOnOutgoing() throws Exception { - Connection cn; - Message msg; - - mRadioControl.setAutoProgressConnectingCall(false); - - // Test 1: local hangup in "DIALING" state - mGSMPhone.dial("+13125551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } - while (mGSMPhone.getForegroundCall().getState() != Call.State.DIALING); - - cn = mGSMPhone.getForegroundCall().getEarliestConnection(); - - mGSMPhone.getForegroundCall().hangup(); - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause()); - - // Test 2: local hangup in "ALERTING" state - mGSMPhone.dial("+13125551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - mRadioControl.progressConnectingCallState(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } - while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING); - - cn = mGSMPhone.getForegroundCall().getEarliestConnection(); - - mGSMPhone.getForegroundCall().hangup(); - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause()); - - // Test 3: local immediate hangup before GSM index is - // assigned (CallTracker.hangupPendingMO case) - - mRadioControl.pauseResponses(); - - cn = mGSMPhone.dial("+13125551212"); - - cn.hangup(); - - mRadioControl.resumeResponses(); - - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - - assertEquals(Connection.DisconnectCause.LOCAL, - mGSMPhone.getForegroundCall().getEarliestConnection().getDisconnectCause()); - } - - public void testHangupOnChannelClose() throws Exception { - mGSMPhone.dial("+13125551212"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getConnections().isEmpty()); - - mRadioControl.shutdown(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - mGSMPhone.clearDisconnected(); - } while (!mGSMPhone.getForegroundCall().getConnections().isEmpty()); - } - - public void testIncallMmiCallDeflection() throws Exception { - Message msg; - - // establish an active call - mGSMPhone.dial("+13125551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // establish a ringing (WAITING) call - - mRadioControl.triggerRing("18005551212"); - - msg = mGSMTestHandler.waitForMessage(EVENT_RINGING); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering 0 followed by SEND: release all held calls - // or sets UDUB for a waiting call. - mGSMPhone.handleInCallMmiCommands("0"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // change the active call to holding call - mGSMPhone.switchHoldingAndActive(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE); - - - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering 0 followed by SEND: release all held calls - // or sets UDUB for a waiting call. - mGSMPhone.handleInCallMmiCommands("0"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState()); - } - - public void testIncallMmiCallWaiting() throws Exception { - Message msg; - - // establish an active call - mGSMPhone.dial("+13125551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // establish a ringing (WAITING) call - - mRadioControl.triggerRing("18005551212"); - - do { - msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE); - assertNotNull("Message Time Out", msg); - } while (msg.what != EVENT_RINGING); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering 1 followed by SEND: release all active calls - // (if any exist) and accepts the other (held or waiting) call. - - mGSMPhone.handleInCallMmiCommands("1"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - - // change the active call to holding call - mGSMPhone.switchHoldingAndActive(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE); - - assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering 1 followed by SEND: release all active calls - // (if any exist) and accepts the other (held or waiting) call. - mGSMPhone.handleInCallMmiCommands("1"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - - // at this point, the active call with number==18005551212 should - // have the gsm index of 2 - - mRadioControl.triggerRing("16505550100"); - - msg = mGSMTestHandler.waitForMessage(EVENT_RINGING); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering "12" followed by SEND: release the call with - // gsm index equals to 2. - mGSMPhone.handleInCallMmiCommands("12"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getState() != Phone.State.OFFHOOK); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertFalse(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // at this point, the call with number==16505550100 should - // have the gsm index of 1 - mGSMPhone.dial("+13125551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE || - mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // at this point, the active call with number==13125551212 should - // have the gsm index of 2 - - // Simulate entering "11" followed by SEND: release the call with - // gsm index equals to 1. This should not be allowed, and a - // Supplementary Service notification must be received. - mGSMPhone.handleInCallMmiCommands("11"); - - msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED); - assertNotNull("Message Time Out", msg); - assertFalse("IncallMmiCallWaiting: command should not work on holding call", msg == null); - - // Simulate entering "12" followed by SEND: release the call with - // gsm index equals to 2. - mGSMPhone.handleInCallMmiCommands("12"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // Simulate entering 1 followed by SEND: release all active calls - // (if any exist) and accepts the other (held or waiting) call. - mGSMPhone.handleInCallMmiCommands("1"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - assertEquals("16505550100", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - - // Simulate entering "11" followed by SEND: release the call with - // gsm index equals to 1. - mGSMPhone.handleInCallMmiCommands("11"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - } - - public void testIncallMmiCallHold() throws Exception { - Message msg; - - // establish an active call - mGSMPhone.dial("13125551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // establish a ringing (WAITING) call - - mRadioControl.triggerRing("18005551212"); - - msg = mGSMTestHandler.waitForMessage(EVENT_RINGING); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // simulate entering 2 followed by SEND: place all active calls - // (if any exist) on hold and accepts the other (held or waiting) - // call - - mGSMPhone.handleInCallMmiCommands("2"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING); - - - assertFalse(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, - mGSMPhone.getForegroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertEquals("13125551212", - mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress()); - - // swap the active and holding calls - mGSMPhone.handleInCallMmiCommands("2"); - - msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED); - assertNotNull("Message Time Out", msg); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("13125551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress()); - - // merge the calls - mGSMPhone.conference(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - assertEquals(2, mGSMPhone.getForegroundCall().getConnections().size()); - - // at this point, we have an active conference call, with - // call(1) = 13125551212 and call(2) = 18005551212 - - // Simulate entering "23" followed by SEND: places all active call - // on hold except call 3. This should fail and a supplementary service - // failed notification should be received. - - mGSMPhone.handleInCallMmiCommands("23"); - - msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED); - assertNotNull("Message Time Out", msg); - assertFalse("IncallMmiCallHold: separate should have failed!", msg == null); - - // Simulate entering "21" followed by SEND: places all active call - // on hold except call 1. - mGSMPhone.handleInCallMmiCommands("21"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("13125551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress()); - } - - public void testIncallMmiMultipartyServices() throws Exception { - // establish an active call - mGSMPhone.dial("13125551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - // dial another call - mGSMPhone.dial("18005551212"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - mGSMPhone.handleInCallMmiCommands("3"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals("13125551212", - mGSMPhone.getForegroundCall().getConnections().get(1).getAddress()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - } - - public void testCallIndex() throws Exception { - Message msg; - - // establish the first call - mGSMPhone.dial("16505550100"); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - String baseNumber = "1650555010"; - - for (int i = 1; i < 6; i++) { - String number = baseNumber + i; - - mGSMPhone.dial(number); - - do { - mRadioControl.progressConnectingCallState(); - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - if (mGSMPhone.getBackgroundCall().getConnections().size() >= 5) { - break; - } - - mGSMPhone.conference(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - } - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("16505550105", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // create an incoming call, this call should have the call index - // of 7 - mRadioControl.triggerRing("18005551212"); - - msg = mGSMTestHandler.waitForMessage(EVENT_RINGING); - assertNotNull("Message Time Out", msg); - - assertEquals(Phone.State.RINGING, mGSMPhone.getState()); - assertTrue(mGSMPhone.getRingingCall().isRinging()); - assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - - // hangup the background call and accept the ringing call - mGSMPhone.getBackgroundCall().hangup(); - mGSMPhone.acceptCall(); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getRingingCall().getState() != Call.State.IDLE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals("18005551212", - mGSMPhone.getForegroundCall().getConnections().get(0).getAddress()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertEquals("16505550105", - mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress()); - - mGSMPhone.handleInCallMmiCommands("17"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState()); - assertEquals("16505550105", - mGSMPhone.getBackgroundCall().getConnections().get(0). - getAddress()); - - mGSMPhone.handleInCallMmiCommands("1"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE); - - assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - mGSMPhone.handleInCallMmiCommands("16"); - - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE); - - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - } - - public void testPostDialSequences() throws Exception { - Message msg; - AsyncResult ar; - Connection cn; - - mGSMPhone.dial("+13125551212,1234;5N8xx"); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(',', msg.arg1); - assertEquals("1234;5N8", cn.getRemainingPostDialString()); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('1', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('2', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('3', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('4', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals(';', msg.arg1); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState()); - assertEquals(Connection.PostDialState.WAIT, ar.userObj); - cn.proceedAfterWaitChar(); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('5', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertEquals('N', msg.arg1); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(Connection.PostDialState.WILD, cn.getPostDialState()); - assertEquals(Connection.PostDialState.WILD, ar.userObj); - cn.proceedAfterWildChar(",6;7"); - - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(',', msg.arg1); - assertEquals("6;78", cn.getRemainingPostDialString()); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('6', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals(';', msg.arg1); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState()); - assertEquals(Connection.PostDialState.WAIT, ar.userObj); - cn.proceedAfterWaitChar(); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('7', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals('8', msg.arg1); - ar = (AsyncResult) (msg.obj); - assertEquals(Connection.PostDialState.STARTED, ar.userObj); - - // Bogus chars at end should be ignored - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals(0, msg.arg1); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(Connection.PostDialState.COMPLETE, - cn.getPostDialState()); - assertEquals(Connection.PostDialState.COMPLETE, ar.userObj); - } - - public void testPostDialCancel() throws Exception { - Message msg; - AsyncResult ar; - Connection cn; - - mGSMPhone.dial("+13125551212,N"); - mRadioControl.progressConnectingToActive(); - - mRadioControl.progressConnectingToActive(); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertNotNull("Message Time Out", msg); - assertEquals(',', msg.arg1); - - msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL); - assertEquals('N', msg.arg1); - ar = (AsyncResult) (msg.obj); - cn = (Connection) (ar.result); - assertEquals(Connection.PostDialState.WILD, cn.getPostDialState()); - cn.cancelPostDial(); - - assertEquals(Connection.PostDialState.CANCELLED, cn.getPostDialState()); - } - - public void testOutgoingCallFail() throws Exception { - Message msg; - /* - * normal clearing - */ - - mRadioControl.setNextCallFailCause(CallFailCause.NORMAL_CLEARING); - mRadioControl.setAutoProgressConnectingCall(false); - - Connection cn = mGSMPhone.dial("+13125551212"); - - mRadioControl.progressConnectingCallState(); - - // I'm just progressing the call state to - // ensure getCurrentCalls() gets processed... - // Normally these failure conditions would happen in DIALING - // not ALERTING - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (cn.getState() == Call.State.DIALING); - - - mRadioControl.triggerHangupAll(); - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - /* - * busy - */ - - mRadioControl.setNextCallFailCause(CallFailCause.USER_BUSY); - mRadioControl.setAutoProgressConnectingCall(false); - - cn = mGSMPhone.dial("+13125551212"); - - mRadioControl.progressConnectingCallState(); - - // I'm just progressing the call state to - // ensure getCurrentCalls() gets processed... - // Normally these failure conditions would happen in DIALING - // not ALERTING - do { - assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE)); - } while (cn.getState() == Call.State.DIALING); - - - mRadioControl.triggerHangupAll(); - msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT); - assertNotNull("Message Time Out", msg); - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Connection.DisconnectCause.BUSY, cn.getDisconnectCause()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, - mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - - /* - * congestion - */ - - mRadioControl.setNextCallFailCause(CallFailCause.NO_CIRCUIT_AVAIL); - mRadioControl.setAutoProgressConnectingCall(false); - - cn = mGSMPhone.dial("+13125551212"); - - mRadioControl.progressConnectingCallState(); - - // I'm just progressing the call state to - // ensure getCurrentCalls() gets processed... - // Normally these failure conditions would happen in DIALING - // not ALERTING - do { - msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE); - assertNotNull("Message Time Out", msg); - } while (cn.getState() == Call.State.DIALING); - - - mRadioControl.triggerHangupAll(); - - // Unlike the while loops above, this one waits - // for a "phone state changed" message back to "idle" - do { - msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE); - assertNotNull("Message Time Out", msg); - } while (!(msg.what == EVENT_PHONE_STATE_CHANGED - && mGSMPhone.getState() == Phone.State.IDLE)); - - assertEquals(Phone.State.IDLE, mGSMPhone.getState()); - - assertEquals(Connection.DisconnectCause.CONGESTION, cn.getDisconnectCause()); - - assertEquals(0, mGSMPhone.getRingingCall().getConnections().size()); - assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size()); - assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size()); - - assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState()); - assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState()); - assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState()); - - assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0); - assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime()); - } - - public void testSSNotification() throws Exception { - // MO - runTest(0, SuppServiceNotification.MO_CODE_UNCONDITIONAL_CF_ACTIVE); - runTest(0, SuppServiceNotification.MO_CODE_CALL_IS_WAITING); - runTest(0, SuppServiceNotification.MO_CODE_CALL_DEFLECTED); - - // MT - runTest(1, SuppServiceNotification.MT_CODE_FORWARDED_CALL); - runTest(1, SuppServiceNotification.MT_CODE_CALL_CONNECTED_ECT); - runTest(1, SuppServiceNotification.MT_CODE_ADDITIONAL_CALL_FORWARDED); - } - - private void runTest(int type, int code) { - Message msg; - - mRadioControl.triggerSsn(type, code); - - msg = mGSMTestHandler.waitForMessage(EVENT_SSN); - assertNotNull("Message Time Out", msg); - AsyncResult ar = (AsyncResult) msg.obj; - - assertNull(ar.exception); - - SuppServiceNotification notification = - (SuppServiceNotification) ar.result; - - assertEquals(type, notification.notificationType); - assertEquals(code, notification.code); - } - - public void testUssd() throws Exception { - // Quick hack to work around a race condition in this test: - // We may initiate a USSD MMI before GSMPhone receives its initial - // GSMTestHandler.EVENT_RADIO_OFF_OR_NOT_AVAILABLE event. When the phone sees this - // event, it will cancel the just issued USSD MMI, which we don't - // want. So sleep a little first. - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - // do nothing - } - - verifyNormal(); - verifyCancel(); - varifyNetworkInitiated(); - } - - private void varifyNetworkInitiated() { - Message msg; - AsyncResult ar; - MmiCode mmi; - - // Receive an incoming NOTIFY - mRadioControl.triggerIncomingUssd("0", "NOTIFY message"); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertFalse(mmi.isUssdRequest()); - - // Receive a REQUEST and send response - mRadioControl.triggerIncomingUssd("1", "REQUEST Message"); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertTrue(mmi.isUssdRequest()); - - mGSMPhone.sendUssdResponse("## TEST: TEST_GSMPhone responding..."); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - GsmMmiCode gsmMmi = (GsmMmiCode) mmi; - assertTrue(gsmMmi.isPendingUSSD()); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertNull(ar.exception); - assertFalse(mmi.isUssdRequest()); - - // Receive a REQUEST and cancel - mRadioControl.triggerIncomingUssd("1", "REQUEST Message"); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertTrue(mmi.isUssdRequest()); - - mmi.cancel(); - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertNull(ar.exception); - assertEquals(MmiCode.State.CANCELLED, mmi.getState()); - - List mmiList = mGSMPhone.getPendingMmiCodes(); - assertEquals(0, mmiList.size()); - } - - private void verifyNormal() throws CallStateException { - Message msg; - AsyncResult ar; - MmiCode mmi; - - mGSMPhone.dial("#646#"); - - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE); - assertNotNull("Message Time Out", msg); - - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - - ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - assertEquals(MmiCode.State.COMPLETE, mmi.getState()); - } - - - private void verifyCancel() throws CallStateException { - /** - * This case makes an assumption that dial() will add the USSD - * to the "pending MMI codes" list before it returns. This seems - * like reasonable semantics. It also assumes that the USSD - * request in question won't complete until we get back to the - * event loop, thus cancel() is safe. - */ - Message msg; - - mGSMPhone.dial("#646#"); - - List pendingMmis = mGSMPhone.getPendingMmiCodes(); - - assertEquals(1, pendingMmis.size()); - - MmiCode mmi = pendingMmis.get(0); - assertTrue(mmi.isCancelable()); - mmi.cancel(); - - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE); - assertNotNull("Message Time Out", msg); - - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - - AsyncResult ar = (AsyncResult) msg.obj; - mmi = (MmiCode) ar.result; - - assertEquals(MmiCode.State.CANCELLED, mmi.getState()); - } - - public void testRilHooks() throws Exception { - // - // These test cases all assume the RIL OEM hooks - // just echo back their input - // - - Message msg; - AsyncResult ar; - - // null byte array - - mGSMPhone.invokeOemRilRequestRaw(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertNull(ar.result); - assertNull(ar.exception); - - // empty byte array - - mGSMPhone.invokeOemRilRequestRaw(new byte[0], mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertEquals(0, ((byte[]) (ar.result)).length); - assertNull(ar.exception); - - // byte array with data - - mGSMPhone.invokeOemRilRequestRaw("Hello".getBytes("utf-8"), - mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertEquals("Hello", new String(((byte[]) (ar.result)), "utf-8")); - assertNull(ar.exception); - - // null strings - - mGSMPhone.invokeOemRilRequestStrings(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertNull(ar.result); - assertNull(ar.exception); - - // empty byte array - - mGSMPhone.invokeOemRilRequestStrings(new String[0], - mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertEquals(0, ((String[]) (ar.result)).length); - assertNull(ar.exception); - - // Strings with data - - String s[] = new String[1]; - - s[0] = "Hello"; - - mGSMPhone.invokeOemRilRequestStrings(s, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE)); - - msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE); - assertNotNull("Message Time Out", msg); - - ar = ((AsyncResult) msg.obj); - - assertEquals("Hello", ((String[]) (ar.result))[0]); - assertEquals(1, ((String[]) (ar.result)).length); - assertNull(ar.exception); - } - - public void testMmi() throws Exception { - mRadioControl.setAutoProgressConnectingCall(false); - - // "valid" MMI sequences - runValidMmi("*#67#", false); - runValidMmi("##43*11#", false); - runValidMmi("#33*1234*11#", false); - runValidMmi("*21*6505551234**5#", false); - runValidMmi("**03**1234*4321*4321#", false); - // pound string - runValidMmi("5308234092307540923#", true); - // short code - runValidMmi("22", true); - // as part of call setup - runValidMmiWithConnect("*31#6505551234"); - - // invalid MMI sequences - runNotMmi("6505551234"); - runNotMmi("1234#*12#34566654"); - runNotMmi("*#*#12#*"); - } - - private void runValidMmi(String dialString, boolean cancelable) throws CallStateException { - Connection c = mGSMPhone.dial(dialString); - assertNull(c); - Message msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE); - assertNotNull("Message Time Out", msg); - // Should not be cancelable. - AsyncResult ar = (AsyncResult) msg.obj; - MmiCode mmi = (MmiCode) ar.result; - assertEquals(cancelable, mmi.isCancelable()); - - msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE); - assertNotNull("Message Time Out", msg); - } - - private void runValidMmiWithConnect(String dialString) throws CallStateException { - mRadioControl.pauseResponses(); - - Connection c = mGSMPhone.dial(dialString); - assertNotNull(c); - - hangup(c); - } - - private void hangup(Connection cn) throws CallStateException { - cn.hangup(); - - mRadioControl.resumeResponses(); - assertNotNull(mGSMTestHandler.waitForMessage(EVENT_DISCONNECT)); - - } - - private void runNotMmi(String dialString) throws CallStateException { - mRadioControl.pauseResponses(); - - Connection c = mGSMPhone.dial(dialString); - assertNotNull(c); - - hangup(c); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java deleted file mode 100644 index fb8a5d9eb936..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.content.Context; - -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.test.SimulatedCommands; -import com.android.internal.telephony.TestPhoneNotifier; - -/** - * This class creates a HandlerThread which waits for the various messages. - */ -public class GSMTestHandler extends HandlerThread implements Handler.Callback { - - private Handler mHandler; - private Message mCurrentMessage; - - private Boolean mMsgConsumed; - private SimulatedCommands sc; - private GSMPhone mGSMPhone; - private Context mContext; - - private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000; - - public GSMTestHandler(Context context) { - super("GSMPhoneTest"); - mMsgConsumed = false; - mContext = context; - } - - @Override - protected void onLooperPrepared() { - sc = new SimulatedCommands(); - mGSMPhone = new GSMPhone(mContext, sc, new TestPhoneNotifier(), true); - mHandler = new Handler(getLooper(), this); - synchronized (this) { - notifyAll(); - } - } - - public boolean handleMessage(Message msg) { - synchronized (this) { - mCurrentMessage = msg; - this.notifyAll(); - while(!mMsgConsumed) { - try { - this.wait(); - } catch (InterruptedException e) {} - } - mMsgConsumed = false; - } - return true; - } - - - public void cleanup() { - Looper looper = getLooper(); - if (looper != null) looper.quit(); - mHandler = null; - } - - public Handler getHandler() { - return mHandler; - } - - public SimulatedCommands getSimulatedCommands() { - return sc; - } - - public GSMPhone getGSMPhone() { - return mGSMPhone; - } - - public Message waitForMessage(int code) { - Message msg; - while(true) { - msg = null; - synchronized (this) { - try { - this.wait(FAIL_TIMEOUT_MILLIS); - } catch (InterruptedException e) { - } - - // Check if timeout has occurred. - if (mCurrentMessage != null) { - // Consume the message - msg = Message.obtain(); - msg.copyFrom(mCurrentMessage); - mCurrentMessage = null; - mMsgConsumed = true; - this.notifyAll(); - } - } - if (msg == null || code == GSMPhoneTest.ANY_MESSAGE || msg.what == code) return msg; - } - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java deleted file mode 100644 index 82c6944e13f6..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java +++ /dev/null @@ -1,758 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.gsm; - -import android.telephony.SmsCbEtwsInfo; -import android.telephony.SmsCbLocation; -import android.telephony.SmsCbMessage; -import android.test.AndroidTestCase; -import android.util.Log; - -import com.android.internal.telephony.IccUtils; - -import java.util.Random; - -/** - * Test cases for basic SmsCbMessage operations - */ -public class GsmSmsCbTest extends AndroidTestCase { - - private static final String TAG = "GsmSmsCbTest"; - - private static final SmsCbLocation sTestLocation = new SmsCbLocation("94040", 1234, 5678); - - private static SmsCbMessage createFromPdu(byte[] pdu) { - try { - SmsCbHeader header = new SmsCbHeader(pdu); - byte[][] pdus = new byte[1][]; - pdus[0] = pdu; - return GsmSmsCbMessage.createSmsCbMessage(header, sTestLocation, pdus); - } catch (IllegalArgumentException e) { - return null; - } - } - - private static void doTestGeographicalScopeValue(byte[] pdu, byte b, int expectedGs) { - pdu[0] = b; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected geographical scope decoded", expectedGs, msg - .getGeographicalScope()); - } - - public void testCreateNullPdu() { - SmsCbMessage msg = createFromPdu(null); - assertNull("createFromPdu(byte[] with null pdu should return null", msg); - } - - public void testCreateTooShortPdu() { - byte[] pdu = new byte[4]; - SmsCbMessage msg = createFromPdu(pdu); - - assertNull("createFromPdu(byte[] with too short pdu should return null", msg); - } - - public void testGetGeographicalScope() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - - doTestGeographicalScopeValue(pdu, (byte)0x00, - SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE); - doTestGeographicalScopeValue(pdu, (byte)0x40, SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE); - doTestGeographicalScopeValue(pdu, (byte)0x80, SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE); - doTestGeographicalScopeValue(pdu, (byte)0xC0, SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE); - } - - public void testGetGeographicalScopeUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A, - (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, - (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, - (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x34 - }; - - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected geographical scope decoded", - SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE, msg.getGeographicalScope()); - } - - public void testGetMessageBody7Bit() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A GSM default alphabet message with carriage return padding", - msg.getMessageBody()); - } - - public void testGetMessageBody7BitUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A, - (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, - (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, - (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x34 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A GSM default alphabet message with carriage return padding", - msg.getMessageBody()); - } - - public void testGetMessageBody7BitMultipageUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x01, (byte)0xC0, (byte)0x00, (byte)0x40, - - (byte)0x02, - - (byte)0xC6, (byte)0xB4, (byte)0x7C, (byte)0x4E, (byte)0x07, (byte)0xC1, - (byte)0xC3, (byte)0xE7, (byte)0xF2, (byte)0xAA, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, - (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, - (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x0A, - - (byte)0xD3, (byte)0xF2, (byte)0xF8, (byte)0xED, (byte)0x26, (byte)0x83, - (byte)0xE0, (byte)0xE1, (byte)0x73, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, - (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, - (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x0A - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected multipage 7-bit string decoded", - "First page+Second page", - msg.getMessageBody()); - } - - public void testGetMessageBody7BitFull() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5, - (byte)0xB4, (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63, - (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40, (byte)0x63, - (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3, (byte)0xCB, (byte)0xF2, - (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76, (byte)0x9F, (byte)0x59, (byte)0xA0, - (byte)0x76, (byte)0x39, (byte)0xEC, (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20, - (byte)0x3A, (byte)0xBA, (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73, - (byte)0x90, (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4, - (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals( - "Unexpected 7-bit string decoded", - "A GSM default alphabet message being exactly 93 characters long, " + - "meaning there is no padding!", - msg.getMessageBody()); - } - - public void testGetMessageBody7BitFullUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5, (byte)0xB4, - (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63, - (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40, - (byte)0x63, (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3, - (byte)0xCB, (byte)0xF2, (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76, - (byte)0x9F, (byte)0x59, (byte)0xA0, (byte)0x76, (byte)0x39, (byte)0xEC, - (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20, (byte)0x3A, (byte)0xBA, - (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73, (byte)0x90, - (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4, - (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02, - - (byte)0x52 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals( - "Unexpected 7-bit string decoded", - "A GSM default alphabet message being exactly 93 characters long, " + - "meaning there is no padding!", - msg.getMessageBody()); - } - - public void testGetMessageBody7BitWithLanguage() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x04, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A GSM default alphabet message with carriage return padding", - msg.getMessageBody()); - - assertEquals("Unexpected language indicator decoded", "es", msg.getLanguageCode()); - } - - public void testGetMessageBody7BitWithLanguageInBody() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x10, (byte)0x11, (byte)0x73, - (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E, (byte)0x9B, (byte)0x20, - (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE, (byte)0xB3, (byte)0xE9, (byte)0xA0, - (byte)0x30, (byte)0x1B, (byte)0x8E, (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74, - (byte)0x50, (byte)0xBB, (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65, - (byte)0xD0, (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61, - (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41, (byte)0xF2, - (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83, (byte)0xE0, (byte)0x61, - (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E, (byte)0x37, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A GSM default alphabet message with carriage return padding", - msg.getMessageBody()); - - assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode()); - } - - public void testGetMessageBody7BitWithLanguageInBodyUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x10, - - (byte)0x01, - - (byte)0x73, (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E, - (byte)0x9B, (byte)0x20, (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE, - (byte)0xB3, (byte)0xE9, (byte)0xA0, (byte)0x30, (byte)0x1B, (byte)0x8E, - (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74, (byte)0x50, (byte)0xBB, - (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65, (byte)0xD0, - (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61, - (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41, - (byte)0xF2, (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83, - (byte)0xE0, (byte)0x61, (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E, - (byte)0x37, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x37 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A GSM default alphabet message with carriage return padding", - msg.getMessageBody()); - - assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode()); - } - - public void testGetMessageBody8Bit() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x44, (byte)0x11, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41, - (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("8-bit message body should be empty", "", msg.getMessageBody()); - } - - public void testGetMessageBodyUcs2() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x48, (byte)0x11, (byte)0x00, - (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43, - (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00, - (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, - (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00, - (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E, - (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69, (byte)0x00, - (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67, - (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04, - (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, - (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, - (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72, - (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A UCS2 message containing a \u0434 character", msg.getMessageBody()); - } - - public void testGetMessageBodyUcs2Umts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48, - - (byte)0x01, - - (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, - (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, - (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65, - (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61, - (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x20, - (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E, - (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69, - (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, - (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, - (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20, - (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61, - (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x63, - (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72, - (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D, - - (byte)0x4E - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A UCS2 message containing a \u0434 character", msg.getMessageBody()); - } - - public void testGetMessageBodyUcs2MultipageUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48, - - (byte)0x02, - - (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41, - (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - - (byte)0x06, - - (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42, - (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, - - (byte)0x06 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected multipage UCS2 string decoded", - "AAABBB", msg.getMessageBody()); - } - - public void testGetMessageBodyUcs2WithLanguageInBody() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x11, (byte)0x11, (byte)0x78, - (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, - (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00, - (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, - (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, - (byte)0x65, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, - (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, - (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, - (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00, - (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, - (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, - (byte)0x61, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, - (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A UCS2 message containing a \u0434 character", msg.getMessageBody()); - - assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode()); - } - - public void testGetMessageBodyUcs2WithLanguageInBodyUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x11, - - (byte)0x01, - - (byte)0x78, (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, - (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, - (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D, - (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, - (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, - (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, - (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, - (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, - (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, - (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34, - (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, - (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, - (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, - (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D, - - (byte)0x50 - }; - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected 7-bit string decoded", - "A UCS2 message containing a \u0434 character", msg.getMessageBody()); - - assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode()); - } - - public void testGetMessageIdentifier() { - byte[] pdu = { - (byte)0xC0, (byte)0x00, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory()); - } - - public void testGetMessageIdentifierUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A, - (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, - (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, - (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x34 - }; - - SmsCbMessage msg = createFromPdu(pdu); - - assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory()); - } - - public void testGetMessageCode() { - byte[] pdu = { - (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - - SmsCbMessage msg = createFromPdu(pdu); - int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4; - - assertEquals("Unexpected message code decoded", 682, messageCode); - } - - public void testGetMessageCodeUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A, - (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, - (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, - (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x34 - }; - - SmsCbMessage msg = createFromPdu(pdu); - int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4; - - assertEquals("Unexpected message code decoded", 682, messageCode); - } - - public void testGetUpdateNumber() { - byte[] pdu = { - (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41, - (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6, - (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70, - (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, - (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, - (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75, - (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69, - (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00 - }; - - SmsCbMessage msg = createFromPdu(pdu); - int updateNumber = msg.getSerialNumber() & 0x000f; - - assertEquals("Unexpected update number decoded", 5, updateNumber); - } - - public void testGetUpdateNumberUmts() { - byte[] pdu = { - (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40, - - (byte)0x01, - - (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, - (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, - (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C, - (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C, - (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A, - (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9, - (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, - (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, - (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, - (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, - (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, - (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, - (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, - (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00, - - (byte)0x34 - }; - - SmsCbMessage msg = createFromPdu(pdu); - int updateNumber = msg.getSerialNumber() & 0x000f; - - assertEquals("Unexpected update number decoded", 5, updateNumber); - } - - /* ETWS Test message including header */ - private static final byte[] etwsMessageNormal = IccUtils.hexStringToBytes("000011001101" + - "0D0A5BAE57CE770C531790E85C716CBF3044573065B930675730" + - "9707767A751F30025F37304463FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" + - "0000000000000000000000000000"); - - private static final byte[] etwsMessageCancel = IccUtils.hexStringToBytes("000011001101" + - "0D0A5148307B3069002800310030003A0035" + - "00320029306E7DCA602557309707901F5831309253D66D883057307E3059FF086C178C615E81FF09" + - "00000000000000000000000000000000000000000000"); - - private static final byte[] etwsMessageTest = IccUtils.hexStringToBytes("000011031101" + - "0D0A5BAE57CE770C531790E85C716CBF3044" + - "573065B9306757309707300263FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" + - "00000000000000000000000000000000000000000000"); - - // FIXME: add example of ETWS primary notification PDU - - public void testEtwsMessageNormal() { - SmsCbMessage msg = createFromPdu(etwsMessageNormal); - Log.d(TAG, msg.toString()); - assertEquals("GS mismatch", 0, msg.getGeographicalScope()); - assertEquals("serial number mismatch", 0, msg.getSerialNumber()); - assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory()); - assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE, - msg.getEtwsWarningInfo().getWarningType()); - } - - public void testEtwsMessageCancel() { - SmsCbMessage msg = createFromPdu(etwsMessageCancel); - Log.d(TAG, msg.toString()); - assertEquals("GS mismatch", 0, msg.getGeographicalScope()); - assertEquals("serial number mismatch", 0, msg.getSerialNumber()); - assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory()); - assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE, - msg.getEtwsWarningInfo().getWarningType()); - } - - public void testEtwsMessageTest() { - SmsCbMessage msg = createFromPdu(etwsMessageTest); - Log.d(TAG, msg.toString()); - assertEquals("GS mismatch", 0, msg.getGeographicalScope()); - assertEquals("serial number mismatch", 0, msg.getSerialNumber()); - assertEquals("message ID mismatch", 0x1103, msg.getServiceCategory()); - assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE, - msg.getEtwsWarningInfo().getWarningType()); - } - - // Make sure we don't throw an exception if we feed random data to the PDU parser. - public void testRandomPdus() { - Random r = new Random(94040); - for (int run = 0; run < 10000; run++) { - int len = r.nextInt(140); - byte[] data = new byte[len]; - for (int i = 0; i < len; i++) { - data[i] = (byte) r.nextInt(256); - } - try { - // this should return a SmsCbMessage object or null for invalid data - SmsCbMessage msg = createFromPdu(data); - } catch (Exception e) { - Log.d(TAG, "exception thrown", e); - fail("Exception in decoder at run " + run + " length " + len + ": " + e); - } - } - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java deleted file mode 100644 index ea6836decbca..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright (C) 2011 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.content.Context; -import android.os.AsyncResult; -import android.os.Message; -import android.os.SystemClock; -import android.util.Log; - -import com.android.internal.telephony.BaseCommands; -import com.android.internal.telephony.IccIoResult; -import com.android.internal.telephony.UUSInfo; - -import junit.framework.Assert; - -/** - * Dummy BaseCommands for UsimDataDownloadTest. Only implements UICC envelope and - * SMS acknowledgement commands. - */ -class UsimDataDownloadCommands extends BaseCommands { - private static final String TAG = "UsimDataDownloadCommands"; - - private boolean mExpectingAcknowledgeGsmSms; // true if expecting ack GSM SMS - private boolean mExpectingAcknowledgeGsmSmsSuccess; // true if expecting ack SMS success - private int mExpectingAcknowledgeGsmSmsFailureCause; // expecting ack SMS failure cause - private String mExpectingAcknowledgeGsmSmsPdu; // expecting ack SMS PDU - - private boolean mExpectingSendEnvelope; // true to expect a send envelope command - private String mExpectingSendEnvelopeContents; // expected string for send envelope - private int mExpectingSendEnvelopeResponseSw1; // SW1/SW2 response status - private int mExpectingSendEnvelopeResponseSw2; // SW1/SW2 response status - private String mExpectingSendEnvelopeResponse; // Response string for Send Envelope - - UsimDataDownloadCommands(Context context) { - super(context); - } - - /** - * Expect a call to acknowledgeLastIncomingGsmSms with success flag and failure cause. - * @param success true if expecting success; false if expecting failure - * @param cause the failure cause, if success is false - */ - synchronized void expectAcknowledgeGsmSms(boolean success, int cause) { - Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms); - mExpectingAcknowledgeGsmSms = true; - mExpectingAcknowledgeGsmSmsSuccess = success; - mExpectingAcknowledgeGsmSmsFailureCause = cause; - } - - /** - * Expect a call to acknowledgeLastIncomingGsmSmsWithPdu with success flag and PDU. - * @param success true if expecting success; false if expecting failure - * @param ackPdu the acknowledgement PDU to expect - */ - synchronized void expectAcknowledgeGsmSmsWithPdu(boolean success, String ackPdu) { - Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms); - mExpectingAcknowledgeGsmSms = true; - mExpectingAcknowledgeGsmSmsSuccess = success; - mExpectingAcknowledgeGsmSmsPdu = ackPdu; - } - - /** - * Expect a call to sendEnvelopeWithStatus(). - * @param contents expected envelope contents to send - * @param sw1 simulated SW1 status to return - * @param sw2 simulated SW2 status to return - * @param response simulated envelope response to return - */ - synchronized void expectSendEnvelope(String contents, int sw1, int sw2, String response) { - Assert.assertFalse("expectSendEnvelope called twice", mExpectingSendEnvelope); - mExpectingSendEnvelope = true; - mExpectingSendEnvelopeContents = contents; - mExpectingSendEnvelopeResponseSw1 = sw1; - mExpectingSendEnvelopeResponseSw2 = sw2; - mExpectingSendEnvelopeResponse = response; - } - - synchronized void assertExpectedMethodsCalled() { - long stopTime = SystemClock.elapsedRealtime() + 5000; - while ((mExpectingAcknowledgeGsmSms || mExpectingSendEnvelope) - && SystemClock.elapsedRealtime() < stopTime) { - try { - wait(); - } catch (InterruptedException ignored) {} - } - Assert.assertFalse("expecting SMS acknowledge call", mExpectingAcknowledgeGsmSms); - Assert.assertFalse("expecting send envelope call", mExpectingSendEnvelope); - } - - @Override - public synchronized void acknowledgeLastIncomingGsmSms(boolean success, int cause, - Message response) { - Log.d(TAG, "acknowledgeLastIncomingGsmSms: success=" + success + ", cause=" + cause); - Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms); - Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success); - Assert.assertEquals(mExpectingAcknowledgeGsmSmsFailureCause, cause); - mExpectingAcknowledgeGsmSms = false; - if (response != null) { - AsyncResult.forMessage(response); - response.sendToTarget(); - } - notifyAll(); // wake up assertExpectedMethodsCalled() - } - - @Override - public synchronized void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, - Message response) { - Log.d(TAG, "acknowledgeLastIncomingGsmSmsWithPdu: success=" + success - + ", ackPDU= " + ackPdu); - Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms); - Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success); - Assert.assertEquals(mExpectingAcknowledgeGsmSmsPdu, ackPdu); - mExpectingAcknowledgeGsmSms = false; - if (response != null) { - AsyncResult.forMessage(response); - response.sendToTarget(); - } - notifyAll(); // wake up assertExpectedMethodsCalled() - } - - @Override - public synchronized void sendEnvelopeWithStatus(String contents, Message response) { - // Add spaces between hex bytes for readability - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < contents.length(); i += 2) { - builder.append(contents.charAt(i)).append(contents.charAt(i+1)).append(' '); - } - Log.d(TAG, "sendEnvelopeWithStatus: " + builder.toString()); - - Assert.assertTrue("unexpected call to send envelope", mExpectingSendEnvelope); - Assert.assertEquals(mExpectingSendEnvelopeContents, contents); - mExpectingSendEnvelope = false; - - IccIoResult result = new IccIoResult(mExpectingSendEnvelopeResponseSw1, - mExpectingSendEnvelopeResponseSw2, mExpectingSendEnvelopeResponse); - - if (response != null) { - AsyncResult.forMessage(response, result, null); - response.sendToTarget(); - } - notifyAll(); // wake up assertExpectedMethodsCalled() - } - - @Override - public void setSuppServiceNotifications(boolean enable, Message result) { - } - - @Override - public void supplyIccPin(String pin, Message result) { - } - - @Override - public void supplyIccPinForApp(String pin, String aid, Message result) { - } - - @Override - public void supplyIccPuk(String puk, String newPin, Message result) { - } - - @Override - public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) { - } - - @Override - public void supplyIccPin2(String pin2, Message result) { - } - - @Override - public void supplyIccPin2ForApp(String pin2, String aid, Message result) { - } - - @Override - public void supplyIccPuk2(String puk2, String newPin2, Message result) { - } - - @Override - public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result) { - } - - @Override - public void changeIccPin(String oldPin, String newPin, Message result) { - } - - @Override - public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result) { - } - - @Override - public void changeIccPin2(String oldPin2, String newPin2, Message result) { - } - - @Override - public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result) { - } - - @Override - public void changeBarringPassword(String facility, String oldPwd, String newPwd, - Message result) { - } - - @Override - public void supplyNetworkDepersonalization(String netpin, Message result) { - } - - @Override - public void getCurrentCalls(Message result) { - } - - @Override - public void getPDPContextList(Message result) { - } - - @Override - public void getDataCallList(Message result) { - } - - @Override - public void dial(String address, int clirMode, Message result) { - } - - @Override - public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { - } - - @Override - public void getIMSI(Message result) { - } - - @Override - public void getIMEI(Message result) { - } - - @Override - public void getIMEISV(Message result) { - } - - @Override - public void hangupConnection(int gsmIndex, Message result) { - } - - @Override - public void hangupWaitingOrBackground(Message result) { - } - - @Override - public void hangupForegroundResumeBackground(Message result) { - } - - @Override - public void switchWaitingOrHoldingAndActive(Message result) { - } - - @Override - public void conference(Message result) { - } - - @Override - public void setPreferredVoicePrivacy(boolean enable, Message result) { - } - - @Override - public void getPreferredVoicePrivacy(Message result) { - } - - @Override - public void separateConnection(int gsmIndex, Message result) { - } - - @Override - public void acceptCall(Message result) { - } - - @Override - public void rejectCall(Message result) { - } - - @Override - public void explicitCallTransfer(Message result) { - } - - @Override - public void getLastCallFailCause(Message result) { - } - - @Override - public void getLastPdpFailCause(Message result) { - } - - @Override - public void getLastDataCallFailCause(Message result) { - } - - @Override - public void setMute(boolean enableMute, Message response) { - } - - @Override - public void getMute(Message response) { - } - - @Override - public void getSignalStrength(Message response) { - } - - @Override - public void getVoiceRegistrationState(Message response) { - } - - @Override - public void getDataRegistrationState(Message response) { - } - - @Override - public void getOperator(Message response) { - } - - @Override - public void sendDtmf(char c, Message result) { - } - - @Override - public void startDtmf(char c, Message result) { - } - - @Override - public void stopDtmf(Message result) { - } - - @Override - public void sendBurstDtmf(String dtmfString, int on, int off, Message result) { - } - - @Override - public void sendSMS(String smscPDU, String pdu, Message response) { - } - - @Override - public void sendCdmaSms(byte[] pdu, Message response) { - } - - @Override - public void deleteSmsOnSim(int index, Message response) { - } - - @Override - public void deleteSmsOnRuim(int index, Message response) { - } - - @Override - public void writeSmsToSim(int status, String smsc, String pdu, Message response) { - } - - @Override - public void writeSmsToRuim(int status, String pdu, Message response) { - } - - @Override - public void setRadioPower(boolean on, Message response) { - } - - @Override - public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response) { - } - - @Override - public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data, - String pin2, Message response) { - } - - @Override - public void queryCLIP(Message response) { - } - - @Override - public void getCLIR(Message response) { - } - - @Override - public void setCLIR(int clirMode, Message response) { - } - - @Override - public void queryCallWaiting(int serviceClass, Message response) { - } - - @Override - public void setCallWaiting(boolean enable, int serviceClass, Message response) { - } - - @Override - public void setCallForward(int action, int cfReason, int serviceClass, String number, - int timeSeconds, Message response) { - } - - @Override - public void queryCallForwardStatus(int cfReason, int serviceClass, String number, - Message response) { - } - - @Override - public void setNetworkSelectionModeAutomatic(Message response) { - } - - @Override - public void setNetworkSelectionModeManual(String operatorNumeric, Message response) { - } - - @Override - public void getNetworkSelectionMode(Message response) { - } - - @Override - public void getAvailableNetworks(Message response) { - } - - @Override - public void getBasebandVersion(Message response) { - } - - @Override - public void queryFacilityLock(String facility, String password, int serviceClass, - Message response) { - } - - @Override - public void queryFacilityLockForApp(String facility, String password, int serviceClass, - String appId, Message response) { - } - - @Override - public void setFacilityLock(String facility, boolean lockState, String password, - int serviceClass, Message response) { - } - - @Override - public void setFacilityLockForApp(String facility, boolean lockState, String password, - int serviceClass, String appId, Message response) { - } - - @Override - public void sendUSSD(String ussdString, Message response) { - } - - @Override - public void cancelPendingUssd(Message response) { - } - - @Override - public void resetRadio(Message result) { - } - - @Override - public void setBandMode(int bandMode, Message response) { - } - - @Override - public void queryAvailableBandMode(Message response) { - } - - @Override - public void setPreferredNetworkType(int networkType, Message response) { - } - - @Override - public void getPreferredNetworkType(Message response) { - } - - @Override - public void getNeighboringCids(Message response) { - } - - @Override - public void setLocationUpdates(boolean enable, Message response) { - } - - @Override - public void getSmscAddress(Message result) { - } - - @Override - public void setSmscAddress(String address, Message result) { - } - - @Override - public void reportSmsMemoryStatus(boolean available, Message result) { - } - - @Override - public void reportStkServiceIsRunning(Message result) { - } - - @Override - public void invokeOemRilRequestRaw(byte[] data, Message response) { - } - - @Override - public void invokeOemRilRequestStrings(String[] strings, Message response) { - } - - @Override - public void sendTerminalResponse(String contents, Message response) { - } - - @Override - public void sendEnvelope(String contents, Message response) { - } - - @Override - public void handleCallSetupRequestFromSim(boolean accept, Message response) { - } - - @Override - public void setGsmBroadcastActivation(boolean activate, Message result) { - } - - @Override - public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) { - } - - @Override - public void getGsmBroadcastConfig(Message response) { - } - - @Override - public void getDeviceIdentity(Message response) { - } - - @Override - public void getCDMASubscription(Message response) { - } - - @Override - public void sendCDMAFeatureCode(String FeatureCode, Message response) { - } - - @Override - public void setPhoneType(int phoneType) { - } - - @Override - public void queryCdmaRoamingPreference(Message response) { - } - - @Override - public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { - } - - @Override - public void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) { - } - - @Override - public void getCdmaSubscriptionSource(Message response) { - } - - @Override - public void setTTYMode(int ttyMode, Message response) { - } - - @Override - public void queryTTYMode(Message response) { - } - - @Override - public void setupDataCall(String radioTechnology, String profile, String apn, String user, - String password, String authType, String protocol, Message result) { - } - - @Override - public void deactivateDataCall(int cid, int reason, Message result) { - } - - @Override - public void setCdmaBroadcastActivation(boolean activate, Message result) { - } - - @Override - public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) { - } - - @Override - public void getCdmaBroadcastConfig(Message result) { - } - - @Override - public void exitEmergencyCallbackMode(Message response) { - } - - @Override - public void getIccCardStatus(Message result) { - } - - @Override - public void requestIsimAuthentication(String nonce, Message response) { - } - - @Override - public void getVoiceRadioTechnology(Message response) { - } - - @Override - public void getIMSIForApp(String aid, Message result) { - } - - @Override - public void iccIOForApp(int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, String aid, Message response) { - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java deleted file mode 100644 index 6c8ba5e1e23d..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2011 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.os.HandlerThread; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.nio.charset.Charset; - -/** - * Test SMS-PP data download to UICC. - * Uses test messages from 3GPP TS 31.124 section 27.22.5. - */ -public class UsimDataDownloadTest extends AndroidTestCase { - private static final String TAG = "UsimDataDownloadTest"; - - class TestHandlerThread extends HandlerThread { - private UsimDataDownloadHandler mHandler; - - TestHandlerThread() { - super("TestHandlerThread"); - } - - @Override - protected void onLooperPrepared() { - synchronized (this) { - mHandler = new UsimDataDownloadHandler(mCm); - notifyAll(); - } - } - - UsimDataDownloadHandler getHandler() { - synchronized (this) { - while (mHandler == null) { - try { - wait(); - } catch (InterruptedException ignored) {} - } - return mHandler; - } - } - } - - private UsimDataDownloadCommands mCm; - private TestHandlerThread mHandlerThread; - UsimDataDownloadHandler mHandler; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mCm = new UsimDataDownloadCommands(mContext); - mHandlerThread = new TestHandlerThread(); - mHandlerThread.start(); - mHandler = mHandlerThread.getHandler(); - Log.d(TAG, "mHandler is constructed"); - } - - @Override - protected void tearDown() throws Exception { - mHandlerThread.quit(); - super.tearDown(); - } - - // SMS-PP Message 3.1.1 - private static final byte[] SMS_PP_MESSAGE_3_1_1 = { - // Service center address - 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8, - - 0x04, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, 0x16, (byte) 0x89, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x0d, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x20, 0x31 - }; - - // SMS-PP Download Envelope 3.1.1 - private static final String SMS_PP_ENVELOPE_3_1_1 = "d12d8202838106099111223344556677f88b1c04" - + "049121437f16891010000000000d546573744d6573736167652031"; - - // SMS-PP Message 3.1.5 - private static final byte[] SMS_PP_MESSAGE_3_1_5 = { - // Service center address - 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8, - - 0x44, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, (byte) 0xf6, (byte) 0x89, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x1e, 0x02, 0x70, 0x00, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x00, - 0x00, 0x00, (byte) 0xbf, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, - (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc - }; - - // SMS-PP Download Envelope 3.1.5 - private static final String SMS_PP_ENVELOPE_3_1_5 = "d13e8202838106099111223344556677f88b2d44" - + "049121437ff6891010000000001e0270000019000d00000000bfff00000000000100" - + "dcdcdcdcdcdcdcdcdcdc"; - - public void testDataDownloadMessage1() { - SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_1); - assertTrue("message is SMS-PP data download", message.isUsimDataDownload()); - - mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, ""); - mCm.expectAcknowledgeGsmSms(true, 0); - mHandler.startDataDownload(message); - mCm.assertExpectedMethodsCalled(); - - mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "0123456789"); - mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077f16050123456789"); - mHandler.startDataDownload(message); - mCm.assertExpectedMethodsCalled(); - - mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x62, 0xff, "0123456789abcdef"); - mCm.expectAcknowledgeGsmSmsWithPdu(false, "00d5077f16080123456789abcdef"); - mHandler.startDataDownload(message); - mCm.assertExpectedMethodsCalled(); - } - - public void testDataDownloadMessage5() { - SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_5); - assertTrue("message is SMS-PP data download", message.isUsimDataDownload()); - - mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x90, 0x00, "9876543210"); - mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077ff6059876543210"); - mHandler.startDataDownload(message); - mCm.assertExpectedMethodsCalled(); - - mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x93, 0x00, ""); - mCm.expectAcknowledgeGsmSms(false, 0xd4); // SIM toolkit busy - mHandler.startDataDownload(message); - mCm.assertExpectedMethodsCalled(); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java deleted file mode 100644 index 56854edcf012..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2011 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * Test UsimServiceTable class. - */ -public class UsimServiceTableTest extends AndroidTestCase { - - @SmallTest - public void testUsimServiceTable() { - byte[] noServices = {0x00}; - byte[] service1 = {0x01, 0x00}; - byte[] service8 = {(byte) 0x80, 0x00, 0x00}; - byte[] service8And9 = {(byte) 0x80, 0x01}; - byte[] service28 = {0x00, 0x00, 0x00, 0x08}; - byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, (byte) 0xff}; - - UsimServiceTable testTable1 = new UsimServiceTable(noServices); - assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN)); - assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - - UsimServiceTable testTable2 = new UsimServiceTable(service1); - assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN)); - assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - - UsimServiceTable testTable3 = new UsimServiceTable(service8); - assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION)); - assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO)); - assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO)); - assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - - UsimServiceTable testTable4 = new UsimServiceTable(service8And9); - assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION)); - assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO)); - assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO)); - assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE)); - assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - - UsimServiceTable testTable5 = new UsimServiceTable(service28); - assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP)); - assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - - UsimServiceTable testTable6 = new UsimServiceTable(service89To96); - assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK)); - assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS)); - assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA)); - assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP)); - assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS)); - assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM)); - } -} diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java deleted file mode 100644 index 3149ee15e00d..000000000000 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony.mockril; - -import android.util.Log; -import android.test.InstrumentationTestCase; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import com.android.internal.communication.MsgHeader; -import com.android.internal.communication.Msg; -import com.android.internal.telephony.RilChannel; -import com.android.internal.telephony.ril_proto.RilCtrlCmds; -import com.android.internal.telephony.ril_proto.RilCmds; - -import com.android.frameworks.telephonytests.TelephonyMockRilTestRunner; -import com.google.protobuf.micro.InvalidProtocolBufferMicroException; - -// Test suite for test ril -public class MockRilTest extends InstrumentationTestCase { - private static final String TAG = "MockRilTest"; - - RilChannel mMockRilChannel; - TelephonyMockRilTestRunner mRunner; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mRunner = (TelephonyMockRilTestRunner)getInstrumentation(); - mMockRilChannel = mRunner.mMockRilChannel; - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - static void log(String s) { - Log.v(TAG, s); - } - - /** - * Test Case 1: Test protobuf serialization and deserialization - * @throws InvalidProtocolBufferMicroException - */ - public void testProtobufSerDes() throws InvalidProtocolBufferMicroException { - log("testProtobufSerdes E"); - - RilCtrlCmds.CtrlRspRadioState rs = new RilCtrlCmds.CtrlRspRadioState(); - assertTrue(String.format("expected rs.state == 0 was %d", rs.getState()), - rs.getState() == 0); - rs.setState(1); - assertTrue(String.format("expected rs.state == 1 was %d", rs.getState()), - rs.getState() == 1); - - byte[] rs_ser = rs.toByteArray(); - RilCtrlCmds.CtrlRspRadioState rsNew = RilCtrlCmds.CtrlRspRadioState.parseFrom(rs_ser); - assertTrue(String.format("expected rsNew.state == 1 was %d", rs.getState()), - rs.getState() == 1); - - log("testProtobufSerdes X"); - } - - /** - * Test case 2: Test echo command works using writeMsg & readMsg - */ - public void testEchoMsg() throws IOException { - log("testEchoMsg E"); - - MsgHeader mh = new MsgHeader(); - mh.setCmd(0); - mh.setToken(1); - mh.setStatus(2); - ByteBuffer data = ByteBuffer.allocate(3); - data.put((byte)3); - data.put((byte)4); - data.put((byte)5); - Msg.send(mMockRilChannel, mh, data); - - Msg respMsg = Msg.recv(mMockRilChannel); - assertTrue(String.format("expected mhd.header.cmd == 0 was %d",respMsg.getCmd()), - respMsg.getCmd() == 0); - assertTrue(String.format("expected mhd.header.token == 1 was %d",respMsg.getToken()), - respMsg.getToken() == 1); - assertTrue(String.format("expected mhd.header.status == 2 was %d", respMsg.getStatus()), - respMsg.getStatus() == 2); - assertTrue(String.format("expected mhd.data[0] == 3 was %d", respMsg.getData(0)), - respMsg.getData(0) == 3); - assertTrue(String.format("expected mhd.data[1] == 4 was %d", respMsg.getData(1)), - respMsg.getData(1) == 4); - assertTrue(String.format("expected mhd.data[2] == 5 was %d", respMsg.getData(2)), - respMsg.getData(2) == 5); - - log("testEchoMsg X"); - } - - /** - * Test case 3: Test get as - */ - public void testGetAs() { - log("testGetAs E"); - - // Use a message header as the protobuf data content - MsgHeader mh = new MsgHeader(); - mh.setCmd(12345); - mh.setToken(9876); - mh.setStatus(7654); - mh.setLengthData(4321); - byte[] data = mh.toByteArray(); - MsgHeader mhResult = Msg.getAs(MsgHeader.class, data); - - assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()), - mhResult.getCmd() == 12345); - assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()), - mhResult.getToken() == 9876); - assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()), - mhResult.getStatus() == 7654); - assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()), - mhResult.getLengthData() == 4321); - - Msg msg = Msg.obtain(); - msg.setData(ByteBuffer.wrap(data)); - - mhResult = msg.getDataAs(MsgHeader.class); - - assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()), - mhResult.getCmd() == 12345); - assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()), - mhResult.getToken() == 9876); - assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()), - mhResult.getStatus() == 7654); - assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()), - mhResult.getLengthData() == 4321); - - log("testGetAs X"); - } - - /** - * Test case 3: test get radio state - */ - public void testGetRadioState() throws IOException { - log("testGetRadioState E"); - - Msg.send(mMockRilChannel, 1, 9876, 0, null); - - Msg resp = Msg.recv(mMockRilChannel); - //resp.printHeader("testGetRadioState"); - - assertTrue(String.format("expected cmd == 1 was %d", resp.getCmd()), - resp.getCmd() == 1); - assertTrue(String.format("expected token == 9876 was %d", resp.getToken()), - resp.getToken() == 9876); - assertTrue(String.format("expected status == 0 was %d", resp.getStatus()), - resp.getStatus() == 0); - - RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); - - int state = rsp.getState(); - log("testGetRadioState state=" + state); - assertTrue(String.format("expected RadioState >= 0 && RadioState <= 9 was %d", state), - ((state >= 0) && (state <= 9))); - - log("testGetRadioState X"); - } - - /** - * Test case 5: test set radio state - */ - public void testSetRadioState() throws IOException { - log("testSetRadioState E"); - - RilCtrlCmds.CtrlReqRadioState cmdrs = new RilCtrlCmds.CtrlReqRadioState(); - assertEquals(0, cmdrs.getState()); - - cmdrs.setState(RilCmds.RADIOSTATE_SIM_NOT_READY); - assertEquals(2, cmdrs.getState()); - - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, cmdrs); - - Msg resp = Msg.recv(mMockRilChannel); - log("get response status :" + resp.getStatus()); - log("get response for command: " + resp.getCmd()); - log("get command token: " + resp.getToken()); - - RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); - - int state = rsp.getState(); - log("get response for testSetRadioState: " + state); - assertTrue(RilCmds.RADIOSTATE_SIM_NOT_READY == state); - } - - /** - * Test case 6: test start incoming call and hangup it. - */ - public void testStartIncomingCallAndHangup() throws IOException { - log("testStartIncomingCallAndHangup"); - RilCtrlCmds.CtrlReqSetMTCall cmd = new RilCtrlCmds.CtrlReqSetMTCall(); - String incomingCall = "6502889108"; - // set the MT call - cmd.setPhoneNumber(incomingCall); - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, cmd); - // get response - Msg resp = Msg.recv(mMockRilChannel); - log("Get response status: " + resp.getStatus()); - assertTrue("The ril is not in a proper state to set MT calls.", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - - // allow the incoming call alerting for some time - try { - Thread.sleep(5000); - } catch (InterruptedException e) {} - - // we are playing a trick to assume the current is 1 - RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote(); - hangupCmd.setConnectionId(1); - hangupCmd.setCallFailCause(16); // normal hangup - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd); - - // get response - resp = Msg.recv(mMockRilChannel); - log("Get response for hangup connection: " + resp.getStatus()); - assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - } - - /** - * Test case 7: test set call transition flag - */ - public void testSetCallTransitionFlag() throws IOException { - log("testSetCallTransitionFlag"); - // Set flag to true: - RilCtrlCmds.CtrlSetCallTransitionFlag cmd = new RilCtrlCmds.CtrlSetCallTransitionFlag(); - cmd.setFlag(true); - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd); - - Msg resp = Msg.recv(mMockRilChannel); - log("Get response status: " + resp.getStatus()); - assertTrue("Set call transition flag failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - - // add a dialing call - RilCtrlCmds.CtrlReqAddDialingCall cmdDialCall = new RilCtrlCmds.CtrlReqAddDialingCall(); - String phoneNumber = "5102345678"; - cmdDialCall.setPhoneNumber(phoneNumber); - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_ADD_DIALING_CALL, 0, 0, cmdDialCall); - resp = Msg.recv(mMockRilChannel); - log("Get response status for adding a dialing call: " + resp.getStatus()); - assertTrue("add dialing call failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - try { - Thread.sleep(5000); - } catch (InterruptedException e) {} - - // send command to force call state change - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null); - resp = Msg.recv(mMockRilChannel); - log("Get response status: " + resp.getStatus()); - assertTrue("Set call alert failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - - try { - Thread.sleep(2000); - } catch (InterruptedException e) {} - - // send command to force call state change - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null); - resp = Msg.recv(mMockRilChannel); - log("Get response status: " + resp.getStatus()); - assertTrue("Set call active failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - - // hangup the active all remotely - RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote(); - hangupCmd.setConnectionId(1); - hangupCmd.setCallFailCause(16); // normal hangup - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd); - resp = Msg.recv(mMockRilChannel); - log("Get response for hangup connection: " + resp.getStatus()); - assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - - // set the flag to false - cmd.setFlag(false); - Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd); - resp = Msg.recv(mMockRilChannel); - assertTrue("Set call transition flag failed", - resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK); - } -} diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk index a6df98e37576..31a0daffed3a 100644 --- a/tests/permission/Android.mk +++ b/tests/permission/Android.mk @@ -7,7 +7,7 @@ LOCAL_MODULE_TAGS := tests # Include all test java files. LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_JAVA_LIBRARIES := android.test.runner +LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common LOCAL_PACKAGE_NAME := FrameworkPermissionTests include $(BUILD_PACKAGE) -- GitLab