1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import android.content.res.Resources; 20 import com.android.internal.telephony.*; 21 import android.telephony.TelephonyManager; 22 23 import android.os.AsyncResult; 24 import android.telephony.Rlog; 25 import java.util.BitSet; 26 import java.util.List; 27 import java.util.ArrayList; 28 import android.text.TextUtils; 29 import android.os.Handler; 30 import android.os.Message; 31 import android.os.Registrant; 32 import android.os.RegistrantList; 33 import android.telephony.ServiceState; 34 35 /** 36 * TelephonyDevController - provides a unified view of the 37 * telephony hardware resources on a device. 38 * 39 * manages the set of HardwareConfig for the framework. 40 */ 41 public class TelephonyDevController extends Handler { 42 private static final String LOG_TAG = "TDC"; 43 private static final boolean DBG = true; 44 private static final Object mLock = new Object(); 45 46 private static final int EVENT_HARDWARE_CONFIG_CHANGED = 1; 47 48 private static TelephonyDevController sTelephonyDevController; 49 private static ArrayList<HardwareConfig> mModems = new ArrayList<HardwareConfig>(); 50 private static ArrayList<HardwareConfig> mSims = new ArrayList<HardwareConfig>(); 51 52 private static Message sRilHardwareConfig; 53 logd(String s)54 private static void logd(String s) { 55 Rlog.d(LOG_TAG, s); 56 } 57 loge(String s)58 private static void loge(String s) { 59 Rlog.e(LOG_TAG, s); 60 } 61 create()62 public static TelephonyDevController create() { 63 synchronized (mLock) { 64 if (sTelephonyDevController != null) { 65 throw new RuntimeException("TelephonyDevController already created!?!"); 66 } 67 sTelephonyDevController = new TelephonyDevController(); 68 return sTelephonyDevController; 69 } 70 } 71 getInstance()72 public static TelephonyDevController getInstance() { 73 synchronized (mLock) { 74 if (sTelephonyDevController == null) { 75 throw new RuntimeException("TelephonyDevController not yet created!?!"); 76 } 77 return sTelephonyDevController; 78 } 79 } 80 initFromResource()81 private void initFromResource() { 82 Resources resource = Resources.getSystem(); 83 String[] hwStrings = resource.getStringArray( 84 com.android.internal.R.array.config_telephonyHardware); 85 if (hwStrings != null) { 86 for (String hwString : hwStrings) { 87 HardwareConfig hw = new HardwareConfig(hwString); 88 if (hw != null) { 89 if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_MODEM) { 90 updateOrInsert(hw, mModems); 91 } else if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_SIM) { 92 updateOrInsert(hw, mSims); 93 } 94 } 95 } 96 } 97 } 98 TelephonyDevController()99 private TelephonyDevController() { 100 initFromResource(); 101 102 mModems.trimToSize(); 103 mSims.trimToSize(); 104 } 105 106 /** 107 * each RIL call this interface to register/unregister the unsolicited hardware 108 * configuration callback data it can provide. 109 */ registerRIL(CommandsInterface cmdsIf)110 public static void registerRIL(CommandsInterface cmdsIf) { 111 /* get the current configuration from this ril... */ 112 cmdsIf.getHardwareConfig(sRilHardwareConfig); 113 /* ... process it ... */ 114 if (sRilHardwareConfig != null) { 115 AsyncResult ar = (AsyncResult) sRilHardwareConfig.obj; 116 if (ar.exception == null) { 117 handleGetHardwareConfigChanged(ar); 118 } 119 } 120 /* and register for async device configuration change. */ 121 cmdsIf.registerForHardwareConfigChanged(sTelephonyDevController, EVENT_HARDWARE_CONFIG_CHANGED, null); 122 } 123 unregisterRIL(CommandsInterface cmdsIf)124 public static void unregisterRIL(CommandsInterface cmdsIf) { 125 cmdsIf.unregisterForHardwareConfigChanged(sTelephonyDevController); 126 } 127 128 /** 129 * handle callbacks from RIL. 130 */ handleMessage(Message msg)131 public void handleMessage(Message msg) { 132 AsyncResult ar; 133 switch (msg.what) { 134 case EVENT_HARDWARE_CONFIG_CHANGED: 135 if (DBG) logd("handleMessage: received EVENT_HARDWARE_CONFIG_CHANGED"); 136 ar = (AsyncResult) msg.obj; 137 handleGetHardwareConfigChanged(ar); 138 break; 139 default: 140 loge("handleMessage: Unknown Event " + msg.what); 141 } 142 } 143 144 /** 145 * hardware configuration update or insert. 146 */ updateOrInsert(HardwareConfig hw, ArrayList<HardwareConfig> list)147 private static void updateOrInsert(HardwareConfig hw, ArrayList<HardwareConfig> list) { 148 int size; 149 HardwareConfig item; 150 synchronized (mLock) { 151 size = list.size(); 152 for (int i = 0 ; i < size ; i++) { 153 item = list.get(i); 154 if (item.uuid.compareTo(hw.uuid) == 0) { 155 if (DBG) logd("updateOrInsert: removing: " + item); 156 list.remove(i); 157 break; 158 } 159 } 160 if (DBG) logd("updateOrInsert: inserting: " + hw); 161 list.add(hw); 162 } 163 } 164 165 /** 166 * hardware configuration changed. 167 */ handleGetHardwareConfigChanged(AsyncResult ar)168 private static void handleGetHardwareConfigChanged(AsyncResult ar) { 169 if ((ar.exception == null) && (ar.result != null)) { 170 List hwcfg = (List)ar.result; 171 for (int i = 0 ; i < hwcfg.size() ; i++) { 172 HardwareConfig hw = null; 173 174 hw = (HardwareConfig) hwcfg.get(i); 175 if (hw != null) { 176 if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_MODEM) { 177 updateOrInsert(hw, mModems); 178 } else if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_SIM) { 179 updateOrInsert(hw, mSims); 180 } 181 } 182 } 183 } else { 184 /* error detected, ignore. are we missing some real time configutation 185 * at this point? what to do... 186 */ 187 loge("handleGetHardwareConfigChanged - returned an error."); 188 } 189 } 190 191 /** 192 * get total number of registered modem. 193 */ getModemCount()194 public static int getModemCount() { 195 synchronized (mLock) { 196 int count = mModems.size(); 197 if (DBG) logd("getModemCount: " + count); 198 return count; 199 } 200 } 201 202 /** 203 * get modem at index 'index'. 204 */ getModem(int index)205 public HardwareConfig getModem(int index) { 206 synchronized (mLock) { 207 if (mModems.isEmpty()) { 208 loge("getModem: no registered modem device?!?"); 209 return null; 210 } 211 212 if (index > getModemCount()) { 213 loge("getModem: out-of-bounds access for modem device " + index + " max: " + getModemCount()); 214 return null; 215 } 216 217 if (DBG) logd("getModem: " + index); 218 return mModems.get(index); 219 } 220 } 221 222 /** 223 * get total number of registered sims. 224 */ getSimCount()225 public int getSimCount() { 226 synchronized (mLock) { 227 int count = mSims.size(); 228 if (DBG) logd("getSimCount: " + count); 229 return count; 230 } 231 } 232 233 /** 234 * get sim at index 'index'. 235 */ getSim(int index)236 public HardwareConfig getSim(int index) { 237 synchronized (mLock) { 238 if (mSims.isEmpty()) { 239 loge("getSim: no registered sim device?!?"); 240 return null; 241 } 242 243 if (index > getSimCount()) { 244 loge("getSim: out-of-bounds access for sim device " + index + " max: " + getSimCount()); 245 return null; 246 } 247 248 if (DBG) logd("getSim: " + index); 249 return mSims.get(index); 250 } 251 } 252 253 /** 254 * get modem associated with sim index 'simIndex'. 255 */ getModemForSim(int simIndex)256 public HardwareConfig getModemForSim(int simIndex) { 257 synchronized (mLock) { 258 if (mModems.isEmpty() || mSims.isEmpty()) { 259 loge("getModemForSim: no registered modem/sim device?!?"); 260 return null; 261 } 262 263 if (simIndex > getSimCount()) { 264 loge("getModemForSim: out-of-bounds access for sim device " + simIndex + " max: " + getSimCount()); 265 return null; 266 } 267 268 if (DBG) logd("getModemForSim " + simIndex); 269 270 HardwareConfig sim = getSim(simIndex); 271 for (HardwareConfig modem: mModems) { 272 if (modem.uuid.equals(sim.modemUuid)) { 273 return modem; 274 } 275 } 276 277 return null; 278 } 279 } 280 281 /** 282 * get all sim's associated with modem at index 'modemIndex'. 283 */ getAllSimsForModem(int modemIndex)284 public ArrayList<HardwareConfig> getAllSimsForModem(int modemIndex) { 285 synchronized (mLock) { 286 if (mSims.isEmpty()) { 287 loge("getAllSimsForModem: no registered sim device?!?"); 288 return null; 289 } 290 291 if (modemIndex > getModemCount()) { 292 loge("getAllSimsForModem: out-of-bounds access for modem device " + modemIndex + " max: " + getModemCount()); 293 return null; 294 } 295 296 if (DBG) logd("getAllSimsForModem " + modemIndex); 297 298 ArrayList<HardwareConfig> result = new ArrayList<HardwareConfig>(); 299 HardwareConfig modem = getModem(modemIndex); 300 for (HardwareConfig sim: mSims) { 301 if (sim.modemUuid.equals(modem.uuid)) { 302 result.add(sim); 303 } 304 } 305 return result; 306 } 307 } 308 309 /** 310 * get all modem's registered. 311 */ getAllModems()312 public ArrayList<HardwareConfig> getAllModems() { 313 synchronized (mLock) { 314 ArrayList<HardwareConfig> modems = new ArrayList<HardwareConfig>(); 315 if (mModems.isEmpty()) { 316 if (DBG) logd("getAllModems: empty list."); 317 } else { 318 for (HardwareConfig modem: mModems) { 319 modems.add(modem); 320 } 321 } 322 323 return modems; 324 } 325 } 326 327 /** 328 * get all sim's registered. 329 */ getAllSims()330 public ArrayList<HardwareConfig> getAllSims() { 331 synchronized (mLock) { 332 ArrayList<HardwareConfig> sims = new ArrayList<HardwareConfig>(); 333 if (mSims.isEmpty()) { 334 if (DBG) logd("getAllSims: empty list."); 335 } else { 336 for (HardwareConfig sim: mSims) { 337 sims.add(sim); 338 } 339 } 340 341 return sims; 342 } 343 } 344 } 345