1a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 22b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Copyright (C) 2013 The Android Open Source Project 3a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 42b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 52b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * you may not use this file except in compliance with the License. 62b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * You may obtain a copy of the License at 7a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 82b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 92b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * 102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Unless required by applicable law or agreed to in writing, software 112b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * See the License for the specific language governing permissions and 142b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * limitations under the License. 15a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 16a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 17a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepackage com.android.internal.telephony; 18a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 192b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport java.util.ArrayList; 202b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport java.util.Random; 212b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 22a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Context; 232b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport android.content.Intent; 242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport android.os.AsyncResult; 25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler; 26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Message; 272b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport android.os.PowerManager; 282b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport android.os.PowerManager.WakeLock; 292b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport android.telephony.RadioAccessFamily; 30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog; 31a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager; 32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandsInterface; 34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone; 35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneBase; 36a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneProxy; 37a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.dataconnection.DctController; 382b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport com.android.internal.telephony.RadioCapability; 39a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.uicc.UiccController; 402b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport com.android.internal.telephony.TelephonyIntents; 41a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 42e97be3971cb6b55e019433c32524cc60ce0d037bWink Savilleimport java.io.FileDescriptor; 43e97be3971cb6b55e019433c32524cc60ce0d037bWink Savilleimport java.io.PrintWriter; 442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Savilleimport java.util.concurrent.atomic.AtomicInteger; 45e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville 46a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepublic class ProxyController { 47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville static final String LOG_TAG = "ProxyController"; 48a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int EVENT_NOTIFICATION_RC_CHANGED = 1; 502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int EVENT_START_RC_RESPONSE = 2; 512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int EVENT_APPLY_RC_RESPONSE = 3; 522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int EVENT_FINISH_RC_RESPONSE = 4; 532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 542b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_IDLE = 0; 552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_STARTING = 1; 562b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_STARTED = 2; 572b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_APPLYING = 3; 582b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_SUCCESS = 4; 592b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_STATUS_FAIL = 5; 602b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 612b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // The entire transaction must complete within this amount of time 622b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // or a FINISH will be issued to each Logical Modem with the old 632b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Radio Access Family. 642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private static final int SET_RC_TIMEOUT_WAITING_MSEC = (45 * 1000); 652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Class Variables 67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static ProxyController sProxyController; 68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private PhoneProxy[] mProxyPhones; 70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccController mUiccController; 72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private CommandsInterface[] mCi; 74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private Context mContext; 76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 77e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville private DctController mDctController; 78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //UiccPhoneBookController to use proper IccPhoneBookInterfaceManagerProxy object 80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccPhoneBookController mUiccPhoneBookController; 81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //PhoneSubInfoController to use proper PhoneSubInfoProxy object 83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private PhoneSubInfoController mPhoneSubInfoController; 84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 85a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //UiccSmsController to use proper IccSmsInterfaceManager object 86a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccSmsController mUiccSmsController; 87a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 882b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville WakeLock mWakeLock; 892b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 902b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // record each phone's set radio capability status 912b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int[] mSetRadioAccessFamilyStatus; 922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int mRadioAccessFamilyStatusCounter; 932b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 942b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private String[] mLogicalModemIds; 952b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 962b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Allows the generation of unique Id's for radio capability request session id 972b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private AtomicInteger mUniqueIdGenerator = new AtomicInteger(new Random().nextInt()); 982b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 992b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // on-going radio capability request session id 1002b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int mRadioCapabilitySessionId; 1012b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1022b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Record new and old Radio Access Family (raf) configuration. 1032b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // The old raf configuration is used to restore each logical modem raf when FINISH is 1042b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // issued if any requests fail. 1052b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int[] mNewRadioAccessFamily; 1062b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int[] mOldRadioAccessFamily; 1072b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1082b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // runnable for radio capability request timeout handling 1092b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapabilityRunnable mSetRadioCapabilityRunnable; 1102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Class Methods 1122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public static ProxyController getInstance(Context context, PhoneProxy[] phoneProxy, 113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UiccController uiccController, CommandsInterface[] ci) { 114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (sProxyController == null) { 115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville sProxyController = new ProxyController(context, phoneProxy, uiccController, ci); 116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return sProxyController; 118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1204e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott public static ProxyController getInstance() { 121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return sProxyController; 122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private ProxyController(Context context, PhoneProxy[] phoneProxy, UiccController uiccController, 125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville CommandsInterface[] ci) { 126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville logd("Constructor - Enter"); 127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mContext = context; 129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mProxyPhones = phoneProxy; 130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccController = uiccController; 131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCi = ci; 132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1332b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mDctController = DctController.makeDctController(phoneProxy); 134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccPhoneBookController = new UiccPhoneBookController(mProxyPhones); 135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPhoneSubInfoController = new PhoneSubInfoController(mProxyPhones); 136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccSmsController = new UiccSmsController(mProxyPhones); 1372b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus = new int[mProxyPhones.length]; 1382b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mNewRadioAccessFamily = new int[mProxyPhones.length]; 1392b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mOldRadioAccessFamily = new int[mProxyPhones.length]; 1402b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mLogicalModemIds = new String[mProxyPhones.length]; 1412b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1422b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // TODO Get logical modem ids assume its just the phoneId as a string for now 1432b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 1442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mLogicalModemIds[i] = Integer.toString(i); 1452b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 1462b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1472b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioCapabilityRunnable = new RadioCapabilityRunnable(); 1482b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // wake lock for set radio capability 1502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 1512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); 1522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mWakeLock.setReferenceCounted(false); 1532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1542b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Clear to be sure we're in the initial state 1552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville clearTransaction(); 1564e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott for (int i = 0; i < mProxyPhones.length; i++) { 1574e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mProxyPhones[i].registerForRadioCapabilityChanged( 1584e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mHandler, EVENT_NOTIFICATION_RC_CHANGED, null); 1594e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott } 160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville logd("Constructor - Exit"); 161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1632b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void updateDataConnectionTracker(int sub) { 1642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[sub].updateDataConnectionTracker(); 1652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 1662b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1672b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void enableDataConnectivity(int sub) { 1682b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[sub].setInternalDataEnabled(true); 1692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 1702b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1712b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void disableDataConnectivity(int sub, 1722b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville Message dataCleanedUpMsg) { 1732b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[sub].setInternalDataEnabled(false, dataCleanedUpMsg); 1742b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 1752b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 1762b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void updateCurrentCarrierInProvider(int sub) { 1772b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[sub].updateCurrentCarrierInProvider(); 1782b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 1792b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 180b237a11044ed842d2865ff8c8716befb06b6ca25Wink Saville public void registerForAllDataDisconnected(int subId, Handler h, int what, Object obj) { 181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville int phoneId = SubscriptionController.getInstance().getPhoneId(subId); 182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) { 1842b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[phoneId].registerForAllDataDisconnected(h, what, obj); 185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 188b237a11044ed842d2865ff8c8716befb06b6ca25Wink Saville public void unregisterForAllDataDisconnected(int subId, Handler h) { 189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville int phoneId = SubscriptionController.getInstance().getPhoneId(subId); 190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) { 1922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[phoneId].unregisterForAllDataDisconnected(h); 193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 196b237a11044ed842d2865ff8c8716befb06b6ca25Wink Saville public boolean isDataDisconnected(int subId) { 197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville int phoneId = SubscriptionController.getInstance().getPhoneId(subId); 198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) { 2002b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville Phone activePhone = mProxyPhones[phoneId].getActivePhone(); 201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ((PhoneBase) activePhone).mDcTracker.isDisconnected(); 202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 2072b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 2082b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Get phone radio type and access technology. 2092b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * 2102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param phoneId which phone you want to get 2112b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @return phone radio type and access technology for input phone ID 2122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 2132b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public int getRadioAccessFamily(int phoneId) { 2142b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (phoneId >= mProxyPhones.length) { 2152b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return RadioAccessFamily.RAF_UNKNOWN; 2162b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 2172b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return mProxyPhones[phoneId].getRadioAccessFamily(); 2182b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2192b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2202b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2212b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 2222b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Set phone radio type and access technology for each phone. 2232b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * 2242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param rafs an RadioAccessFamily array to indicate all phone's 2252b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * new radio access family. The length of RadioAccessFamily 2262b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * must equal to phone count. 22712fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal * @return false if another session is already active and the request is rejected. 2282b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 22912fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal public boolean setRadioCapability(RadioAccessFamily[] rafs) { 2302b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (rafs.length != mProxyPhones.length) { 2312b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville throw new RuntimeException("Length of input rafs must equal to total phone count"); 2322b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2332b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2342b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Check if there is any ongoing transaction and throw an exception if there 2352b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // is one as this is a programming error. 2362b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 2372b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 2384e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("setRadioCapability: mSetRadioAccessFamilyStatus[" + i + "]=" 2394e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott + mSetRadioAccessFamilyStatus[i]); 2402b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_IDLE) { 24112fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal // TODO: The right behaviour is to cancel previous request and send this. 24212fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal loge("setRadioCapability: Phone[" + i + "] is not idle. Rejecting request."); 24312fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal return false; 2442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2452b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2462b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2472b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2482b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Clear to be sure we're in the initial state 2492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville clearTransaction(); 2502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // A new sessionId for this transaction 2522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioCapabilitySessionId = mUniqueIdGenerator.getAndIncrement(); 2532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2542b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Keep a wake lock until we finish radio capability changed 2552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mWakeLock.acquire(); 2562b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2572b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Start timer to make sure all phones respond within a specific time interval. 2582b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Will send FINISH if a timeout occurs. 2592b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioCapabilityRunnable.setTimeoutState(mRadioCapabilitySessionId); 2602b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mHandler.postDelayed(mSetRadioCapabilityRunnable, SET_RC_TIMEOUT_WAITING_MSEC); 2612b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2622b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 2634e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("setRadioCapability: new request session id=" + mRadioCapabilitySessionId); 2642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioAccessFamilyStatusCounter = rafs.length; 2652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < rafs.length; i++) { 2662b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville int phoneId = rafs[i].getPhoneId(); 2674e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("setRadioCapability: phoneId=" + phoneId + " status=STARTING"); 2682b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus[phoneId] = SET_RC_STATUS_STARTING; 2692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mOldRadioAccessFamily[phoneId] = mProxyPhones[phoneId].getRadioAccessFamily(); 2707e7d2b34010bf24a70bbf40303c7a4606c438adaStuart Scott int requestedRaf = rafs[i].getRadioAccessFamily(); 271972efd34f867b7803688c3f831106f59244a11f0Stuart Scott // TODO Set the new radio access family to the maximum of the requested & supported 272972efd34f867b7803688c3f831106f59244a11f0Stuart Scott // int supportedRaf = mProxyPhones[i].getSupportedRadioAccessFamily(); 273972efd34f867b7803688c3f831106f59244a11f0Stuart Scott // mNewRadioAccessFamily[phoneId] = requestedRaf & supportedRaf; 274972efd34f867b7803688c3f831106f59244a11f0Stuart Scott mNewRadioAccessFamily[phoneId] = requestedRaf; 2752b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("setRadioCapability: mOldRadioAccessFamily[" + phoneId + "]=" 2762b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + mOldRadioAccessFamily[phoneId]); 2772b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("setRadioCapability: mNewRadioAccessFamily[" + phoneId + "]=" 2782b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + mNewRadioAccessFamily[phoneId]); 2792b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville sendRadioCapabilityRequest( 2802b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville phoneId, 2812b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioCapabilitySessionId, 2822b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability.RC_PHASE_START, 2832b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mOldRadioAccessFamily[phoneId], 2842b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mLogicalModemIds[phoneId], 2852b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability.RC_STATUS_NONE, 2862b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville EVENT_START_RC_RESPONSE); 2872b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2882b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 28912fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal 29012fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal return true; 2912b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 2922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 2932b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private Handler mHandler = new Handler() { 2942b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville @Override 2952b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void handleMessage(Message msg) { 2964e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("handleMessage msg.what=" + msg.what); 2972b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville switch (msg.what) { 2982b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville case EVENT_START_RC_RESPONSE: 2992b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville onStartRadioCapabilityResponse(msg); 3002b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville break; 3012b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3022b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville case EVENT_APPLY_RC_RESPONSE: 3032b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville onApplyRadioCapabilityResponse(msg); 3042b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville break; 3052b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3062b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville case EVENT_NOTIFICATION_RC_CHANGED: 3072b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville onNotificationRadioCapabilityChanged(msg); 3082b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville break; 3092b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville case EVENT_FINISH_RC_RESPONSE: 3112b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville onFinishRadioCapabilityResponse(msg); 3122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville break; 3132b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3142b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville default: 3152b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville break; 3162b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3172b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3182b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville }; 3192b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3202b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 3212b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Handle START response 3222b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param msg obj field isa RadioCapability 3232b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 3242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void onStartRadioCapabilityResponse(Message msg) { 3252b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 3262b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result; 3272b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) { 3282b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onStartRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId 3292b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " rc=" + rc); 3302b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 3312b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3322b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioAccessFamilyStatusCounter--; 3334e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott int id = rc.getPhoneId(); 3342b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (((AsyncResult) msg.obj).exception != null) { 3352b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onStartRadioCapabilityResponse: Error response session=" + rc.getSession()); 3364e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=FAIL"); 3374e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL; 3382b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 3394e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=STARTED"); 3404e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED; 3412b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3422b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3432b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mRadioAccessFamilyStatusCounter == 0) { 3442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville resetRadioAccessFamilyStatusCounter(); 3452b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville boolean success = checkAllRadioCapabilitySuccess(); 3464e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onStartRadioCapabilityResponse: success=" + success); 3472b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (!success) { 3482b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville issueFinish(RadioCapability.RC_STATUS_FAIL, 3492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioCapabilitySessionId); 3502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 3512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // All logical modem accepted the new radio access family, issue the APPLY 3522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 3532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville sendRadioCapabilityRequest( 3542b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville i, 3552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioCapabilitySessionId, 3562b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability.RC_PHASE_APPLY, 3572b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mNewRadioAccessFamily[i], 3582b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mLogicalModemIds[i], 3592b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability.RC_STATUS_NONE, 3602b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville EVENT_APPLY_RC_RESPONSE); 3614e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott 3624e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onStartRadioCapabilityResponse: phoneId=" + i + " status=APPLYING"); 3632b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_APPLYING; 3642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3662b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3672b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3682b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3702b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 3712b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Handle APPLY response 3722b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param msg obj field isa RadioCapability 3732b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 3742b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void onApplyRadioCapabilityResponse(Message msg) { 3752b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result; 3762b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) { 3772b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onApplyRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId 3782b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " rc=" + rc); 3792b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 3802b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3812b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onApplyRadioCapabilityResponse: rc=" + rc); 3822b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (((AsyncResult) msg.obj).exception != null) { 3832b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 3842b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onApplyRadioCapabilityResponse: Error response session=" + rc.getSession()); 3854e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott int id = rc.getPhoneId(); 3864e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onApplyRadioCapabilityResponse: phoneId=" + id + " status=FAIL"); 3874e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL; 3882b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3892b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 3902b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onApplyRadioCapabilityResponse: Valid start expecting notification rc=" + rc); 3912b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 3932b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 3942b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 3952b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Handle the notification unsolicited response associated with the APPLY 3962b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param msg obj field isa RadioCapability 3972b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 3982b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void onNotificationRadioCapabilityChanged(Message msg) { 3992b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result; 4002b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) { 4012b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onNotificationRadioCapabilityChanged: Ignore session=" + mRadioCapabilitySessionId 4022b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " rc=" + rc); 4032b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 4042b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4052b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 4062b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onNotificationRadioCapabilityChanged: rc=" + rc); 4072b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // skip the overdue response by checking sessionId 4082b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (rc.getSession() != mRadioCapabilitySessionId) { 4092b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onNotificationRadioCapabilityChanged: Ignore session=" 4102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + mRadioCapabilitySessionId + " rc=" + rc); 4112b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 4122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4132b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 4144e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott int id = rc.getPhoneId(); 4152b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if ((((AsyncResult) msg.obj).exception != null) || 4162b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville (rc.getStatus() == RadioCapability.RC_STATUS_FAIL)) { 4174e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onNotificationRadioCapabilityChanged: phoneId=" + id + " status=FAIL"); 4184e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL; 4192b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 4204e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onNotificationRadioCapabilityChanged: phoneId=" + id + " status=SUCCESS"); 4214e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_SUCCESS; 4222b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4232b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 4242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioAccessFamilyStatusCounter--; 4252b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mRadioAccessFamilyStatusCounter == 0) { 4264e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onNotificationRadioCapabilityChanged: removing callback from handler"); 4272b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mHandler.removeCallbacks(mSetRadioCapabilityRunnable); 4282b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville resetRadioAccessFamilyStatusCounter(); 4292b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville boolean success = checkAllRadioCapabilitySuccess(); 4302b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onNotificationRadioCapabilityChanged: APPLY URC success=" + success); 4312b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville int status; 4322b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (success) { 4332b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville status = RadioCapability.RC_STATUS_SUCCESS; 4342b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 4352b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville status = RadioCapability.RC_STATUS_FAIL; 4362b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4372b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville issueFinish(status, mRadioCapabilitySessionId); 4382b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4392b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4402b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4412b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 4422b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 4432b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Handle the FINISH Phase response 4442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * @param msg obj field isa RadioCapability 4452b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 4462b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville void onFinishRadioCapabilityResponse(Message msg) { 4472b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result; 4482b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) { 4492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("onFinishRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId 4502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " rc=" + rc); 4512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 4522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized (mSetRadioAccessFamilyStatus) { 4544e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd(" onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter=" 4552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + mRadioAccessFamilyStatusCounter); 4562b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioAccessFamilyStatusCounter--; 4572b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mRadioAccessFamilyStatusCounter == 0) { 4582b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville completeRadioCapabilityTransaction(); 4592b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4602b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4612b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4622b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 4632b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void issueFinish(int status, int sessionId) { 4642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Issue FINISH 4652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized(mSetRadioAccessFamilyStatus) { 4662b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 4672b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_FAIL) { 4684e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("issueFinish: phoneId=" + i + " sessionId=" + sessionId 4692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " status=" + status); 4702b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville sendRadioCapabilityRequest( 4712b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville i, 4722b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville sessionId, 4732b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability.RC_PHASE_FINISH, 4742b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mOldRadioAccessFamily[i], 4752b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mLogicalModemIds[i], 4762b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville status, 4772b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville EVENT_FINISH_RC_RESPONSE); 4782b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (status == RadioCapability.RC_STATUS_FAIL) { 4794e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("issueFinish: phoneId: " + i + " status: FAIL"); 4802b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // At least one failed, mark them all failed. 4812b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_FAIL; 4822b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4832b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 4842b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("issueFinish: Ignore already FAIL, Phone" + i + " sessionId=" + sessionId 4852b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + " status=" + status); 4862b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4872b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4882b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4892b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 4902b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 4912b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void completeRadioCapabilityTransaction() { 4922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Create the intent to broadcast 4932b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville Intent intent; 4942b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville boolean success = checkAllRadioCapabilitySuccess(); 4954e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("onFinishRadioCapabilityResponse: success=" + success); 4962b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (success) { 4972b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville ArrayList<RadioAccessFamily> phoneRAFList = new ArrayList<RadioAccessFamily>(); 4982b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 4992b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville int raf = mProxyPhones[i].getRadioAccessFamily(); 5004e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("radioAccessFamily[" + i + "]=" + raf); 5012b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioAccessFamily phoneRC = new RadioAccessFamily(i, raf); 5022b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville phoneRAFList.add(phoneRC); 5032b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5042b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_DONE); 5052b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville intent.putParcelableArrayListExtra(TelephonyIntents.EXTRA_RADIO_ACCESS_FAMILY, 5062b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville phoneRAFList); 5072b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } else { 5082b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED); 5092b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5102b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5112b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Reinitialize 5122b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville clearTransaction(); 5132b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5142b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Broadcast that we're done 5152b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mContext.sendBroadcast(intent); 5162b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5172b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5182b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Clear this transaction 5192b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void clearTransaction() { 5204e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("clearTransaction"); 5212b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized(mSetRadioAccessFamilyStatus) { 5222b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 5234e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott logd("clearTransaction: phoneId=" + i + " status=IDLE"); 5242b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_IDLE; 5252b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mOldRadioAccessFamily[i] = 0; 5262b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mNewRadioAccessFamily[i] = 0; 5272b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5284e7f34de0e226703fadd1f30f9976bb426c5166bStuart Scott 5292b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mWakeLock.isHeld()) { 5302b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mWakeLock.release(); 5312b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5322b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5332b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5342b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5352b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private boolean checkAllRadioCapabilitySuccess() { 5362b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized(mSetRadioAccessFamilyStatus) { 5372b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 5382b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mSetRadioAccessFamilyStatus[i] == SET_RC_STATUS_FAIL) { 5392b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return false; 5402b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5412b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5422b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return true; 5432b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5442b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5452b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5462b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void resetRadioAccessFamilyStatusCounter() { 5472b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mRadioAccessFamilyStatusCounter = mProxyPhones.length; 5482b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5492b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5502b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private void sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase, 5512b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville int radioFamily, String logicalModemId, int status, int eventId) { 5522b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville RadioCapability requestRC = new RadioCapability( 5532b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville phoneId, sessionId, rcPhase, radioFamily, logicalModemId, status); 5542b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mProxyPhones[phoneId].setRadioCapability( 5552b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville requestRC, mHandler.obtainMessage(eventId)); 5562b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5572b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5582b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville /** 5592b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * RadioCapabilityRunnable is used to check 5602b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * if radio capability request's response is out of date. 5612b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * <p> 5622b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * Note that the setRadioCapability will be stopped directly and send FINISH 5632b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * with fail status to all logical modems. and send out fail intent 5642b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville * 5652b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville */ 5662b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private class RadioCapabilityRunnable implements Runnable { 5672b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville private int mSessionId; 5682b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public RadioCapabilityRunnable() { 5692b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5702b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5712b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void setTimeoutState(int sessionId) { 5722b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSessionId = sessionId; 5732b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5742b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5752b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville @Override 5762b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville public void run() { 5772b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville if (mSessionId != mRadioCapabilitySessionId) { 5782b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("RadioCapability timeout: Ignore mSessionId=" + mSessionId 5792b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville + "!= mRadioCapabilitySessionId=" + mRadioCapabilitySessionId); 5802b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville return; 5812b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5822b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5832b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville synchronized(mSetRadioAccessFamilyStatus) { 5842b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville for (int i = 0; i < mProxyPhones.length; i++) { 5852b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville logd("RadioCapability timeout: mSetRadioAccessFamilyStatus[" + i + "]=" + 5862b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville mSetRadioAccessFamilyStatus[i]); 5872b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5882b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5892b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // Increment the sessionId as we are completing the transaction below 5902b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // so we don't want it completed when the FINISH phase is done. 5912b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville int uniqueDifferentId = mUniqueIdGenerator.getAndIncrement(); 5922b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 5932b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville // send FINISH request with fail status and then uniqueDifferentId 5942b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville issueFinish(RadioCapability.RC_STATUS_FAIL, 5952b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville uniqueDifferentId); 5962b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville completeRadioCapabilityTransaction(); 5972b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5982b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 5992b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville } 6002b40e6226b4b71408964bca46f0a9f256cd4f523Wink Saville 601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private void logd(String string) { 602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, string); 603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 604e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville 60512fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal private void loge(String string) { 60612fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal Rlog.e(LOG_TAG, string); 60712fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal } 60812fe7c9dce4807d482bf1bcb8472dacae9aa34fdShishir Agrawal 609e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 610e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville try { 611e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville mDctController.dump(fd, pw, args); 612e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville } catch (Exception e) { 613e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville e.printStackTrace(); 614e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville } 615e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville } 616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 617