ImsPhone.java revision 6bc4098827f3070a44b5e51508b455d7c7be9c07
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2013 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpackage com.android.internal.telephony.imsphone; 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.app.ActivityManagerNative; 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.content.Context; 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.content.Intent; 22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianimport android.os.AsyncResult; 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.Handler; 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.Message; 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.PowerManager; 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.Registrant; 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.RegistrantList; 283330b203039dea366d4981db1408a460134b2d2cMathias Agopianimport android.os.PowerManager.WakeLock; 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.os.SystemProperties; 309cce325fae8adcf7560a28eef394489f09bad74dMathias Agopianimport android.os.UserHandle; 319cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.telephony.PhoneNumberUtils; 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.telephony.ServiceState; 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.telephony.Rlog; 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.telephony.SubscriptionManager; 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport android.text.TextUtils; 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsCallForwardInfo; 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsCallProfile; 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsEcbm; 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsEcbmStateListener; 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsException; 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport com.android.ims.ImsReasonInfo; 44ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopianimport com.android.ims.ImsSsInfo; 45ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopianimport com.android.ims.ImsUtInterface; 46ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 47ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopianimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAOC; 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAOIC; 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAOICxH; 5096f0819f81293076e652792794a961543e6750d7Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAIC; 5196f0819f81293076e652792794a961543e6750d7Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAICr; 5296f0819f81293076e652792794a961543e6750d7Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_ALL; 53d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_MO; 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_MT; 55401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 56d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; 57d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; 58a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; 59a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; 65bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; 66bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; 67bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianimport static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE; 68bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 690aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopianimport com.android.internal.telephony.Call; 70d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport com.android.internal.telephony.CallForwardInfo; 71d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport com.android.internal.telephony.CallStateException; 72d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianimport com.android.internal.telephony.CallTracker; 7396f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.CommandException; 7496f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.CommandsInterface; 7596f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.Connection; 7696f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.Phone; 7796f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.PhoneBase; 7896f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.PhoneConstants; 7996f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.PhoneNotifier; 8096f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.TelephonyIntents; 8196f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.TelephonyProperties; 8296f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.cdma.CDMAPhone; 8396f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.gsm.GSMPhone; 8496f0819f81293076e652792794a961543e6750d7Mathias Agopianimport com.android.internal.telephony.uicc.IccRecords; 8596f0819f81293076e652792794a961543e6750d7Mathias Agopian 8696f0819f81293076e652792794a961543e6750d7Mathias Agopianimport java.util.ArrayList; 8796f0819f81293076e652792794a961543e6750d7Mathias Agopianimport java.util.List; 8896f0819f81293076e652792794a961543e6750d7Mathias Agopian 89d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian/** 90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian * {@hide} 91d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian */ 92d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianpublic class ImsPhone extends ImsPhoneBase { 9396f0819f81293076e652792794a961543e6750d7Mathias Agopian private static final String LOG_TAG = "ImsPhone"; 9496f0819f81293076e652792794a961543e6750d7Mathias Agopian private static final boolean DBG = true; 9596f0819f81293076e652792794a961543e6750d7Mathias Agopian private static final boolean VDBG = false; // STOPSHIP if true 9696f0819f81293076e652792794a961543e6750d7Mathias Agopian 9796f0819f81293076e652792794a961543e6750d7Mathias Agopian protected static final int EVENT_SET_CALL_BARRING_DONE = EVENT_LAST + 1; 9848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian protected static final int EVENT_GET_CALL_BARRING_DONE = EVENT_LAST + 2; 99cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian protected static final int EVENT_SET_CALL_WAITING_DONE = EVENT_LAST + 3; 100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian protected static final int EVENT_GET_CALL_WAITING_DONE = EVENT_LAST + 4; 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public static final String CS_FALLBACK = "cs_fallback"; 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static final int RESTART_ECM_TIMER = 0; // restart Ecm timer 1059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer 1069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 107bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian // Default Emergency Callback Mode exit timer 108bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000; 1090aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian 110f5430db059be3e771c004d0ada594bf8820d0517Mathias Agopian // Instance Variables 111bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian PhoneBase mDefaultPhone; 112bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian ImsPhoneCallTracker mCT; 113bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian ArrayList <ImsPhoneMmiCode> mPendingMMIs = new ArrayList<ImsPhoneMmiCode>(); 114bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 115bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Registrant mPostDialHandler; 116bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian ServiceState mSS = new ServiceState(); 117bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1189a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian // To redial silently through GSM or CDMA when dialing through IMS fails 1199a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian private String mLastDialString; 1209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 121f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian WakeLock mWakeLock; 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project protected boolean mIsPhoneInEcmState; 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 124401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // mEcmExitRespRegistrant is informed after the phone has been exited the emergency 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // callback mode keep track of if phone is in emergency callback mode 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project private Registrant mEcmExitRespRegistrant; 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project private final RegistrantList mSilentRedialRegistrants = new RegistrantList(); 129401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 130401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // A runnable which is used to automatically exit from Ecm after a period of time. 131ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian private Runnable mExitEcmRunnable = new Runnable() { 132ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian @Override 133ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian public void run() { 134ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian exitEmergencyCallbackMode(); 135ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian } 136ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian }; 137ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian 138ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // Create Cf (Call forward) so that dialling number & 139ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian // mIsCfu (true if reason is call forward unconditional) 140401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // mOnComplete (Message object passed by client) can be packed & 141401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // given as a single Cf object as user data to UtInterface. 142a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian private static class Cf { 143a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian final String mSetCfNumber; 144cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian final Message mOnComplete; 145ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian final boolean mIsCfu; 146cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 1473330b203039dea366d4981db1408a460134b2d2cMathias Agopian Cf(String cfNumber, boolean isCfu, Message onComplete) { 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSetCfNumber = cfNumber; 149ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian mIsCfu = isCfu; 150401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian mOnComplete = onComplete; 151401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } 152401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } 153401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 154401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian // Constructors 15596f0819f81293076e652792794a961543e6750d7Mathias Agopian 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ImsPhone(Context context, PhoneNotifier notifier, Phone defaultPhone) { 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project super("ImsPhone", context, notifier); 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDefaultPhone = (PhoneBase) defaultPhone; 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCT = new ImsPhoneCallTracker(this); 161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mSS.setStateOff(); 1628f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 1638f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian mPhoneId = mDefaultPhone.getPhoneId(); 1648f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian 1658f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // This is needed to handle phone process crashes 1668f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian // Same property is used for both CDMA & IMS phone. 1678f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian mIsPhoneInEcmState = SystemProperties.getBoolean( 1688f03b47432f007b1fb3438608361ebf4e3a1310bMathias Agopian TelephonyProperties.PROPERTY_INECM_MODE, false); 16954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 17057720c384af81327d327ef8b88078f11a750fd05Mathias Agopian PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 171d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); 172d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mWakeLock.setReferenceCounted(false); 173d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 174d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 175d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian public void updateParentPhone(PhoneBase parentPhone) { 176076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // synchronization is managed at the PhoneBase scope (which calls this function) 17754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian mDefaultPhone = parentPhone; 17854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian mPhoneId = mDefaultPhone.getPhoneId(); 17954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } 180fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian 181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian @Override 1823330b203039dea366d4981db1408a460134b2d2cMathias Agopian public void dispose() { 1830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Rlog.d(LOG_TAG, "dispose"); 1840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian // Nothing to dispose in PhoneBase 1850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian //super.dispose(); 186d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mPendingMMIs.clear(); 1870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mCT.dispose(); 188076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //Force all referenced classes to unregister their former registered events 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void removeReferences() { 194d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Rlog.d(LOG_TAG, "removeReferences"); 195d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian super.removeReferences(); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 197179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian mCT = null; 198179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian mSS = null; 199179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 200179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 201179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian @Override 202179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian public ServiceState 203179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian getServiceState() { 204179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian return mSS; 205179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 206179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 207179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian /* package */ void setServiceState(int state) { 208179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian mSS.setState(state); 209179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 210179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 211179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian @Override 212179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian public CallTracker getCallTracker() { 213179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian return mCT; 214179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian } 215179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian 216179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian @Override 217179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian public List<? extends ImsPhoneMmiCode> 218179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian getPendingMmiCodes() { 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mPendingMMIs; 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 221d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 224a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian public void 225a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian acceptCall(int videoState) throws CallStateException { 226a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian mCT.acceptCall(videoState); 227a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 228a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 229a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian @Override 230a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian public void 231a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian rejectCall() throws CallStateException { 232a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian mCT.rejectCall(); 233a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian } 234a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian 235a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian @Override 236a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian public void 237b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian switchHoldingAndActive() throws CallStateException { 238b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian mCT.switchWaitingOrHoldingAndActive(); 239b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 240bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 241b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian @Override 242b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian public boolean canConference() { 243b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return mCT.canConference(); 244b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 245b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 246b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian public boolean canDial() { 247b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return mCT.canDial(); 248bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 249bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 250bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian @Override 251bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian public void conference() { 252b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian mCT.conference(); 253b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 254b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 255b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian @Override 256a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian public void clearDisconnected() { 257a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mCT.clearDisconnected(); 258a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2603330b203039dea366d4981db1408a460134b2d2cMathias Agopian @Override 26148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian public boolean canTransfer() { 262a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mCT.canTransfer(); 263a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 264a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 265a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian @Override 266a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian public void explicitCallTransfer() { 267a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mCT.explicitCallTransfer(); 26848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 26948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 27048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian @Override 27148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian public ImsPhoneCall 27248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian getForegroundCall() { 27348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return mCT.mForegroundCall; 27448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 27548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 276076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian @Override 277cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian public ImsPhoneCall 278cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian getBackgroundCall() { 279cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return mCT.mBackgroundCall; 280bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 281cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 282cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian @Override 283cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian public ImsPhoneCall 284cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian getRingingCall() { 285076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return mCT.mRingingCall; 286cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 287cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 28848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian private boolean handleCallDeflectionIncallSupplementaryService( 28948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian String dialString) { 29048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (dialString.length() > 1) { 29148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian return false; 29248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 293a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 29448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (getRingingCall().getState() != ImsPhoneCall.State.IDLE) { 29548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 0: rejectCall"); 296a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian try { 297a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mCT.rejectCall(); 298a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } catch (CallStateException e) { 299a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "reject failed", e); 300a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian notifySuppServiceFailed(Phone.SuppService.REJECT); 301a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 302a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } else if (getBackgroundCall().getState() != ImsPhoneCall.State.IDLE) { 303a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 0: hangupWaitingOrBackground"); 304a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian try { 305d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian mCT.hangup(getBackgroundCall()); 306a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } catch (CallStateException e) { 307a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "hangup failed", e); 308a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 30948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian } 31048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian 3113330b203039dea366d4981db1408a460134b2d2cMathias Agopian return true; 3126d9f69843bae31b2da9a8f2869547b1ff5d0654dMathias Agopian } 313a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 314cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 315cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian private boolean handleCallWaitingIncallSupplementaryService( 316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian String dialString) { 317cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int len = dialString.length(); 318cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 319a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (len > 2) { 320cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return false; 321076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 322cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 323cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ImsPhoneCall call = getForegroundCall(); 324cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 325cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian try { 326cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (len > 1) { 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (DBG) Rlog.d(LOG_TAG, "not support 1X SEND"); 328cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian notifySuppServiceFailed(Phone.SuppService.HANGUP); 3297e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian } else { 3307e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if (call.getState() != ImsPhoneCall.State.IDLE) { 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (DBG) Rlog.d(LOG_TAG, "MmiCode 1: hangup foreground"); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCT.hangup(call); 333cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 33448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 1: switchWaitingOrHoldingAndActive"); 335a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mCT.switchWaitingOrHoldingAndActive(); 336f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } 337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 338f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian } catch (CallStateException e) { 339f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "hangup failed", e); 3403330b203039dea366d4981db1408a460134b2d2cMathias Agopian notifySuppServiceFailed(Phone.SuppService.HANGUP); 3413330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3423330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3433330b203039dea366d4981db1408a460134b2d2cMathias Agopian return true; 3443330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3453330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3463330b203039dea366d4981db1408a460134b2d2cMathias Agopian private boolean handleCallHoldIncallSupplementaryService(String dialString) { 3473330b203039dea366d4981db1408a460134b2d2cMathias Agopian int len = dialString.length(); 3483330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3493330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (len > 2) { 3503330b203039dea366d4981db1408a460134b2d2cMathias Agopian return false; 3513330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3533330b203039dea366d4981db1408a460134b2d2cMathias Agopian ImsPhoneCall call = getForegroundCall(); 3543330b203039dea366d4981db1408a460134b2d2cMathias Agopian 3553330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (len > 1) { 3563330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (DBG) Rlog.d(LOG_TAG, "separate not supported"); 3573330b203039dea366d4981db1408a460134b2d2cMathias Agopian notifySuppServiceFailed(Phone.SuppService.SEPARATE); 3583330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3593330b203039dea366d4981db1408a460134b2d2cMathias Agopian try { 3603330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (getRingingCall().getState() != ImsPhoneCall.State.IDLE) { 36189141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 2: accept ringing call"); 36289141f949270100d1cacecf99cc2ff25fce79087Mathias Agopian mCT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE); 3633330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 3643330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 2: switchWaitingOrHoldingAndActive"); 3653330b203039dea366d4981db1408a460134b2d2cMathias Agopian mCT.switchWaitingOrHoldingAndActive(); 3663330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } catch (CallStateException e) { 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (DBG) Rlog.d(LOG_TAG, "switch failed", e); 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project notifySuppServiceFailed(Phone.SuppService.SWITCH); 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 372a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 373a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return true; 374a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 375a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 376cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian private boolean handleMultipartyIncallSupplementaryService( 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String dialString) { 378a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (dialString.length() > 1) { 379a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return false; 380a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 381a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 382a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 3: merge calls"); 383a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian conference(); 384a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return true; 385a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 386a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 387a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian private boolean handleEctIncallSupplementaryService(String dialString) { 388a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 389a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int len = dialString.length(); 390a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 391a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (len != 1) { 392a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return false; 393a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 395caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian if (DBG) Rlog.d(LOG_TAG, "MmiCode 4: not support explicit call transfer"); 396a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian notifySuppServiceFailed(Phone.SuppService.TRANSFER); 397a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return true; 398a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 399a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 400a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian private boolean handleCcbsIncallSupplementaryService(String dialString) { 401df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian if (dialString.length() > 1) { 402a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return false; 403a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 404a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 4056656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian Rlog.i(LOG_TAG, "MmiCode 5: CCBS not supported!"); 40696f0819f81293076e652792794a961543e6750d7Mathias Agopian // Treat it as an "unknown" service. 40796f0819f81293076e652792794a961543e6750d7Mathias Agopian notifySuppServiceFailed(Phone.SuppService.UNKNOWN); 40896f0819f81293076e652792794a961543e6750d7Mathias Agopian return true; 40996f0819f81293076e652792794a961543e6750d7Mathias Agopian } 41096f0819f81293076e652792794a961543e6750d7Mathias Agopian 411a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian @Override 412a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian public boolean handleInCallMmiCommands(String dialString) { 413a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (!isInCall()) { 414a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return false; 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (TextUtils.isEmpty(dialString)) { 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean result = false; 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char ch = dialString.charAt(0); 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (ch) { 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case '0': 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result = handleCallDeflectionIncallSupplementaryService( 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dialString); 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 428a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian case '1': 429cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian result = handleCallWaitingIncallSupplementaryService( 430cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian dialString); 431cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian break; 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case '2': 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result = handleCallHoldIncallSupplementaryService(dialString); 434a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian break; 435a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian case '3': 436a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian result = handleMultipartyIncallSupplementaryService(dialString); 437a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian break; 438a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian case '4': 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result = handleEctIncallSupplementaryService(dialString); 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case '5': 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project result = handleCcbsIncallSupplementaryService(dialString); 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 44596f0819f81293076e652792794a961543e6750d7Mathias Agopian break; 44696f0819f81293076e652792794a961543e6750d7Mathias Agopian } 44796f0819f81293076e652792794a961543e6750d7Mathias Agopian 44896f0819f81293076e652792794a961543e6750d7Mathias Agopian return result; 44996f0819f81293076e652792794a961543e6750d7Mathias Agopian } 45096f0819f81293076e652792794a961543e6750d7Mathias Agopian 45196f0819f81293076e652792794a961543e6750d7Mathias Agopian boolean isInCall() { 452cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ImsPhoneCall.State foregroundCallState = getForegroundCall().getState(); 453d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsPhoneCall.State backgroundCallState = getBackgroundCall().getState(); 454d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsPhoneCall.State ringingCallState = getRingingCall().getState(); 455d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 456cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return (foregroundCallState.isAlive() || 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project backgroundCallState.isAlive() || 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ringingCallState.isAlive()); 459d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 460d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 461d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian void notifyNewRingingConnection(Connection c) { 462d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mDefaultPhone.notifyNewRingingConnectionP(c); 463d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 464d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 465d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 466cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian @Override 467d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian public Connection 468d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian dial(String dialString, int videoState) throws CallStateException { 469d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return dialInternal(dialString, videoState); 470d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 471d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project protected Connection dialInternal(String dialString, int videoState) 473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian throws CallStateException { 4743330b203039dea366d4981db1408a460134b2d2cMathias Agopian // Need to make sure dialString gets parsed properly 475d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian String newDialString = PhoneNumberUtils.stripSeparators(dialString); 476d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 477d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // handle in-call MMI first if applicable 478d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (handleInCallMmiCommands(newDialString)) { 479d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return null; 480d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 481d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 482d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (mDefaultPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 483d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return mCT.dial(dialString, videoState); 484df3e0b934f2822ea0a334777e51e681f04a64d7cMathias Agopian } 485d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 486d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // Only look at the Network portion for mmi 487d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString); 488d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian ImsPhoneMmiCode mmi = 489d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian ImsPhoneMmiCode.newFromDialString(networkPortion, this); 490d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (DBG) Rlog.d(LOG_TAG, 491d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian "dialing w/ mmi '" + mmi + "'..."); 492d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 493d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (mmi == null) { 494d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return mCT.dial(dialString, videoState); 495d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else if (mmi.isTemporaryModeCLIR()) { 496d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return mCT.dial(mmi.getDialingNumber(), mmi.getCLIRMode(), videoState); 497d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else if (!mmi.isSupportedOverImsPhone()) { 498d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // If the mmi is not supported by IMS service, 499d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian // try to initiate dialing with default phone 500d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian throw new CallStateException(CS_FALLBACK); 501d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 502d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mPendingMMIs.add(mmi); 503d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 504d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian mmi.processCode(); 505d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 506d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian return null; 5078f2d50521653f24c2a5e77b627dc015c7fbd656aMathias Agopian } 508d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } 509d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian 510d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian @Override 511d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian public void 512d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian sendDtmf(char c) { 513d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian if (!PhoneNumberUtils.is12Key(c)) { 514d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian Rlog.e(LOG_TAG, 515d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian "sendDtmf called with invalid character '" + c + "'"); 516d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian } else { 517caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian if (mCT.mState == PhoneConstants.State.OFFHOOK) { 518caa600c4a1af1eefd108cf2ec3d86068af35111fMathias Agopian mCT.sendDtmf(c); 519e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 520e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 521e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian } 522e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 524245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian public void 525245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian startDtmf(char c) { 526245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian if (!PhoneNumberUtils.is12Key(c)) { 527245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian Rlog.e(LOG_TAG, 528245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian "startDtmf called with invalid character '" + c + "'"); 529245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian } else { 530245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian sendDtmf(c); 531245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian } 532245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian } 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project stopDtmf() { 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // no op 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void setOnPostDialCharacter(Handler h, int what, Object obj) { 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostDialHandler = new Registrant(h, what, obj); 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /*package*/ void notifyIncomingRing() { 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (DBG) Rlog.d(LOG_TAG, "notifyIncomingRing"); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AsyncResult ar = new AsyncResult(null, null, null); 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sendMessage(obtainMessage(EVENT_CALL_RING, ar)); 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void setMute(boolean muted) { 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCT.setMute(muted); 554c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian } 555c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian 5561b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian @Override 557c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian public boolean getMute() { 558c61de17f143b5f806c5bab9cc58910a322302b70Mathias Agopian return mCT.getMute(); 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project @Override 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public PhoneConstants.State getState() { 56396f0819f81293076e652792794a961543e6750d7Mathias Agopian return mCT.mState; 56496f0819f81293076e652792794a961543e6750d7Mathias Agopian } 56596f0819f81293076e652792794a961543e6750d7Mathias Agopian 56696f0819f81293076e652792794a961543e6750d7Mathias Agopian private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) { 56796f0819f81293076e652792794a961543e6750d7Mathias Agopian switch (commandInterfaceCFReason) { 56896f0819f81293076e652792794a961543e6750d7Mathias Agopian case CF_REASON_UNCONDITIONAL: 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CF_REASON_BUSY: 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CF_REASON_NO_REPLY: 5711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_NOT_REACHABLE: 5721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_ALL: 5731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_ALL_CONDITIONAL: 5741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return true; 5751b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian default: 5761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return false; 5771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5791b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) { 5811b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian switch (commandInterfaceCFAction) { 5821b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_ACTION_DISABLE: 5831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_ACTION_ENABLE: 5841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_ACTION_REGISTRATION: 5851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_ACTION_ERASURE: 5861b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return true; 5871b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian default: 5881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return false; 5891b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5921b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian private boolean isCfEnable(int action) { 5931b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION); 5941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian } 5951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 5961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian private int getConditionFromCFReason(int reason) { 5971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian switch(reason) { 5981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_UNCONDITIONAL: return ImsUtInterface.CDIV_CF_UNCONDITIONAL; 5991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_BUSY: return ImsUtInterface.CDIV_CF_BUSY; 6001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_NO_REPLY: return ImsUtInterface.CDIV_CF_NO_REPLY; 6011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian case CF_REASON_NOT_REACHABLE: return ImsUtInterface.CDIV_CF_NOT_REACHABLE; 6021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian default: 603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian break; 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 605d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 606bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.INVALID; 607bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 608bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 609bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian private int getCFReasonFromCondition(int condition) { 610bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian switch(condition) { 611bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian case ImsUtInterface.CDIV_CF_UNCONDITIONAL: return CF_REASON_UNCONDITIONAL; 612d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case ImsUtInterface.CDIV_CF_BUSY: return CF_REASON_BUSY; 613d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case ImsUtInterface.CDIV_CF_NO_REPLY: return CF_REASON_NO_REPLY; 614d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case ImsUtInterface.CDIV_CF_NOT_REACHABLE: return CF_REASON_NOT_REACHABLE; 615bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian default: 616bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian break; 617bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 618bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 619bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return CF_REASON_NOT_REACHABLE; 620d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 621d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 622d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian private int getActionFromCFAction(int action) { 623d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian switch(action) { 624d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case CF_ACTION_DISABLE: return ImsUtInterface.ACTION_DEACTIVATION; 625d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case CF_ACTION_ENABLE: return ImsUtInterface.ACTION_ACTIVATION; 626d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case CF_ACTION_ERASURE: return ImsUtInterface.ACTION_ERASURE; 627d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian case CF_ACTION_REGISTRATION: return ImsUtInterface.ACTION_REGISTRATION; 628d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian default: 629d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian break; 630d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 631d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 632d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return ImsUtInterface.INVALID; 633d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 634d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 635d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian @Override 636d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian public void getCallForwardingOption(int commandInterfaceCFReason, 637d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Message onComplete) { 638bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "getCallForwardingOption reason=" + commandInterfaceCFReason); 639bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) { 640bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "requesting call forwarding query."); 641bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Message resp; 642bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete); 643bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 644bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian try { 645d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsUtInterface ut = mCT.getUtInterface(); 646d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ut.queryCallForward(getConditionFromCFReason(commandInterfaceCFReason),null,resp); 647d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } catch (ImsException e) { 648bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sendErrorResponse(onComplete, e); 649bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 650d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } else if (onComplete != null) { 651bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sendErrorResponse(onComplete); 652d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 653d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 654d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 655d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian @Override 656bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian public void setCallForwardingOption(int commandInterfaceCFAction, 657d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian int commandInterfaceCFReason, 658d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian String dialingNumber, 659bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian int timerSeconds, 660bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Message onComplete) { 661d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "setCallForwardingOption action=" + commandInterfaceCFAction 662d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian + ", reason=" + commandInterfaceCFReason); 663d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) && 664d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) { 665d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Message resp; 666d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Cf cf = new Cf(dialingNumber, 667bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL ? true : false), 668d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian onComplete); 669bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE, 670bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, cf); 671d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 672d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian try { 673d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsUtInterface ut = mCT.getUtInterface(); 674d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ut.updateCallForward(getActionFromCFAction(commandInterfaceCFAction), 675d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian getConditionFromCFReason(commandInterfaceCFReason), 676bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian dialingNumber, 677bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian timerSeconds, 678bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian onComplete); 679bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } catch (ImsException e) { 680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sendErrorResponse(onComplete, e); 681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 682bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (onComplete != null) { 683bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sendErrorResponse(onComplete); 684bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 685bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 686bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 687d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian @Override 688d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian public void getCallWaiting(Message onComplete) { 689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "getCallWaiting"); 690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Message resp; 691d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian resp = obtainMessage(EVENT_GET_CALL_WAITING_DONE, onComplete); 692d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 693d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian try { 694d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsUtInterface ut = mCT.getUtInterface(); 695d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ut.queryCallWaiting(resp); 696bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } catch (ImsException e) { 697d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sendErrorResponse(onComplete, e); 698d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 699d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 700d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 701d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian @Override 702d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian public void setCallWaiting(boolean enable, Message onComplete) { 703d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "setCallWaiting enable=" + enable); 704d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian Message resp; 705bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian resp = obtainMessage(EVENT_SET_CALL_WAITING_DONE, onComplete); 706bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 707d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian try { 708d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ImsUtInterface ut = mCT.getUtInterface(); 709d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian ut.updateCallWaiting(enable, resp); 710d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } catch (ImsException e) { 711d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian sendErrorResponse(onComplete, e); 712d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 713d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 714d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 715d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian private int getCBTypeFromFacility(String facility) { 716d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian if (CB_FACILITY_BAOC.equals(facility)) { 717d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian return ImsUtInterface.CB_BAOC; 718d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } else if (CB_FACILITY_BAOIC.equals(facility)) { 719bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BOIC; 720bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BAOICxH.equals(facility)) { 721bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BOIC_EXHC; 722bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BAIC.equals(facility)) { 723bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BAIC; 724bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BAICr.equals(facility)) { 725bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BIC_WR; 726bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BA_ALL.equals(facility)) { 727bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BA_ALL; 728bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BA_MO.equals(facility)) { 729bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BA_MO; 730bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } else if (CB_FACILITY_BA_MT.equals(facility)) { 731bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return ImsUtInterface.CB_BA_MT; 732d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian } 733d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian 7349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return 0; 73596f0819f81293076e652792794a961543e6750d7Mathias Agopian } 73696f0819f81293076e652792794a961543e6750d7Mathias Agopian 7379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* package */ 7389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian void getCallBarring(String facility, Message onComplete) { 7399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "getCallBarring facility=" + facility); 7409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian Message resp; 741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian resp = obtainMessage(EVENT_GET_CALL_BARRING_DONE, onComplete); 742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian try { 744a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian ImsUtInterface ut = mCT.getUtInterface(); 745a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian ut.queryCallBarring(getCBTypeFromFacility(facility), resp); 746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } catch (ImsException e) { 7473330b203039dea366d4981db1408a460134b2d2cMathias Agopian sendErrorResponse(onComplete, e); 748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 750bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 751bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian /* package */ 752bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian void setCallBarring(String facility, boolean lockState, String password, Message onComplete) { 753bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian if (DBG) Rlog.d(LOG_TAG, "setCallBarring facility=" + facility 754bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian + ", lockState=" + lockState); 755a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Message resp; 756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian resp = obtainMessage(EVENT_SET_CALL_BARRING_DONE, onComplete); 757076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian try { 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ImsUtInterface ut = mCT.getUtInterface(); 760b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian // password is not required with Ut interface 761b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian ut.updateCallBarring(getCBTypeFromFacility(facility), lockState, resp, null); 762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } catch (ImsException e) { 763b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sendErrorResponse(onComplete, e); 764b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 765bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 766bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 767bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian @Override 768bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian public void sendUssdResponse(String ussdMessge) { 769bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian Rlog.d(LOG_TAG, "sendUssdResponse"); 770b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian ImsPhoneMmiCode mmi = ImsPhoneMmiCode.newFromUssdUserInput(ussdMessge, this); 771b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian mPendingMMIs.add(mmi); 772b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); 773b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian mmi.sendUssd(ussdMessge); 774b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian } 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* package */ 777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void sendUSSD (String ussdString, Message response) { 778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCT.sendUSSD(ussdString, response); 779 } 780 781 /* package */ 782 void cancelUSSD() { 783 mCT.cancelUSSD(); 784 } 785 786 /* package */ 787 void sendErrorResponse(Message onComplete) { 788 Rlog.d(LOG_TAG, "sendErrorResponse"); 789 if (onComplete != null) { 790 AsyncResult.forMessage(onComplete, null, 791 new CommandException(CommandException.Error.GENERIC_FAILURE)); 792 onComplete.sendToTarget(); 793 } 794 } 795 796 /* package */ 797 void sendErrorResponse(Message onComplete, Throwable e) { 798 Rlog.d(LOG_TAG, "sendErrorResponse"); 799 if (onComplete != null) { 800 AsyncResult.forMessage(onComplete, null, getCommandException(e)); 801 onComplete.sendToTarget(); 802 } 803 } 804 805 /* package */ 806 void sendErrorResponse(Message onComplete, ImsReasonInfo reasonInfo) { 807 Rlog.d(LOG_TAG, "sendErrorResponse reasonCode=" + reasonInfo.getCode()); 808 if (onComplete != null) { 809 AsyncResult.forMessage(onComplete, null, getCommandException(reasonInfo.getCode())); 810 onComplete.sendToTarget(); 811 } 812 } 813 814 /* package */ 815 CommandException getCommandException(int code) { 816 Rlog.d(LOG_TAG, "getCommandException code=" + code); 817 CommandException.Error error = CommandException.Error.GENERIC_FAILURE; 818 819 switch(code) { 820 case ImsReasonInfo.CODE_UT_NOT_SUPPORTED: 821 error = CommandException.Error.REQUEST_NOT_SUPPORTED; 822 break; 823 case ImsReasonInfo.CODE_UT_CB_PASSWORD_MISMATCH: 824 error = CommandException.Error.PASSWORD_INCORRECT; 825 break; 826 default: 827 break; 828 } 829 830 return new CommandException(error); 831 } 832 833 /* package */ 834 CommandException getCommandException(Throwable e) { 835 CommandException ex = null; 836 837 if (e instanceof ImsException) { 838 ex = getCommandException(((ImsException)e).getCode()); 839 } else { 840 Rlog.d(LOG_TAG, "getCommandException generic failure"); 841 ex = new CommandException(CommandException.Error.GENERIC_FAILURE); 842 } 843 return ex; 844 } 845 846 private void 847 onNetworkInitiatedUssd(ImsPhoneMmiCode mmi) { 848 Rlog.d(LOG_TAG, "onNetworkInitiatedUssd"); 849 mMmiCompleteRegistrants.notifyRegistrants( 850 new AsyncResult(null, mmi, null)); 851 } 852 853 /* package */ 854 void onIncomingUSSD (int ussdMode, String ussdMessage) { 855 if (DBG) Rlog.d(LOG_TAG, "onIncomingUSSD ussdMode=" + ussdMode); 856 857 boolean isUssdError; 858 boolean isUssdRequest; 859 860 isUssdRequest 861 = (ussdMode == CommandsInterface.USSD_MODE_REQUEST); 862 863 isUssdError 864 = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY 865 && ussdMode != CommandsInterface.USSD_MODE_REQUEST); 866 867 ImsPhoneMmiCode found = null; 868 for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { 869 if(mPendingMMIs.get(i).isPendingUSSD()) { 870 found = mPendingMMIs.get(i); 871 break; 872 } 873 } 874 875 if (found != null) { 876 // Complete pending USSD 877 if (isUssdError) { 878 found.onUssdFinishedError(); 879 } else { 880 found.onUssdFinished(ussdMessage, isUssdRequest); 881 } 882 } else { // pending USSD not found 883 // The network may initiate its own USSD request 884 885 // ignore everything that isnt a Notify or a Request 886 // also, discard if there is no message to present 887 if (!isUssdError && ussdMessage != null) { 888 ImsPhoneMmiCode mmi; 889 mmi = ImsPhoneMmiCode.newNetworkInitiatedUssd(ussdMessage, 890 isUssdRequest, 891 ImsPhone.this); 892 onNetworkInitiatedUssd(mmi); 893 } 894 } 895 } 896 897 /** 898 * Removes the given MMI from the pending list and notifies 899 * registrants that it is complete. 900 * @param mmi MMI that is done 901 */ 902 /*package*/ void 903 onMMIDone(ImsPhoneMmiCode mmi) { 904 /* Only notify complete if it's on the pending list. 905 * Otherwise, it's already been handled (eg, previously canceled). 906 * The exception is cancellation of an incoming USSD-REQUEST, which is 907 * not on the list. 908 */ 909 if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) { 910 mMmiCompleteRegistrants.notifyRegistrants( 911 new AsyncResult(null, mmi, null)); 912 } 913 } 914 915 public ImsPhoneConnection getHandoverConnection() { 916 // handover for single foreground call 917 ImsPhoneConnection conn = getForegroundCall().getHandoverConnection(); 918 919 // handover for single background call 920 if (conn == null) { 921 conn = getBackgroundCall().getHandoverConnection(); 922 } 923 924 // handover for single ringing call 925 if (conn == null) { 926 conn = getRingingCall().getHandoverConnection(); 927 } 928 929 return conn; 930 } 931 932 public void notifySrvccState(Call.SrvccState state) { 933 mCT.notifySrvccState(state); 934 } 935 936 /* package */ void 937 initiateSilentRedial() { 938 String result = mLastDialString; 939 AsyncResult ar = new AsyncResult(null, result, null); 940 if (ar != null) { 941 mSilentRedialRegistrants.notifyRegistrants(ar); 942 } 943 } 944 945 public void registerForSilentRedial(Handler h, int what, Object obj) { 946 mSilentRedialRegistrants.addUnique(h, what, obj); 947 } 948 949 public void unregisterForSilentRedial(Handler h) { 950 mSilentRedialRegistrants.remove(h); 951 } 952 953 @Override 954 public long getSubId() { 955 return mDefaultPhone.getSubId(); 956 } 957 958 @Override 959 public int getPhoneId() { 960 return mDefaultPhone.getPhoneId(); 961 } 962 963 private IccRecords getIccRecords() { 964 return mDefaultPhone.mIccRecords.get(); 965 } 966 967 private CallForwardInfo getCallForwardInfo(ImsCallForwardInfo info) { 968 CallForwardInfo cfInfo = new CallForwardInfo(); 969 cfInfo.status = info.mStatus; 970 cfInfo.reason = getCFReasonFromCondition(info.mCondition); 971 cfInfo.serviceClass = SERVICE_CLASS_VOICE; 972 cfInfo.toa = info.mToA; 973 cfInfo.number = info.mNumber; 974 cfInfo.timeSeconds = info.mTimeSeconds; 975 return cfInfo; 976 } 977 978 private CallForwardInfo[] handleCfQueryResult(ImsCallForwardInfo[] infos) { 979 CallForwardInfo[] cfInfos = null; 980 981 if (infos != null && infos.length != 0) { 982 cfInfos = new CallForwardInfo[infos.length]; 983 } 984 985 IccRecords r = getIccRecords(); 986 if (infos == null || infos.length == 0) { 987 if (r != null) { 988 // Assume the default is not active 989 // Set unconditional CFF in SIM to false 990 r.setVoiceCallForwardingFlag(1, false, null); 991 } 992 } else { 993 for (int i = 0, s = infos.length; i < s; i++) { 994 if (infos[i].mCondition == ImsUtInterface.CDIV_CF_UNCONDITIONAL) { 995 if (r != null) { 996 r.setVoiceCallForwardingFlag(1, (infos[i].mStatus == 1), 997 infos[i].mNumber); 998 } 999 } 1000 cfInfos[i] = getCallForwardInfo(infos[i]); 1001 } 1002 } 1003 1004 return cfInfos; 1005 } 1006 1007 private int[] handleCbQueryResult(ImsSsInfo[] infos) { 1008 int[] cbInfos = new int[1]; 1009 cbInfos[0] = SERVICE_CLASS_NONE; 1010 1011 if (infos[0].mStatus == 1) { 1012 cbInfos[0] = SERVICE_CLASS_VOICE; 1013 } 1014 1015 return cbInfos; 1016 } 1017 1018 private int[] handleCwQueryResult(ImsSsInfo[] infos) { 1019 int[] cwInfos = new int[2]; 1020 cwInfos[0] = 0; 1021 1022 if (infos[0].mStatus == 1) { 1023 cwInfos[0] = 1; 1024 cwInfos[1] = SERVICE_CLASS_VOICE; 1025 } 1026 1027 return cwInfos; 1028 } 1029 1030 private void 1031 sendResponse(Message onComplete, Object result, Throwable e) { 1032 if (onComplete != null) { 1033 CommandException ex = null; 1034 if (e != null) { 1035 ex = getCommandException(e); 1036 } 1037 AsyncResult.forMessage(onComplete, result, ex); 1038 onComplete.sendToTarget(); 1039 } 1040 } 1041 1042 @Override 1043 public void handleMessage (Message msg) { 1044 AsyncResult ar = (AsyncResult) msg.obj; 1045 Message onComplete; 1046 1047 if (DBG) Rlog.d(LOG_TAG, "handleMessage what=" + msg.what); 1048 switch (msg.what) { 1049 case EVENT_SET_CALL_FORWARD_DONE: 1050 IccRecords r = getIccRecords(); 1051 Cf cf = (Cf) ar.userObj; 1052 if (cf.mIsCfu && ar.exception == null && r != null) { 1053 r.setVoiceCallForwardingFlag(1, msg.arg1 == 1, cf.mSetCfNumber); 1054 } 1055 sendResponse(cf.mOnComplete, null, ar.exception); 1056 break; 1057 1058 case EVENT_GET_CALL_FORWARD_DONE: 1059 CallForwardInfo[] cfInfos = null; 1060 if (ar.exception == null) { 1061 cfInfos = handleCfQueryResult((ImsCallForwardInfo[])ar.result); 1062 } 1063 sendResponse((Message) ar.userObj, cfInfos, ar.exception); 1064 break; 1065 1066 case EVENT_GET_CALL_BARRING_DONE: 1067 case EVENT_GET_CALL_WAITING_DONE: 1068 int[] ssInfos = null; 1069 if (ar.exception == null) { 1070 if (msg.what == EVENT_GET_CALL_BARRING_DONE) { 1071 ssInfos = handleCbQueryResult((ImsSsInfo[])ar.result); 1072 } else if (msg.what == EVENT_GET_CALL_WAITING_DONE) { 1073 ssInfos = handleCwQueryResult((ImsSsInfo[])ar.result); 1074 } 1075 } 1076 sendResponse((Message) ar.userObj, ssInfos, ar.exception); 1077 break; 1078 1079 case EVENT_SET_CALL_BARRING_DONE: 1080 case EVENT_SET_CALL_WAITING_DONE: 1081 sendResponse((Message) ar.userObj, null, ar.exception); 1082 break; 1083 1084 default: 1085 super.handleMessage(msg); 1086 break; 1087 } 1088 } 1089 1090 /** 1091 * Listen to the IMS ECBM state change 1092 */ 1093 ImsEcbmStateListener mImsEcbmStateListener = 1094 new ImsEcbmStateListener() { 1095 @Override 1096 public void onECBMEntered() { 1097 if (DBG) Rlog.d(LOG_TAG, "onECBMEntered"); 1098 handleEnterEmergencyCallbackMode(); 1099 } 1100 1101 @Override 1102 public void onECBMExited() { 1103 if (DBG) Rlog.d(LOG_TAG, "onECBMExited"); 1104 handleExitEmergencyCallbackMode(); 1105 } 1106 }; 1107 1108 public boolean isInEmergencyCall() { 1109 return mCT.isInEmergencyCall(); 1110 } 1111 1112 public boolean isInEcm() { 1113 return mIsPhoneInEcmState; 1114 } 1115 1116 void sendEmergencyCallbackModeChange() { 1117 // Send an Intent 1118 Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); 1119 intent.putExtra(PhoneConstants.PHONE_IN_ECM_STATE, mIsPhoneInEcmState); 1120 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId()); 1121 ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); 1122 if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallbackModeChange"); 1123 } 1124 1125 @Override 1126 public void exitEmergencyCallbackMode() { 1127 if (mWakeLock.isHeld()) { 1128 mWakeLock.release(); 1129 } 1130 if (DBG) Rlog.d(LOG_TAG, "exitEmergencyCallbackMode()"); 1131 1132 // Send a message which will invoke handleExitEmergencyCallbackMode 1133 ImsEcbm ecbm; 1134 try { 1135 ecbm = mCT.getEcbmInterface(); 1136 ecbm.exitEmergencyCallbackMode(); 1137 } catch (ImsException e) { 1138 e.printStackTrace(); 1139 } 1140 } 1141 1142 private void handleEnterEmergencyCallbackMode() { 1143 if (DBG) { 1144 Rlog.d(LOG_TAG, "handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= " 1145 + mIsPhoneInEcmState); 1146 } 1147 // if phone is not in Ecm mode, and it's changed to Ecm mode 1148 if (mIsPhoneInEcmState == false) { 1149 mIsPhoneInEcmState = true; 1150 // notify change 1151 sendEmergencyCallbackModeChange(); 1152 setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true"); 1153 1154 // Post this runnable so we will automatically exit 1155 // if no one invokes exitEmergencyCallbackMode() directly. 1156 long delayInMillis = SystemProperties.getLong( 1157 TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); 1158 postDelayed(mExitEcmRunnable, delayInMillis); 1159 // We don't want to go to sleep while in Ecm 1160 mWakeLock.acquire(); 1161 } 1162 } 1163 1164 private void handleExitEmergencyCallbackMode() { 1165 if (DBG) { 1166 Rlog.d(LOG_TAG, "handleExitEmergencyCallbackMode: mIsPhoneInEcmState = " 1167 + mIsPhoneInEcmState); 1168 } 1169 // Remove pending exit Ecm runnable, if any 1170 removeCallbacks(mExitEcmRunnable); 1171 1172 if (mEcmExitRespRegistrant != null) { 1173 mEcmExitRespRegistrant.notifyResult(Boolean.TRUE); 1174 } 1175 if (mIsPhoneInEcmState) { 1176 mIsPhoneInEcmState = false; 1177 setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 1178 } 1179 // send an Intent 1180 sendEmergencyCallbackModeChange(); 1181 } 1182 1183 /** 1184 * Handle to cancel or restart Ecm timer in emergency call back mode if action is 1185 * CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled; otherwise, restart 1186 * Ecm timer and notify apps the timer is restarted. 1187 */ 1188 void handleTimerInEmergencyCallbackMode(int action) { 1189 switch (action) { 1190 case CANCEL_ECM_TIMER: 1191 removeCallbacks(mExitEcmRunnable); 1192 if (mDefaultPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) { 1193 ((GSMPhone) mDefaultPhone).notifyEcbmTimerReset(Boolean.TRUE); 1194 } else { // Should be CDMA - also go here by default 1195 ((CDMAPhone) mDefaultPhone).notifyEcbmTimerReset(Boolean.TRUE); 1196 } 1197 break; 1198 case RESTART_ECM_TIMER: 1199 long delayInMillis = SystemProperties.getLong( 1200 TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); 1201 postDelayed(mExitEcmRunnable, delayInMillis); 1202 if (mDefaultPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) { 1203 ((GSMPhone) mDefaultPhone).notifyEcbmTimerReset(Boolean.FALSE); 1204 } else { // Should be CDMA - also go here by default 1205 ((CDMAPhone) mDefaultPhone).notifyEcbmTimerReset(Boolean.FALSE); 1206 } 1207 break; 1208 default: 1209 Rlog.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action); 1210 } 1211 } 1212 1213 public void setOnEcbModeExitResponse(Handler h, int what, Object obj) { 1214 mEcmExitRespRegistrant = new Registrant(h, what, obj); 1215 } 1216 1217 public void unsetOnEcbModeExitResponse(Handler h) { 1218 mEcmExitRespRegistrant.clear(); 1219 } 1220 1221 public boolean isVolteEnabled() { 1222 return mCT.isVolteEnabled(); 1223 } 1224 1225 public boolean isVtEnabled() { 1226 return mCT.isVtEnabled(); 1227 } 1228} 1229