diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-06-07 22:49:49 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-06-07 22:49:49 -0700 |
commit | 7699318ecd1e31b9ee4ead4acdb430f3aaa36ff1 (patch) | |
tree | 2f4f01dbe9816a074ecc23c5c4355394ca2ea8a0 /telephony | |
parent | 8bb61e68355dac89fb4fa08b7362c4b7ccdcc573 (diff) | |
parent | 1e3d1b4b83452286b000b8cd1997e5aef97fe2a7 (diff) | |
download | frameworks_base-7699318ecd1e31b9ee4ead4acdb430f3aaa36ff1.zip frameworks_base-7699318ecd1e31b9ee4ead4acdb430f3aaa36ff1.tar.gz frameworks_base-7699318ecd1e31b9ee4ead4acdb430f3aaa36ff1.tar.bz2 |
am 1e3d1b4b: Merge change 3107 into donut
Merge commit '1e3d1b4b83452286b000b8cd1997e5aef97fe2a7'
* commit '1e3d1b4b83452286b000b8cd1997e5aef97fe2a7':
Motorola changes from 090602 through 090605
Diffstat (limited to 'telephony')
20 files changed, 1097 insertions, 392 deletions
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java index dba4972..a0d2dd2 100644 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ b/telephony/java/com/android/internal/telephony/BaseCommands.java @@ -59,6 +59,12 @@ public abstract class BaseCommands implements CommandsInterface { protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList(); protected RegistrantList mDisplayInfoRegistrants = new RegistrantList(); protected RegistrantList mSignalInfoRegistrants = new RegistrantList(); + protected RegistrantList mNumberInfoRegistrants = new RegistrantList(); + protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList(); + protected RegistrantList mLineControlInfoRegistrants = new RegistrantList(); + protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList(); + protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList(); + protected Registrant mSMSRegistrant; protected Registrant mNITZTimeRegistrant; protected Registrant mSignalStrengthRegistrant; @@ -509,6 +515,50 @@ public abstract class BaseCommands implements CommandsInterface { mOtaProvisionRegistrants.remove(h); } + public void registerForNumberInfo(Handler h,int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mNumberInfoRegistrants.add(r); + } + + public void unregisterForNumberInfo(Handler h){ + mNumberInfoRegistrants.remove(h); + } + + public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mRedirNumInfoRegistrants.add(r); + } + + public void unregisterForRedirectedNumberInfo(Handler h) { + mRedirNumInfoRegistrants.remove(h); + } + + public void registerForLineControlInfo(Handler h, int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mLineControlInfoRegistrants.add(r); + } + + public void unregisterForLineControlInfo(Handler h) { + mLineControlInfoRegistrants.remove(h); + } + + public void registerFoT53ClirlInfo(Handler h,int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mT53ClirInfoRegistrants.add(r); + } + + public void unregisterForT53ClirInfo(Handler h) { + mT53ClirInfoRegistrants.remove(h); + } + + public void registerForT53AudioControlInfo(Handler h,int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mT53AudCntrlInfoRegistrants.add(r); + } + + public void unregisterForT53AudioControlInfo(Handler h) { + mT53AudCntrlInfoRegistrants.remove(h); + } //***** Protected Methods /** diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java index 70471b6..7eb9d85 100644 --- a/telephony/java/com/android/internal/telephony/Call.java +++ b/telephony/java/com/android/internal/telephony/Call.java @@ -46,6 +46,13 @@ public abstract class Call { public State state = State.IDLE; + // Flag to indicate if the current calling/caller information + // is accurate. If false the information is known to be accurate. + // + // For CDMA, during call waiting/3 way, there is no network response + // if call waiting is answered, network timed out, dropped, 3 way + // merged, etc. + protected boolean isGeneric = false; /* Instance Methods */ @@ -126,6 +133,7 @@ public abstract class Call { if (t < time) { earliest = c; + time = t; } } @@ -157,10 +165,8 @@ public abstract class Call { public long getEarliestConnectTime() { - List l; long time = Long.MAX_VALUE; - - l = getConnections(); + List l = getConnections(); if (l.size() == 0) { return 0; @@ -189,4 +195,44 @@ public abstract class Call { return getState().isRinging(); } + /** + * Returns the Connection associated with this Call that was created + * last, or null if there are no Connections in this Call + */ + public Connection + getLatestConnection() { + List l = getConnections(); + if (l.size() == 0) { + return null; + } + + long time = 0; + Connection latest = null; + for (int i = 0, s = l.size() ; i < s ; i++) { + Connection c = (Connection) l.get(i); + long t = c.getCreateTime(); + + if (t > time) { + latest = c; + time = t; + } + } + + return latest; + } + + /** + * To indicate if the connection information is accurate + * or not. false means accurate. Only used for CDMA. + */ + public boolean isGeneric() { + return isGeneric; + } + + /** + * Set the generic instance variable + */ + public void setGeneric(boolean generic) { + isGeneric = generic; + } } diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java index 8263ded..9619a66 100644 --- a/telephony/java/com/android/internal/telephony/CallTracker.java +++ b/telephony/java/com/android/internal/telephony/CallTracker.java @@ -44,20 +44,21 @@ public abstract class CallTracker extends Handler { //***** Events - protected static final int EVENT_POLL_CALLS_RESULT = 1; - protected static final int EVENT_CALL_STATE_CHANGE = 2; - protected static final int EVENT_REPOLL_AFTER_DELAY = 3; - protected static final int EVENT_OPERATION_COMPLETE = 4; - protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; - - protected static final int EVENT_SWITCH_RESULT = 8; - protected static final int EVENT_RADIO_AVAILABLE = 9; - protected static final int EVENT_RADIO_NOT_AVAILABLE = 10; - protected static final int EVENT_CONFERENCE_RESULT = 11; - protected static final int EVENT_SEPARATE_RESULT = 12; - protected static final int EVENT_ECT_RESULT = 13; - protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14; - + protected static final int EVENT_POLL_CALLS_RESULT = 1; + protected static final int EVENT_CALL_STATE_CHANGE = 2; + protected static final int EVENT_REPOLL_AFTER_DELAY = 3; + protected static final int EVENT_OPERATION_COMPLETE = 4; + protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; + + protected static final int EVENT_SWITCH_RESULT = 8; + protected static final int EVENT_RADIO_AVAILABLE = 9; + protected static final int EVENT_RADIO_NOT_AVAILABLE = 10; + protected static final int EVENT_CONFERENCE_RESULT = 11; + protected static final int EVENT_SEPARATE_RESULT = 12; + protected static final int EVENT_ECT_RESULT = 13; + protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14; + protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15; + protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16; protected void pollCallsWhenSafe() { needsPoll = true; diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index c6d1a4b..cd53b87 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -466,6 +466,61 @@ public interface CommandsInterface { 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); diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index a6b0480..cdbfd61 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -1350,10 +1350,14 @@ public interface Phone { /** * Retrieves the MIN for CDMA phones. */ - String getCdmaMin(); /** + * Retrieves PRL Version for CDMA phones + */ + String getCdmaPrlVersion(); + + /** * Retrieves the ESN for CDMA phones. */ String getEsn(); @@ -1464,14 +1468,12 @@ public interface Phone { * @param what User-defined message code. * @param obj User object. */ - // TODO(Moto) TODO: Remove when generic implemented 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. */ - // TODO(Moto): Remove when generic implemented void unregisterForCallWaiting(Handler h); @@ -1513,6 +1515,109 @@ public interface Phone { */ 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 diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index c92cf3d..c34f26e 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -694,6 +694,12 @@ public abstract class PhoneBase implements Phone { return null; } + public String getCdmaPrlVersion(){ + // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. + Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); + return null; + } + public void sendBurstDtmf(String dtmfString, Message onComplete) { // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); @@ -746,6 +752,46 @@ public abstract class PhoneBase implements Phone { mCM.unregisterForDisplayInfo(h); } + public void registerForNumberInfo(Handler h, int what, Object obj) { + mCM.registerForNumberInfo(h, what, obj); + } + + public void unregisterForNumberInfo(Handler h) { + mCM.unregisterForNumberInfo(h); + } + + public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { + mCM.registerForRedirectedNumberInfo(h, what, obj); + } + + public void unregisterForRedirectedNumberInfo(Handler h) { + mCM.unregisterForRedirectedNumberInfo(h); + } + + public void registerForLineControlInfo(Handler h, int what, Object obj) { + mCM.registerForLineControlInfo( h, what, obj); + } + + public void unregisterForLineControlInfo(Handler h) { + mCM.unregisterForLineControlInfo(h); + } + + public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { + mCM.registerFoT53ClirlInfo(h, what, obj); + } + + public void unregisterForT53ClirInfo(Handler h) { + mCM.unregisterForT53ClirInfo(h); + } + + public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { + mCM.registerForT53AudioControlInfo( h, what, obj); + } + + public void unregisterForT53AudioControlInfo(Handler h) { + mCM.unregisterForT53AudioControlInfo(h); + } + public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index 7d968f9..4bb24dc 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -418,6 +418,10 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.getCdmaMin(); } + public String getCdmaPrlVersion() { + return mActivePhone.getCdmaPrlVersion(); + } + public String getLine1AlphaTag() { return mActivePhone.getLine1AlphaTag(); } @@ -745,6 +749,46 @@ public class PhoneProxy extends Handler implements Phone { 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); } diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 7b486e7..e7f0c49 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -2233,7 +2233,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { 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 = responseCdmaInfoRec(p); break; + case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break; case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break; default: @@ -2490,23 +2490,18 @@ public final class RIL extends BaseCommands implements CommandsInterface { break; case RIL_UNSOL_CDMA_INFO_REC: - if (RILJ_LOGD) unsljLog(response); - - CdmaInformationRecords infoRec = (CdmaInformationRecords) ret; - if (infoRec.isDispInfo) { - if (mDisplayInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.cdmaDisplayInfoRecord); + ArrayList<CdmaInformationRecords> listInfoRecs; - mDisplayInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.cdmaDisplayInfoRecord, null)); - } + try { + listInfoRecs = (ArrayList<CdmaInformationRecords>)ret; + } catch (ClassCastException e) { + Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e); + break; } - if (infoRec.isSignInfo) { - if (mSignalInfoRegistrants != null) { - if (RILJ_LOGD) unsljLogRet(response, infoRec.cdmaSignalInfoRecord); - mSignalInfoRegistrants.notifyRegistrants( - new AsyncResult (null, infoRec.cdmaSignalInfoRecord, null)); - } + + for (CdmaInformationRecords rec : listInfoRecs) { + if (RILJ_LOGD) unsljLogRet(response, rec); + notifyRegistrantsCdmaInfoRec(rec); } break; @@ -2764,30 +2759,24 @@ public final class RIL extends BaseCommands implements CommandsInterface { dc.als = p.readInt(); voiceSettings = p.readInt(); dc.isVoice = (0 == voiceSettings) ? false : true; - int voicePrivacy = p.readInt(); - dc.isVoicePrivacy = (0 != voicePrivacy); + dc.isVoicePrivacy = (0 != p.readInt()); dc.number = p.readString(); int np = p.readInt(); dc.numberPresentation = DriverCall.presentationFromCLIP(np); dc.name = p.readString(); dc.namePresentation = p.readInt(); - // Make sure there's a leading + on addresses with a TOA - // of 145 - - dc.number = PhoneNumberUtils.stringFromStringAndTOA( - dc.number, dc.TOA); + // Make sure there's a leading + on addresses with a TOA of 145 + dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA); response.add(dc); - if ( RILConstants.CDMA_VOICE_PRIVACY == voicePrivacy ) { + if (dc.isVoicePrivacy) { mVoicePrivacyOnRegistrants.notifyRegistrants(); - Log.d(LOG_TAG, "InCall VoicePrivacy is enabled: " + - Integer.toString(voicePrivacy)); + Log.d(LOG_TAG, "InCall VoicePrivacy is enabled"); } else { mVoicePrivacyOffRegistrants.notifyRegistrants(); - Log.d(LOG_TAG, "InCall VoicePrivacy is disabled: " + - Integer.toString(voicePrivacy)); + Log.d(LOG_TAG, "InCall VoicePrivacy is disabled"); } } @@ -2880,15 +2869,19 @@ public final class RIL extends BaseCommands implements CommandsInterface { numServiceCategories = p.readInt(); if (numServiceCategories == 0) { + // TODO(Teleca) TODO(Moto): The logic of providing default + // values should not be done by this transport layer. And + // needs to be done by the vendor ril or application logic. + // TODO(Google): Remove ASAP int numInts; numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1; response = new int[numInts]; - // Indicate that a zero length table was received - response[0] = 0; // TODO(Moto): This is very strange, please explain why. + // 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 + // 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; @@ -2922,66 +2915,24 @@ public final class RIL extends BaseCommands implements CommandsInterface { return response; } - private Object - responseCdmaInfoRec(Parcel p) { - int infoRecordName; - CdmaInformationRecords records = new CdmaInformationRecords(); + private ArrayList<CdmaInformationRecords> + responseCdmaInformationRecord(Parcel p) { + int numberOfInfoRecs; + ArrayList<CdmaInformationRecords> response; + + /** + * Loop through all of the information records unmarshalling them + * and converting them to Java Objects. + */ + numberOfInfoRecs = p.readInt(); + response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs); - int numberOfInfoRecs = p.readInt(); for (int i = 0; i < numberOfInfoRecs; i++) { - infoRecordName = p.readInt(); - switch(infoRecordName) { - case CdmaInformationRecords.RIL_CDMA_DISPLAY_INFO_REC: - case CdmaInformationRecords.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: - records.setDispInfo(p.readString()); - break; - case CdmaInformationRecords.RIL_CDMA_SIGNAL_INFO_REC: - records.setSignInfo(p.readInt(), p.readInt(), p.readInt(), p.readInt()); - break; - // InfoReocords with names as below aren't supported in AFW yet - case CdmaInformationRecords.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: - case CdmaInformationRecords.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: - case CdmaInformationRecords.RIL_CDMA_CONNECTED_NUMBER_INFO_REC: - // TODO(Moto) implement - p.readString(); // number - p.readInt(); // number_type - p.readInt(); // number_plan - p.readInt(); // pi - p.readInt(); // si - break; - case CdmaInformationRecords.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: - // TODO(Moto) implement - p.readString(); // redirecting number - p.readInt(); // number_type - p.readInt(); // number_plan - p.readInt(); // pi - p.readInt(); // si - p.readInt(); // reason - break; - case CdmaInformationRecords.RIL_CDMA_LINE_CONTROL_INFO_REC: - // TODO(Moto) implement - p.readInt(); // PolarityIncluded - p.readInt(); // Toggle - p.readInt(); // Reverse - p.readInt(); // PowerDenial - break; - case CdmaInformationRecords.RIL_CDMA_T53_CLIR_INFO_REC: - // TODO(Moto) implement - p.readInt(); // Cause - break; - case CdmaInformationRecords.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: - // TODO(Moto) implement - p.readInt(); // upLink - p.readInt(); // downLink - break; - case CdmaInformationRecords.RIL_CDMA_T53_RELEASE_INFO_REC: - // TODO(Moto) implement unknown fall through - default: - throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got " - + records.recordToString(infoRecordName) + " "); - } + CdmaInformationRecords InfoRec = new CdmaInformationRecords(p); + response.add(InfoRec); } - return records; + + return response; } private Object @@ -3012,6 +2963,54 @@ public final class RIL extends BaseCommands implements CommandsInterface { 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) { /* diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 26995ef..0e9e244 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -78,9 +78,6 @@ public interface RILConstants { int CDM_TTY_HCO_MODE = 2; int CDM_TTY_VCO_MODE = 3; - byte CDMA_VOICE_PRIVACY = 0x70; /* "p" value used in Ril_Call.isVoice if Privacy - is active */ - /* cat include/telephony/ril.h | \ egrep '^#define' | \ diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index c78ceae..2abb097 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -185,8 +185,9 @@ public class TelephonyIntents { /** * <p>Broadcast Action: It indicates the Emergency callback mode blocks datacall/sms * <p class="note">. + * This is to pop up a notice to show user that the phone is in emergency callback mode + * and atacalls and outgoing sms are blocked. */ - // TODO(Moto): What is the use case, who is interested in this? public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS"; @@ -202,6 +203,11 @@ public class TelephonyIntents { // TODO(Moto): Generally broadcast intents are for use to allow entities which // may not know about each other to "communicate". This seems quite specific // and maybe using the registrant style would be better. + + // Moto: Since this is used for apps not in the same process of phone, can the + // registrant style be used? (Ling Li says: Maybe the "app" can request rather + // than save the MDN each time and this intent would not be necessary?) + // Moto response: Moto internal discussion is on-going. public static final String ACTION_CDMA_OTA_MDN_CHANGED = "android.intent.action.ACTION_MDN_STATE_CHANGED"; diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 4e8950f..290e1fc 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -101,4 +101,9 @@ public interface TelephonyProperties /** Indicate if phone is in emergency callback mode */ static final String PROPERTY_INECM_MODE = "ril.cdma.inecmmode"; + /** Indicate the timer value for exiting emergency callback mode */ + static final String PROPERTY_ECM_EXIT_TIMER = "ro.cdma.ecmexittimer"; + + /** The international dialing prefix conversion string */ + static final String PROPERTY_IDP_STRING = "ro.cdma.idpstring"; } diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 0ebe507..6ba09ce 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -34,9 +34,6 @@ import android.telephony.SignalStrength; import android.text.TextUtils; import android.util.Log; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_INECM_MODE; - import com.android.internal.telephony.CallStateException; import com.android.internal.telephony.CommandException; import com.android.internal.telephony.CommandsInterface; @@ -66,6 +63,9 @@ public class CDMAPhone extends PhoneBase { static final String LOG_TAG = "CDMA"; private static final boolean LOCAL_DEBUG = true; + // Default Emergency Callback Mode exit timer + private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 30000; + //***** Instance Variables CdmaCallTracker mCT; CdmaSMSDispatcher mSMS; @@ -144,8 +144,8 @@ public class CDMAPhone extends PhoneBase { SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, new Integer(RILConstants.CDMA_PHONE).toString()); - // TODO(Moto): Is this needed to handle phone crashes and/or power cycling? - String inEcm=SystemProperties.get(PROPERTY_INECM_MODE, "false"); + // This is needed to handle phone process crashes + String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); mIsPhoneInECMState = inEcm.equals("true"); } @@ -288,16 +288,10 @@ public class CDMAPhone extends PhoneBase { if (fc != null) { //mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null)); fc.processCode(); - } else { - FeatureCode digits = new FeatureCode(this); - // use dial number as poundString - digits.poundString = newDialString; - digits.processCode(); + return null; } - return null; - } else { - return mCT.dial(newDialString); } + return mCT.dial(newDialString); } public SignalStrength getSignalStrength() { @@ -388,6 +382,10 @@ public class CDMAPhone extends PhoneBase { return mSST.getMdnNumber(); } + public String getCdmaPrlVersion(){ + return mRuimRecords.getPrlVersion(); + } + public String getCdmaMIN() { return mSST.getCdmaMin(); } @@ -420,8 +418,13 @@ public class CDMAPhone extends PhoneBase { } public String getSubscriberId() { - Log.e(LOG_TAG, "method getSubscriberId for IMSI is NOT supported in CDMA!"); - return null; + // Subscriber ID is the combination of MCC+MNC+MIN as CDMA IMSI + // TODO(Moto): Replace with call to mRuimRecords.getIMSI_M() when implemented. + if ((getServiceState().getOperatorNumeric() != null) && (getCdmaMIN() != null)) { + return (getServiceState().getOperatorNumeric() + getCdmaMIN()); + } else { + return null; + } } public boolean canConference() { @@ -513,11 +516,11 @@ public class CDMAPhone extends PhoneBase { } public void registerForCallWaiting(Handler h, int what, Object obj) { - Log.e(LOG_TAG, "method registerForCallWaiting is NOT yet supported in CDMA"); + mCT.registerForCallWaiting(h, what, obj); } public void unregisterForCallWaiting(Handler h) { - Log.e(LOG_TAG, "method unregisterForCallWaiting is NOT yet supported in CDMA"); + mCT.unregisterForCallWaiting(h); } public String getIpAddress(String apnType) { @@ -850,12 +853,12 @@ public class CDMAPhone extends PhoneBase { mIsPhoneInECMState = true; // notify change sendEmergencyCallbackModeChange(); - setSystemProperty(PROPERTY_INECM_MODE, "true"); + setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true"); // Post this runnable so we will automatically exit // if no one invokes exitEmergencyCallbackMode() directly. - // TODO(Moto): Get the delay a property so it can be adjusted - long delayInMillis = 300000; // 30,000 millis == 5 minutes + long delayInMillis = SystemProperties.getLong( + TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); h.postDelayed(mExitEcmRunnable, delayInMillis); } } @@ -874,7 +877,7 @@ public class CDMAPhone extends PhoneBase { if (ar.exception == null) { if (mIsPhoneInECMState) { mIsPhoneInECMState = false; - setSystemProperty(PROPERTY_INECM_MODE, "false"); + setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false"); } // send an Intent sendEmergencyCallbackModeChange(); @@ -911,7 +914,7 @@ public class CDMAPhone extends PhoneBase { } if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result); - setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result); + setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result); } break; @@ -977,7 +980,7 @@ public class CDMAPhone extends PhoneBase { Log.d(LOG_TAG, "ERI read, notify registrants"); mEriFileLoadedRegistrants.notifyRegistrants(); } - setSystemProperty(PROPERTY_INECM_MODE,"false"); + setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE,"false"); } break; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java index 34514d9..e8724c2 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java @@ -181,9 +181,7 @@ public final class CdmaCall extends Call { */ void onHangupLocal() { - for (int i = 0, s = connections.size() - ; i < s; i++ - ) { + for (int i = 0, s = connections.size(); i < s; i++) { CdmaConnection cn = (CdmaConnection)connections.get(i); cn.onHangupLocal(); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java index c02fcd4..719e92c 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java @@ -58,6 +58,7 @@ public final class CdmaCallTracker extends CallTracker { CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS]; RegistrantList voiceCallEndedRegistrants = new RegistrantList(); RegistrantList voiceCallStartedRegistrants = new RegistrantList(); + RegistrantList callWaitingRegistrants = new RegistrantList(); // connections dropped durin last poll @@ -93,13 +94,15 @@ public final class CdmaCallTracker extends CallTracker { cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null); cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null); + cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null); + foregroundCall.setGeneric(false); } public void dispose() { cm.unregisterForCallStateChanged(this); cm.unregisterForOn(this); cm.unregisterForNotAvailable(this); - + cm.unregisterForCallWaitingInfo(this); for(CdmaConnection c : connections) { try { if(c != null) hangup(c); @@ -143,6 +146,15 @@ public final class CdmaCallTracker extends CallTracker { voiceCallEndedRegistrants.remove(h); } + public void registerForCallWaiting(Handler h, int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + callWaitingRegistrants.add(r); + } + + public void unregisterForCallWaiting(Handler h) { + callWaitingRegistrants.remove(h); + } + private void fakeHoldForegroundBeforeDial() { List<Connection> connCopy; @@ -170,34 +182,24 @@ public final class CdmaCallTracker extends CallTracker { throw new CallStateException("cannot dial in current state"); } + + // We are initiating a call therefore even if we previously + // didn't know the state (i.e. Generic was true) we now know + // and therefore can set Generic to false. + foregroundCall.setGeneric(false); + // The new call must be assigned to the foreground call. // That call must be idle, so place anything that's // there on hold if (foregroundCall.getState() == CdmaCall.State.ACTIVE) { - // this will probably be done by the radio anyway - // but the dial might fail before this happens - // and we need to make sure the foreground call is clear - // for the newly dialed connection - switchWaitingOrHoldingAndActive(); - - // Fake local state so that - // a) foregroundCall is empty for the newly dialed connection - // b) hasNonHangupStateChanged remains false in the - // next poll, so that we don't clear a failed dialing call - fakeHoldForegroundBeforeDial(); - } - - if (foregroundCall.getState() != CdmaCall.State.IDLE) { - //we should have failed in !canDial() above before we get here - throw new CallStateException("cannot dial in current state"); + return dialThreeWay(dialString); } pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall); hangupPendingMO = false; if (pendingMO.address == null || pendingMO.address.length() == 0 - || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0 - ) { + || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) { // Phone number is invalid pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER; @@ -231,19 +233,39 @@ public final class CdmaCallTracker extends CallTracker { return dial(dialString, CommandsInterface.CLIR_DEFAULT); } - void - acceptCall () throws CallStateException { - // FIXME if SWITCH fails, should retry with ANSWER - // in case the active/holding call disappeared and this - // is no longer call waiting + private Connection + dialThreeWay (String dialString) { + if (!foregroundCall.isIdle()) { + // Attach the new connection to foregroundCall + pendingMO = new CdmaConnection(phone.getContext(), + dialString, this, foregroundCall); + cm.sendCDMAFeatureCode(pendingMO.address, + obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA)); + return pendingMO; + } + return null; + } + void + acceptCall() throws CallStateException { if (ringingCall.getState() == CdmaCall.State.INCOMING) { Log.i("phone", "acceptCall: incoming..."); // Always unmute when answering a new call setMute(false); cm.acceptCall(obtainCompleteMessage()); - } else if (ringingCall.getState() == CdmaCall.State.WAITING) { - setMute(false); + } else if ((foregroundCall.connections.size() > 0) && + (ringingCall.getState() == CdmaCall.State.WAITING)) { + // TODO(Moto): jsh asks, "Is this check necessary? I don't think it should be + // possible to have no fg connection and a WAITING call, but if we should hit + // this situation, is a CallStateExcetion appropriate?" + CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection()); + + // Since there is no network response for supplimentary + // service for CDMA, we assume call waiting is answered. + // ringing Call state change to idle is in CdmaCall.detach + // triggered by updateParent. + cwConn.updateParent(ringingCall, foregroundCall); + cwConn.onConnectedInOrOut(); switchWaitingOrHoldingAndActive(); } else { throw new CallStateException("phone not ringing"); @@ -267,14 +289,14 @@ public final class CdmaCallTracker extends CallTracker { if (ringingCall.getState() == CdmaCall.State.INCOMING) { throw new CallStateException("cannot be in the incoming state"); } else { - cm.sendCDMAFeatureCode("", obtainCompleteMessage(EVENT_SWITCH_RESULT)); + flashAndSetGenericTrue(); } } void conference() throws CallStateException { - // three way calls in CDMA will be handled by feature codes - Log.e(LOG_TAG, "conference: not possible in CDMA"); + // Should we be checking state? + flashAndSetGenericTrue(); } void @@ -307,6 +329,7 @@ public final class CdmaCallTracker extends CallTracker { pendingMO == null && !ringingCall.isRinging() && (!foregroundCall.getState().isAlive() + || (foregroundCall.getState() == CdmaCall.State.ACTIVE) || !backgroundCall.getState().isAlive()); return ret; @@ -495,9 +518,24 @@ public final class CdmaCallTracker extends CallTracker { } hasNonHangupStateChanged = true; } else if (conn != null && dc == null) { - // Connection missing in CLCC response that we were - // tracking. - droppedDuringPoll.add(conn); + int count = foregroundCall.connections.size(); + if (count == 0) { + // Handle an unanswered MO/MT call, there is no + // foregroundCall connections at this time. + droppedDuringPoll.add(conn); + } else { + // Loop through foreground call connections as + // it contains the known logical connections. + for (int n = 0; n < count; n++) { + CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n); + droppedDuringPoll.add(cn); + } + // TODO(Moto): jsh asks, "Are we sure we don't need to do this for + // ringingCall as well? What if there's a WAITING call (ie, UI timer + // hasn't expired, moving it to DISCONNECTED)? How/when will it + // transition to DISCONNECTED?" + } + foregroundCall.setGeneric(false); // Dropped connections are removed from the CallTracker // list but kept in the Call list connections[i] = null; @@ -634,6 +672,18 @@ public final class CdmaCallTracker extends CallTracker { if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); hangupPendingMO = true; + } else if ((conn.getCall() == ringingCall) + && (ringingCall.getState() == CdmaCall.State.WAITING)) { + // Handle call waiting hang up case. + // + // The ringingCall state will change to IDLE in CdmaCall.detach + // if the ringing call connection size is 0. We don't specifically + // set the ringing call state to IDLE here to avoid a race condition + // where a new call waiting could get a hang up from an old call + // waiting ringingCall. + // TODO(Moto): jsh asks, "Should we call conn.ondisconnect() here or Somewhere?" + ringingCall.detach(conn); + return; } else { try { cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage()); @@ -768,6 +818,16 @@ public final class CdmaCallTracker extends CallTracker { return null; } + private void flashAndSetGenericTrue() throws CallStateException { + cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT)); + + // Set generic to true because in CDMA it is not known what + // the status of the call is after a call waiting is answered, + // 3 way call merged or a switch between calls. + foregroundCall.setGeneric(true); + phone.notifyCallStateChanged(); + } + private Phone.SuppService getFailedService(int what) { switch (what) { case EVENT_SWITCH_RESULT: @@ -789,6 +849,30 @@ public final class CdmaCallTracker extends CallTracker { pollCallsWhenSafe(); } + private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) { + if (callWaitingRegistrants != null) { + callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null)); + } + } + + private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) { + // Check how many connections in foregroundCall. + // If the connection in foregroundCall is more + // than one, then the connection information is + // not reliable anymore since it means either + // call waiting is connected or 3 way call is + // dialed before, so set generic. + if (foregroundCall.connections.size() > 1 ) { + foregroundCall.setGeneric(true); + } + + // Create a new CdmaConnection which attaches itself to ringingCall. + ringingCall.setGeneric(false); + new CdmaConnection(phone.getContext(), cw, this, ringingCall); + + // Finally notify application + notifyCallWaitingInfo(cw); + } //****** Overridden from Handler public void @@ -811,13 +895,13 @@ public final class CdmaCallTracker extends CallTracker { break; case EVENT_OPERATION_COMPLETE: - ar = (AsyncResult)msg.obj; operationComplete(); break; case EVENT_SWITCH_RESULT: - ar = (AsyncResult)msg.obj; - operationComplete(); + // In GSM call operationComplete() here which gets the + // current call list. But in CDMA there is no list so + // there is nothing to do. break; case EVENT_GET_LAST_CALL_FAIL_CAUSE: @@ -871,6 +955,22 @@ public final class CdmaCallTracker extends CallTracker { phone.unsetOnEcbModeExitResponse(this); break; + case EVENT_CALL_WAITING_INFO_CDMA: + ar = (AsyncResult)msg.obj; + if (ar.exception == null) { + handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result); + Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received"); + } + break; + + case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA: + ar = (AsyncResult)msg.obj; + if (ar.exception == null) { + // Assume 3 way call is connected + pendingMO.onConnectedInOrOut(); + } + break; + default:{ throw new RuntimeException("unexpected event not handled"); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java index 32442f6..6fe7fe1 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java @@ -25,11 +25,14 @@ import android.os.Message; import android.os.PowerManager; import android.os.Registrant; import android.os.SystemClock; +import android.os.SystemProperties; import android.util.Config; import android.util.Log; +import android.text.TextUtils; + import android.telephony.PhoneNumberUtils; import android.telephony.ServiceState; - +import com.android.internal.telephony.TelephonyProperties; /** * {@hide} @@ -90,17 +93,7 @@ public class CdmaConnection extends Connection { //***** Constants static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000; static final int PAUSE_DELAY_MILLIS = 2 * 1000; - - // TODO(Moto): These should be come from a resourse file - // at a minimum as different carriers may want to use - // different characters and our general default is "," & ";". - // Furthermore Android supports contacts that have phone - // numbers entered as strings so '1-800-164flowers' would not - // be handled as expected. Both issues need to be resolved. - static final char CUSTOMERIZED_WAIT_CHAR_UPPER ='W'; - static final char CUSTOMERIZED_WAIT_CHAR_LOWER ='w'; - static final char CUSTOMERIZED_PAUSE_CHAR_UPPER ='P'; - static final char CUSTOMERIZED_PAUSE_CHAR_LOWER ='p'; + //***** Inner Classes class MyHandler extends Handler { @@ -147,19 +140,9 @@ public class CdmaConnection extends Connection { parent.attach(this, dc); } - CdmaConnection () { - owner = null; - h = null; - address = null; - index = -1; - parent = null; - isIncoming = true; - createTime = System.currentTimeMillis(); - } - - /** This is an MO call, created when dialing */ + /** This is an MO call/three way call, created when dialing */ /*package*/ - CdmaConnection (Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) { + CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) { createWakeLock(context); acquireWakeLock(); @@ -184,10 +167,36 @@ public class CdmaConnection extends Connection { if (parent != null) { this.parent = parent; - parent.attachFake(this, CdmaCall.State.DIALING); + + //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() { } @@ -363,16 +372,6 @@ public class CdmaConnection extends Connection { } } - /** - * Used for 3way call only - */ - void update (CdmaConnection c) { - address = c.address; - cnapName = c.cnapName; - cnapNamePresentation = c.cnapNamePresentation; - numberPresentation = c.numberPresentation; - } - public void cancelPostDial() { setPostDialState(PostDialState.CANCELLED); } @@ -408,7 +407,7 @@ public class CdmaConnection extends Connection { case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE: return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE; case CallFailCause.CDMA_DROP: - return DisconnectCause.LOST_SIGNAL; // TODO(Moto): wink/dave changed from CDMA_DROP; + return DisconnectCause.CDMA_DROP; case CallFailCause.CDMA_INTERCEPT: return DisconnectCause.CDMA_INTERCEPT; case CallFailCause.CDMA_REORDER: @@ -488,15 +487,14 @@ public class CdmaConnection extends Connection { } // A null cnapName should be the same as "" - if (null != dc.name) { - if (cnapName != dc.name) { - cnapName = dc.name; - changed = true; - } - } else { + if (TextUtils.isEmpty(dc.name) && !TextUtils.isEmpty(cnapName)) { + changed = true; cnapName = ""; - // TODO(Moto): Should changed = true if cnapName wasn't previously "" + } else if (dc.name.equals(cnapName) == false) { + changed = true; + cnapName = dc.name; } + log("--dssds----"+cnapName); cnapNamePresentation = dc.namePresentation; numberPresentation = dc.numberPresentation; @@ -631,21 +629,7 @@ public class CdmaConnection extends Connection { int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT); int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE); - // TODO(Moto): Courtesy of jsh; is this simpler expression equivalent? - // - // if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) { - // subStr = subStr.substring(0, wIndex); - // } else if (pIndex > 0) { - // subStr = subStr.substring(0, pIndex); - // } - - if (wIndex > 0 && pIndex > 0) { - if (wIndex > pIndex) { - subStr = subStr.substring(0, pIndex); - } else { - subStr = subStr.substring(0, wIndex); - } - } else if (wIndex > 0) { + if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) { subStr = subStr.substring(0, wIndex); } else if (pIndex > 0) { subStr = subStr.substring(0, pIndex); @@ -654,6 +638,16 @@ public class CdmaConnection extends Connection { 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() { @@ -795,114 +789,121 @@ public class CdmaConnection extends Connection { } private static boolean isPause(char c) { - if (c == CUSTOMERIZED_PAUSE_CHAR_UPPER || c == CUSTOMERIZED_PAUSE_CHAR_LOWER - || c == PhoneNumberUtils.PAUSE) { - return true; - } else { - return false; - } + return c == PhoneNumberUtils.PAUSE; } private static boolean isWait(char c) { - if (c == CUSTOMERIZED_WAIT_CHAR_LOWER || c == CUSTOMERIZED_WAIT_CHAR_UPPER - || c == PhoneNumberUtils.WAIT) { - return true; - } else { - return false; + return c == PhoneNumberUtils.WAIT; + } + + + + + // This function is to find the next PAUSE character index if + // multiple pauses in a row. Otherwise it finds the next non PAUSE or + // non WAIT character index. + private static int + findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) { + boolean wMatched = false; + int index = currIndex + 1; + int length = phoneNumber.length(); + while (index < length) { + char cNext = phoneNumber.charAt(index); + // if there is any W inside P/W sequence,mark it + if (isWait(cNext)) { + wMatched = true; + } + // if any characters other than P/W chars after P/W sequence + // we break out the loop and append the correct + if (!isWait(cNext) && !isPause(cNext)) { + break; + } + index++; + } + + // It means the PAUSE character(s) is in the middle of dial string + // and it needs to be handled one by one. + if ((index < length) && (index > (currIndex + 1)) && + ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) { + return (currIndex + 1); + } + return index; + } + + // This function returns either PAUSE or WAIT character to append. + // It is based on the next non PAUSE/WAIT character in the phoneNumber and the + // index for the current PAUSE/WAIT character + private static char + findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) { + char c = phoneNumber.charAt(currPwIndex); + char ret; + + // Append the PW char + ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT; + + // if there is a PAUSE in at the begining of PW character sequences, and this + // PW character sequences has more than 2 PAUSE and WAIT Characters,skip P, append W + if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 1))) { + ret = PhoneNumberUtils.WAIT; } + return ret; } + /** - * format string - * convert "+" to "011" - * handle corner cases for PAUSE/WAIT - * If PAUSE/WAIT sequence at the end,ignore them - * If PAUSE/WAIT sequence in the middle, then if there is any WAIT - * in PAUSE/WAIT sequence, treat them like WAIT - * If PAUSE followed by WAIT or WAIT followed by PAUSE in the middle, - * treat them like just PAUSE or WAIT + * format orignal dial string + * 1) convert international dialing prefix "+" to + * string specified per region + * + * 2) handle corner cases for PAUSE/WAIT dialing: + * + * If PAUSE/WAIT sequence at the end, ignore them. + * + * If consecutive PAUSE/WAIT sequence in the middle of the string, + * and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT. */ - private static String formatDialString(String phoneNumber) { + public static String formatDialString(String phoneNumber) { if (phoneNumber == null) { return null; } int length = phoneNumber.length(); StringBuilder ret = new StringBuilder(); - - // TODO(Moto): Modifying the for loop index is confusing, a - // while loop is probably better and overall this code is - // hard to follow. If this was routine was refactored and - // used several private methods with good names to make it - // easier to follow. - for (int i = 0; i < length; i++) { - char c = phoneNumber.charAt(i); - + char c; + int currIndex = 0; + while (currIndex < length) { + c = phoneNumber.charAt(currIndex); if (PhoneNumberUtils.isDialable(c)) { if (c == '+') { - // TODO(Moto): Is this valid for "all" countries???? - // should probably be pulled from a resource based - // on current contry code (MCC). - ret.append("011"); + String ps = null; + SystemProperties.get(TelephonyProperties.PROPERTY_IDP_STRING, ps); + if (TextUtils.isEmpty(ps)) { + ps = "011"; + } + ret.append(ps); } else { ret.append(c); } } else if (isPause(c) || isWait(c)) { - if (i < length - 1) { // if PAUSE/WAIT not at the end - int index = 0; - boolean wMatched = false; - for (index = i + 1; index < length; index++) { - 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; + if (currIndex < length - 1) { + // if PW not at the end + int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex); + // If there is non PW char following PW sequence + if (nextIndex < length) { + char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex); + ret.append(pC); + // If PW char is immediately followed by non-PW char + if (nextIndex > (currIndex + 1)) { + currIndex = nextIndex - 1; } + } else if (nextIndex == length) { + // It means PW characters at the end, ignore + currIndex = length - 1; } - if (index == length) { - // it means there is no dialable character after PAUSE/WAIT - i = length - 1; - break; - } else {// means index <length - if (isPause(c)) { - c = PhoneNumberUtils.PAUSE; - } else if (isWait(c)) { - c = PhoneNumberUtils.WAIT; - } - - if (index == i + 1) { - ret.append(c); - } else if (isWait(c)) { - // for case like 123WP456 =123P456 - if ((index == i + 2) && isPause(phoneNumber.charAt(index - 1))) { - // skip W,append P - ret.append(PhoneNumberUtils.PAUSE); - } else { - // append W - ret.append(c); - } - i = index - 1; - } else if (isPause(c)) { - - // for case like 123PW456 =123W456, skip p, append W - // or there is 1 W in between, treat the whole PW - // sequence as W - if (wMatched == true) { - // skip P,append W - ret.append(PhoneNumberUtils.WAIT); - i = index - 1; - } else { - ret.append(c); - } - } // end of pause case - } // end of index <length, it means dialable characters after P/W } - } else { // if it's characters other than P/W + } else { ret.append(c); } + currIndex++; } return ret.toString(); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java index 93a6aa4..7402769 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java @@ -16,8 +16,14 @@ 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; @@ -30,34 +36,54 @@ public final class CdmaInformationRecords { public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9; public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10; - public boolean isDispInfo; - public boolean isSignInfo; - public String cdmaDisplayInfoRecord; - public int[] cdmaSignalInfoRecord; + 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; - private static final int ALPHA_LEN_FOR_DISPLAY_INFO = 64; + 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; - public CdmaInformationRecords() { - isDispInfo = false; - isSignInfo = false; - } + case RIL_CDMA_SIGNAL_INFO_REC: + record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt()); + break; - public void setDispInfo(String resString) { - isDispInfo = true; - cdmaDisplayInfoRecord = resString; - } + case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: + record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(), + p.readInt(), p.readInt(), p.readInt()); + break; + + case RIL_CDMA_LINE_CONTROL_INFO_REC: + record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(), + p.readInt()); + break; + + case RIL_CDMA_T53_CLIR_INFO_REC: + record = new CdmaT53ClirInfoRec(p.readInt()); + break; + + case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: + record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt()); + break; + + case RIL_CDMA_T53_RELEASE_INFO_REC: + // TODO(Moto): WHAT to do, for now fall through and throw exception + default: + throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got " + + CdmaInformationRecords.idToString(id) + " "); - public void setSignInfo(int isPresent, int signalType, int alertPitch, int signal) { - isSignInfo = true; - cdmaSignalInfoRecord = new int[4]; - cdmaSignalInfoRecord[0] = isPresent; - cdmaSignalInfoRecord[1] = signalType; - cdmaSignalInfoRecord[2] = alertPitch; - cdmaSignalInfoRecord[3] = signal; + } } - public String recordToString (int record) { - switch(record) { + 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"; @@ -72,4 +98,166 @@ public final class CdmaInformationRecords { default: return "<unknown record>"; } } + + /** + * Signal Information record from 3GPP2 C.S005 3.7.5.5 + */ + public static class CdmaSignalInfoRec { + public boolean isPresent; /* non-zero if signal information record is present */ + public int signalType; + public int alertPitch; + public int signal; + + public CdmaSignalInfoRec() {} + + public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) { + this.isPresent = isPresent != 0; + this.signalType = signalType; + this.alertPitch = alertPitch; + this.signal = signal; + } + + @Override + public String toString() { + return "CdmaSignalInfo: {" + + " isPresent: " + isPresent + + ", signalType: " + signalType + + ", alertPitch: " + alertPitch + + ", signal: " + signal + + " }"; + } + } + + public static class CdmaDisplayInfoRec { + public int id; + public String alpha; + + public CdmaDisplayInfoRec(int id, String alpha) { + this.id = id; + this.alpha = alpha; + } + + @Override + public String toString() { + return "CdmaDisplayInfoRec: {" + + " id: " + CdmaInformationRecords.idToString(id) + + ", alpha: " + alpha + + " }"; + } + } + + public static class CdmaNumberInfoRec { + public int id; + public String number; + public byte numberType; + public byte numberPlan; + public byte pi; + public byte si; + + public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi, + int si) { + this.number = number; + this.numberType = (byte)numberType; + this.numberPlan = (byte)numberPlan; + this.pi = (byte)pi; + this.si = (byte)si; + } + + @Override + public String toString() { + return "CdmaNumberInfoRec: {" + + " id: " + CdmaInformationRecords.idToString(id) + + ", number: " + number + + ", numberType: " + numberType + + ", numberPlan: " + numberPlan + + ", pi: " + pi + + ", si: " + si + + " }"; + } + } + + public static class CdmaRedirectingNumberInfoRec { + public static final int REASON_UNKNOWN = 0; + public static final int REASON_CALL_FORWARDING_BUSY = 1; + public static final int REASON_CALL_FORWARDING_NO_REPLY = 2; + public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9; + public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10; + public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15; + + public CdmaNumberInfoRec numberInfoRec; + public int redirectingReason; + + public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan, + int pi, int si, int reason) { + numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, + number, numberType, numberPlan, pi, si); + redirectingReason = reason; + } + + @Override + public String toString() { + return "CdmaNumberInfoRec: {" + + " numberInfoRec: " + numberInfoRec + + ", redirectingReason: " + redirectingReason + + " }"; + } + } + + public static class CdmaLineControlInfoRec { + public byte lineCtrlPolarityIncluded; + public byte lineCtrlToggle; + public byte lineCtrlReverse; + public byte lineCtrlPowerDenial; + + public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle, + int lineCtrlReverse, int lineCtrlPowerDenial) { + this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded; + this.lineCtrlToggle = (byte)lineCtrlToggle; + this.lineCtrlReverse = (byte)lineCtrlReverse; + this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial; + } + + @Override + public String toString() { + return "CdmaLineControlInfoRec: {" + + " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded + + " lineCtrlToggle: " + lineCtrlToggle + + " lineCtrlReverse: " + lineCtrlReverse + + " lineCtrlPowerDenial: " + lineCtrlPowerDenial + + " }"; + } + } + + public static class CdmaT53ClirInfoRec { + public byte cause; + + public CdmaT53ClirInfoRec(int cause) { + this.cause = (byte)cause; + } + + @Override + public String toString() { + return "CdmaT53ClirInfoRec: {" + + " cause: " + cause + + " }"; + } + } + + public static class CdmaT53AudioControlInfoRec { + public byte uplink; + public byte downlink; + + public CdmaT53AudioControlInfoRec(int uplink, int downlink) { + this.uplink = (byte) uplink; + this.downlink = (byte) downlink; + } + + @Override + public String toString() { + return "CdmaT53AudioControlInfoRec: {" + + " uplink: " + uplink + + " downlink: " + downlink + + " }"; + } + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 12ceeaf..0be09b9 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -19,8 +19,11 @@ package com.android.internal.telephony.cdma; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; +import android.content.ContentValues; import android.content.Intent; import android.database.ContentObserver; +import android.database.SQLException; +import android.net.Uri; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; @@ -32,6 +35,7 @@ import android.os.SystemProperties; import android.provider.Checkin; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; +import android.provider.Telephony; import android.provider.Telephony.Intents; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -134,6 +138,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { static final String LOG_TAG = "CDMA"; private ContentResolver cr; + private String currentCarrier = null; private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { @Override @@ -203,6 +208,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { cr.unregisterContentObserver(this.mAutoTimeObserver); } + @Override protected void finalize() { if (DBG) log("CdmaServiceStateTracker finalized"); } @@ -265,10 +271,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { EVENT_GET_LOC_DONE_CDMA, onComplete)); } - - //***** Overridden from ServiceStateTracker - public void - handleMessage (Message msg) { + @Override + public void handleMessage (Message msg) { AsyncResult ar; int[] ints; String[] strings; @@ -434,8 +438,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { //***** Private Instance Methods - protected void setPowerStateToDesired() - { + @Override + protected void setPowerStateToDesired() { // If we want it on and it's off, turn it on if (mDesiredPowerState && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) { @@ -470,6 +474,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } // Otherwise, we're in the desired state } + @Override protected void updateSpnDisplay() { String spn = ""; boolean showSpn = false; @@ -511,8 +516,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { * Handle the result of one of the pollState()-related requests */ - protected void - handlePollStateResult (int what, AsyncResult ar) { + @Override + protected void handlePollStateResult (int what, AsyncResult ar) { int ints[]; String states[]; @@ -624,11 +629,32 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { if (opNames != null && opNames.length >= 3) { if (cm.getRadioState().isNVReady()) { // In CDMA in case on NV the ss.mOperatorAlphaLong is set later with the - // ERI text, so here is ignored what is coming from the modem + // ERI text, so here it is ignored what is coming from the modem newSS.setOperatorName(null, opNames[1], opNames[2]); } else { newSS.setOperatorName(opNames[0], opNames[1], opNames[2]); } + + if (!(opNames[2].equals(currentCarrier))) { + // TODO(Moto): jsh asks, "This uses the MCC+MNC of the current registered + // network to set the "current" entry in the APN table. But the correct + // entry should be the MCC+MNC that matches the subscribed operator + // (eg, phone issuer). These can be different when roaming." + try { + // Set the current field of the telephony provider according to + // the CDMA's operator + Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); + ContentValues map = new ContentValues(); + map.put(Telephony.Carriers.NUMERIC, opNames[2]); + cr.insert(uri, map); + // save current carrier for the next time check + currentCarrier = opNames[2]; + } catch (SQLException e) { + Log.e(LOG_TAG, "Can't store current operator", e); + } + } else { + Log.i(LOG_TAG, "current carrier is not changed"); + } } else { Log.w(LOG_TAG, "error parsing opNames"); } diff --git a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java index 85fe6dc..23a4ac7 100644 --- a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java +++ b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java @@ -84,7 +84,6 @@ public final class FeatureCode extends Handler implements MmiCode { CDMAPhone phone; Context context; - CdmaConnection suppConn; String action; // '*' in CDMA String sc; // Service Code String poundString; // Entire Flash string @@ -237,17 +236,9 @@ public final class FeatureCode extends Handler implements MmiCode { } /** Process a Flash Code...anything that isn't a dialing number */ - void processCode () { + void processCode() { Log.d(LOG_TAG, "send feature code..."); - if (this.poundString != null) { - // TODO(Moto): Is suppConn going away? - suppConn = new CdmaConnection(phone.getContext(), this.poundString, phone.mCT, null); - phone.mCM.sendCDMAFeatureCode(suppConn.address, - obtainMessage(EVENT_CDMA_FLASH_COMPLETED)); - } else { - phone.mCM.sendCDMAFeatureCode(this.poundString, - obtainMessage(EVENT_CDMA_FLASH_COMPLETED)); - } + phone.mCM.sendCDMAFeatureCode(this.poundString, obtainMessage(EVENT_CDMA_FLASH_COMPLETED)); } /** Called from CDMAPhone.handleMessage; not a Handler subclass */ @@ -268,7 +259,6 @@ public final class FeatureCode extends Handler implements MmiCode { } else { state = State.COMPLETE; message = context.getText(com.android.internal.R.string.fcComplete); - suppConn.processNextPostDialChar(); } phone.onFeatureCodeDone(this); break; diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index 7edd30f..c7e61da 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -16,19 +16,17 @@ package com.android.internal.telephony.cdma; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; import android.os.Registrant; import android.util.Log; -import static com.android.internal.telephony.TelephonyProperties.*; import com.android.internal.telephony.AdnRecord; import com.android.internal.telephony.AdnRecordCache; import com.android.internal.telephony.AdnRecordLoader; import com.android.internal.telephony.CommandsInterface; +import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.cdma.RuimCard; import com.android.internal.telephony.gsm.MccTable; @@ -55,8 +53,13 @@ public final class RuimRecords extends IccRecords { //***** Instance Variables - String spn; - int spnDisplayCondition; + private String mImsi; + private String mMyMobileNumber; + private String mSid; + private String mNid; + private String mMin2Min1; + + private String mPrlVersion; //***** Event Constants @@ -122,8 +125,8 @@ public final class RuimRecords extends IccRecords { adnCache.reset(); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null); - phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null); + phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, null); + phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null); // recordsRequested is set to false indicating that the SIM // read requests made so far are not valid. This is set to @@ -131,6 +134,25 @@ public final class RuimRecords extends IccRecords { recordsRequested = false; } + /** Returns null if RUIM is not yet ready */ + public String getIMSI_M() { + // TODO(Moto): mImsi is not initialized, fix. + return mImsi; + } + + 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 @@ -155,6 +177,30 @@ public final class RuimRecords extends IccRecords { } } + /** + * 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; + } + + // TODO(Moto): mncLength is not set anywhere. + if (mncLength != 0) { + // Length = length of MCC + length of MNC + // TODO: change spec name + // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) + return 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; @@ -181,35 +227,27 @@ public final class RuimRecords extends IccRecords { /* IO events */ case EVENT_GET_CDMA_SUBSCRIPTION_DONE: - // TODO(Moto):TODO(Teleca): This event was removed by Teleca/QCT - // I've left it as it's needed to complete EVENT_OTA_PROVISION_STATUS_CHANGE. - // But since various instance variables are removed I've commented - // out code that references them. I'm sure this is wrong so - // Moto/Teleca/QCT need to come to an agreement. Also see onRuimReady - // and onVnReady. - ar = (AsyncResult)msg.obj; String localTemp[] = (String[])ar.result; if (ar.exception != null) { break; } - if(m_ota_commited) { - //if(mMyMobileNumber != localTemp[0]) { + if (m_ota_commited) { + if (mMyMobileNumber != localTemp[0]) { Intent intent = new Intent(TelephonyIntents.ACTION_CDMA_OTA_MDN_CHANGED); intent.putExtra("mdn", localTemp[0]); Log.d(LOG_TAG,"Broadcasting intent MDN Change in OTA "); ActivityManagerNative.broadcastStickyIntent(intent, null); - //} - m_ota_commited=false; + } + m_ota_commited = false; } - //mMyMobileNumber = localTemp[0]; - //mSid = localTemp[1]; - //mNid = localTemp[2]; - //if (localTemp.length >= 3) { // TODO(Moto): remove when new ril always returns min2_min1 - // mMin2Min1 = localTemp[3]; - //} + mMyMobileNumber = localTemp[0]; + mSid = localTemp[1]; + mNid = localTemp[2]; + mMin2Min1 = localTemp[3]; + mPrlVersion = localTemp[4]; - //Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); + Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); break; @@ -262,9 +300,11 @@ public final class RuimRecords extends IccRecords { if (ar.exception == null) { int[] ints = (int[]) ar.result; int otaStatus = ints[0]; - if (otaStatus== phone.CDMA_OTA_PROVISION_STATUS_COMMITTED) { + if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_COMMITTED) { m_ota_commited=true; phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + } else if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) { + phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); } } break; @@ -315,14 +355,14 @@ public final class RuimRecords extends IccRecords { RuimCard.INTENT_VALUE_ICC_READY, null); fetchRuimRecords(); - - // TODO(Moto): TODO(Teleca): Work out how to do CDMA subscription - // phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + + phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + } private void onNvReady() { - // TODO(Moto): TODO(Teleca): Work out how to do CDMA subscription - // phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); + } private void fetchRuimRecords() { diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java index 444dec3..925a755 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java +++ b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java @@ -74,13 +74,18 @@ public class SignalToneUtil { static private HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>(); private static Integer signalParamHash(int signalType, int alertPitch, int signal) { - // TODO(Moto): The input should get checked before usage + if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) || + (alertPitch < 0) || (signal > 256) || (signal < 0)) { + return new Integer(ToneGenerator.TONE_CDMA_INVALID); + } return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal); } public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) { - int result = ToneGenerator.TONE_CDMA_INVALID; - result = hm.get(signalParamHash(signalType, alertPitch, signal)); + Integer result = hm.get(signalParamHash(signalType, alertPitch, signal)); + if (result == null) { + return ToneGenerator.TONE_CDMA_INVALID; + } return result; } |