/* package */ void resumeWaitingOrHolding() throws CallStateException { if (DBG) log("resumeWaitingOrHolding"); try { if (mForegroundCall.getState().isAlive()) { // resume foreground call after holding background call // they were switched before holding ImsCall imsCall = mForegroundCall.getImsCall(); if (imsCall != null) imsCall.resume(); } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING) { // accept waiting call after holding background call ImsCall imsCall = mRingingCall.getImsCall(); if (imsCall != null) imsCall.accept(ImsCallProfile.CALL_TYPE_VOICE); } else { // Just resume background call. // To distinguish resuming call with swapping calls // we do not switch calls.here // ImsPhoneConnection.update will chnage the parent when completed ImsCall imsCall = mBackgroundCall.getImsCall(); if (imsCall != null) imsCall.resume(); } } catch (ImsException e) { throw new CallStateException(e.getMessage()); } }
void conference() { if (DBG) log("conference"); ImsCall fgImsCall = mForegroundCall.getImsCall(); if (fgImsCall == null) { log("conference no foreground ims call"); return; } ImsCall bgImsCall = mBackgroundCall.getImsCall(); if (bgImsCall == null) { log("conference no background ims call"); return; } // Keep track of the connect time of the earliest call so that it can be set on the // {@code ImsConference} when it is created. long conferenceConnectTime = Math.min( mForegroundCall.getEarliestConnectTime(), mBackgroundCall.getEarliestConnectTime()); ImsPhoneConnection foregroundConnection = mForegroundCall.getFirstConnection(); if (foregroundConnection != null) { foregroundConnection.setConferenceConnectTime(conferenceConnectTime); } try { fgImsCall.merge(bgImsCall); } catch (ImsException e) { log("conference " + e.getMessage()); } }
void switchWaitingOrHoldingAndActive() throws CallStateException { if (DBG) log("switchWaitingOrHoldingAndActive"); if (mRingingCall.getState() == ImsPhoneCall.State.INCOMING) { throw new CallStateException("cannot be in the incoming state"); } if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) { ImsCall imsCall = mForegroundCall.getImsCall(); if (imsCall == null) { throw new CallStateException("no ims call"); } // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls. // If hold or resume later fails, we will swap them back. mSwitchingFgAndBgCalls = true; mCallExpectedToResume = mBackgroundCall.getImsCall(); mForegroundCall.switchWith(mBackgroundCall); // Hold the foreground call; once the foreground call is held, the background call will // be resumed. try { imsCall.hold(); } catch (ImsException e) { mForegroundCall.switchWith(mBackgroundCall); throw new CallStateException(e.getMessage()); } } else if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) { resumeWaitingOrHolding(); } }
/* package */ void hangup(ImsPhoneCall call) throws CallStateException { if (DBG) log("hangup call"); if (call.getConnections().size() == 0) { throw new CallStateException("no connections"); } ImsCall imsCall = call.getImsCall(); boolean rejectCall = false; if (call == mRingingCall) { if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming"); rejectCall = true; } else if (call == mForegroundCall) { if (call.isDialingOrAlerting()) { if (Phone.DEBUG_PHONE) { log("(foregnd) hangup dialing or alerting..."); } } else { if (Phone.DEBUG_PHONE) { log("(foregnd) hangup foreground"); } // held call will be resumed by onCallTerminated } } else if (call == mBackgroundCall) { if (Phone.DEBUG_PHONE) { log("(backgnd) hangup waiting or background"); } } else { throw new CallStateException( "ImsPhoneCall " + call + "does not belong to ImsPhoneCallTracker " + this); } call.onHangupLocal(); try { if (imsCall != null) { if (rejectCall) imsCall.reject(ImsReasonInfo.CODE_USER_DECLINE); else imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED); } else if (mPendingMO != null && call == mForegroundCall) { // is holding a foreground call mPendingMO.update(null, ImsPhoneCall.State.DISCONNECTED); mPendingMO.onDisconnect(); removeConnection(mPendingMO); mPendingMO = null; updatePhoneState(); removeMessages(EVENT_DIAL_PENDINGMO); } } catch (ImsException e) { throw new CallStateException(e.getMessage()); } mPhone.notifyPreciseCallStateChanged(); }
@Override protected String readValue() { ImsLboPcscf[] lboPcscfs = null; try { ImsConfig imsConfig = mImsManager.getConfigInterface(); lboPcscfs = imsConfig.getMasterLboPcscfValue(); } catch (ImsException e) { e.printStackTrace(); } return lboPcscfs[mIndex].getLboPcscfAddress(); }
@Override protected void writeValue(String value) { ImsLboPcscf[] values = null; try { ImsConfig imsConfig = mImsManager.getConfigInterface(); values = imsConfig.getMasterLboPcscfValue(); values[mIndex].setLboPcscfAddress(value); imsConfig.setProvisionedLboPcscfValue(values); } catch (ImsException e) { e.printStackTrace(); } }
@Override public void configureDmTree(MdmTree tree) { ImsConfig imsConfig = null; try { imsConfig = mImsManager.getConfigInterface(); } catch (ImsException e) { e.printStackTrace(); } // Normal Nodes registerNodeIoHandler( tree, "P-CSCF_Address", ConfigConstants.IMS_MO_PCSCF, true, StringHandler.class); registerNodeIoHandler( tree, "Timer_T1", ConfigConstants.SIP_T1_TIMER, true, IntegerHandler.class); registerNodeIoHandler( tree, "Timer_T2", ConfigConstants.SIP_T2_TIMER, true, IntegerHandler.class); registerNodeIoHandler( tree, "Timer_T4", ConfigConstants.SIP_TF_TIMER, true, IntegerHandler.class); registerNodeIoHandler( tree, "Private_user_identity", ConfigConstants.IMS_MO_IMPI, false, StringHandler.class); registerNodeIoHandler( tree, "Home_network_domain_name", ConfigConstants.IMS_MO_DOMAIN, false, StringHandler.class); registerNodeIoHandler( tree, "Resource_Allocation_Mode", ConfigConstants.IMS_MO_RESOURCE, true, BooleanHandler.class); registerNodeIoHandler( tree, "Voice_Domain_Preference_E_UTRAN", ConfigConstants.IMS_MO_VOICE_E, true, IntegerHandler.class); registerNodeIoHandler( tree, "SMS_Over_IP_Networks_Indication", ConfigConstants.IMS_MO_SMS, true, BooleanHandler.class); registerNodeIoHandler( tree, "Keep_Alive_Enabled", ConfigConstants.IMS_MO_KEEPALIVE, true, BooleanHandler.class); registerNodeIoHandler( tree, "Voice_Domain_Preference_UTRAN", ConfigConstants.IMS_MO_VOICE_U, true, IntegerHandler.class); registerNodeIoHandler( tree, "Mobility_Management_IMS_Voice_Termination", ConfigConstants.IMS_MO_MOBILITY, true, BooleanHandler.class); registerNodeIoHandler( tree, "RegRetryBaseTime", ConfigConstants.IMS_MO_REG_BASE, true, IntegerHandler.class); registerNodeIoHandler( tree, "RegRetryMaxTime", ConfigConstants.IMS_MO_REG_MAX, true, IntegerHandler.class); // Public User Identity List try { // 1. clear old nodes for (String child : tree.listChildren(PUBLIC_USER_IDENTITY_LIST_PATH)) { tree.deleteNode(MdmTree.makeUri(PUBLIC_USER_IDENTITY_LIST_PATH, child)); } // 2. create new nodes String[] publicUserIdentities = imsConfig.getMasterStringArrayValue(ConfigConstants.IMS_MO_IMPU); for (int i = 0; i < publicUserIdentities.length; ++i) { Log.d(TAG.NODEIOHANDLER, "publicUserIdentities[i] is " + publicUserIdentities[i]); if (publicUserIdentities[i] == null) { continue; } String nodeXId = Integer.toString(i + 1); tree.addInteriorChildNode(PUBLIC_USER_IDENTITY_LIST_PATH, nodeXId, null); String leafUri = MdmTree.makeUri(PUBLIC_USER_IDENTITY_LIST_PATH, nodeXId, "Public_user_identity"); Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, publicUserIdentities[i].getBytes()); tree.replaceACL(leafUri, "Get=*"); } } catch (MdmException e) { throw new Error(e); } catch (ImsException e) { throw new Error(e); } // ICSI List try { // 1. clear old nodes for (String child : tree.listChildren(ICSI_LIST_PATH)) { tree.deleteNode(MdmTree.makeUri(ICSI_LIST_PATH, child)); } // 2. create new nodes & register handlers ImsIcsi[] icsiList = imsConfig.getMasterIcsiValue(); for (int i = 0; i < icsiList.length; ++i) { if (icsiList[i] == null) { continue; } String nodeXId = Integer.toString(i + 1); tree.addInteriorChildNode(ICSI_LIST_PATH, nodeXId, null); String leafUri = MdmTree.makeUri(ICSI_LIST_PATH, nodeXId, "ICSI"); String data = icsiList[i].getIcsi(); Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, (data == null ? null : data.getBytes())); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler(leafUri, new ICSIHandler(leafUri, mImsManager, i)); leafUri = MdmTree.makeUri(ICSI_LIST_PATH, nodeXId, "ICSI_Resource_Allocation_Mode"); Utilities.addLeafNodeChecked( tree, leafUri, "bool", null, (icsiList[i].getIsAllocated() ? "1" : "0").getBytes()); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler(leafUri, new ICSIModeHandler(leafUri, mImsManager, i)); } } catch (MdmException e) { throw new Error(e); } catch (ImsException e) { throw new Error(e); } // LBO P-CSCF Address try { // 1. clear old nodes for (String child : tree.listChildren(LBO_PCSCF_ADDRESS_PATH)) { tree.deleteNode(MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, child)); } // 2. create new nodes & register handlers ImsLboPcscf[] addressList = imsConfig.getMasterLboPcscfValue(); for (int i = 0; i < addressList.length; ++i) { if (addressList[i] == null) { continue; } String nodeXId = Integer.toString(i + 1); tree.addInteriorChildNode(LBO_PCSCF_ADDRESS_PATH, nodeXId, null); String leafUri = MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, nodeXId, "Address"); String data = addressList[i].getLboPcscfAddress(); Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, (data == null ? null : data.getBytes())); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler(leafUri, new PCSCFAddressHandler(leafUri, mImsManager, i)); leafUri = MdmTree.makeUri(LBO_PCSCF_ADDRESS_PATH, nodeXId, "AddressType"); data = addressList[i].getLboPcscfAddressType(); Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, (data == null ? null : data.getBytes())); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler(leafUri, new PCSCFAddressTypeHandler(leafUri, mImsManager, i)); } } catch (MdmException e) { throw new Error(e); } catch (ImsException e) { throw new Error(e); } // Phone Context List try { // 1. clear old nodes for (String child : tree.listChildren(PHONE_CONTEXT_LIST_PATH)) { tree.deleteNode(MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, child)); } // 2. create new nodes & register handlers ImsPhoneCtx[] contextList = imsConfig.getMasterImsPhoneCtxValue(); for (int i = 0; i < contextList.length; ++i) { if (contextList[i] == null) { continue; } String nodeXId = Integer.toString(i + 1); tree.addInteriorChildNode(PHONE_CONTEXT_LIST_PATH, nodeXId, null); String leafUri = MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, nodeXId, "PhoneContext"); String data = contextList[i].getPhoneCtx(); Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, (data == null ? null : data.getBytes())); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler(leafUri, new PhoneContextHandler(leafUri, mImsManager, i)); leafUri = MdmTree.makeUri(PHONE_CONTEXT_LIST_PATH, nodeXId, "Public_user_identity"); data = contextList[i].getPhoneCtxIpuis()[0]; Utilities.addLeafNodeChecked( tree, leafUri, "chr", null, (data == null ? null : data.getBytes())); tree.replaceACL(leafUri, "Get=*&Replace=*"); tree.registerNodeIoHandler( leafUri, new PhoneContextIdentityHandler(leafUri, mImsManager, i)); } } catch (MdmException e) { throw new Error(e); } catch (ImsException e) { throw new Error(e); } // RCS-related try { String uri = MdmTree.makeUri(RCS_PATH, "AuthType"); tree.registerNodeIoHandler(uri, new RCSAuthTypeHandler(uri, mImsManager)); uri = MdmTree.makeUri(RCS_PATH, "Realm"); tree.registerNodeIoHandler(uri, new RCSRealmHandler(uri, mImsManager)); uri = MdmTree.makeUri(RCS_PATH, "UserName"); tree.registerNodeIoHandler(uri, new RCSUserNameHandler(uri, mImsManager)); uri = MdmTree.makeUri(RCS_PATH, "UserPwd"); tree.registerNodeIoHandler(uri, new RCSUserPwdHandler(uri, mImsManager)); } catch (MdmException e) { throw new Error(e); } // Write back try { tree.writeToPersistentStorage(); } catch (MdmException e) { throw new Error(e); } }
/** oirMode is one of the CLIR_ constants */ synchronized Connection dial(String dialString, int clirMode, int videoState) throws CallStateException { boolean isPhoneInEcmMode = SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false); boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString); if (DBG) log("dial clirMode=" + clirMode); // note that this triggers call state changed notif clearDisconnected(); if (mImsManager == null) { throw new CallStateException("service not available"); } if (!canDial()) { throw new CallStateException("cannot dial in current state"); } if (isPhoneInEcmMode && isEmergencyNumber) { handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER); } boolean holdBeforeDial = 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 (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) { if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) { // we should have failed in !canDial() above before we get here throw new CallStateException("cannot dial in current state"); } // foreground call is empty for the newly dialed connection holdBeforeDial = true; switchWaitingOrHoldingAndActive(); } ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE; ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE; mClirMode = clirMode; synchronized (mSyncHold) { if (holdBeforeDial) { fgState = mForegroundCall.getState(); bgState = mBackgroundCall.getState(); // holding foreground call failed if (fgState == ImsPhoneCall.State.ACTIVE) { throw new CallStateException("cannot dial in current state"); } // holding foreground call succeeded if (bgState == ImsPhoneCall.State.HOLDING) { holdBeforeDial = false; } } mPendingMO = new ImsPhoneConnection( mPhone.getContext(), checkForTestEmergencyNumber(dialString), this, mForegroundCall); } addConnection(mPendingMO); if (!holdBeforeDial) { if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) { dialInternal(mPendingMO, clirMode, videoState); } else { try { getEcbmInterface().exitEmergencyCallbackMode(); } catch (ImsException e) { e.printStackTrace(); throw new CallStateException("service not available"); } mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null); pendingCallClirMode = clirMode; pendingCallVideoState = videoState; pendingCallInEcm = true; } } updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); return mPendingMO; }