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 54 private static void logd(String s) { 55 Rlog.d(LOG_TAG, s); 56 } 57 58 private static void loge(String s) { 59 Rlog.e(LOG_TAG, s); 60 } 61 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 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 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 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 */ 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 124 public static void unregisterRIL(CommandsInterface cmdsIf) { 125 cmdsIf.unregisterForHardwareConfigChanged(sTelephonyDevController); 126 } 127 128 /** 129 * handle callbacks from RIL. 130 */ 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 */ 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 } 158 } 159 if (DBG) logd("updateOrInsert: inserting: " + hw); 160 list.add(hw); 161 } 162 } 163 164 /** 165 * hardware configuration changed. 166 */ 167 private static void handleGetHardwareConfigChanged(AsyncResult ar) { 168 if ((ar.exception == null) && (ar.result != null)) { 169 List hwcfg = (List)ar.result; 170 for (int i = 0 ; i < hwcfg.size() ; i++) { 171 HardwareConfig hw = null; 172 173 hw = (HardwareConfig) hwcfg.get(i); 174 if (hw != null) { 175 if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_MODEM) { 176 updateOrInsert(hw, mModems); 177 } else if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_SIM) { 178 updateOrInsert(hw, mSims); 179 } 180 } 181 } 182 } else { 183 /* error detected, ignore. are we missing some real time configutation 184 * at this point? what to do... 185 */ 186 loge("handleGetHardwareConfigChanged - returned an error."); 187 } 188 } 189 190 /** 191 * get total number of registered modem. 192 */ 193 public static int getModemCount() { 194 synchronized (mLock) { 195 int count = mModems.size(); 196 if (DBG) logd("getModemCount: " + count); 197 return count; 198 } 199 } 200 201 /** 202 * get modem at index 'index'. 203 */ 204 public HardwareConfig getModem(int index) { 205 synchronized (mLock) { 206 if (mModems.isEmpty()) { 207 loge("getModem: no registered modem device?!?"); 208 return null; 209 } 210 211 if (index > getModemCount()) { 212 loge("getModem: out-of-bounds access for modem device " + index + " max: " + getModemCount()); 213 return null; 214 } 215 216 if (DBG) logd("getModem: " + index); 217 return mModems.get(index); 218 } 219 } 220 221 /** 222 * get total number of registered sims. 223 */ 224 public int getSimCount() { 225 synchronized (mLock) { 226 int count = mSims.size(); 227 if (DBG) logd("getSimCount: " + count); 228 return count; 229 } 230 } 231 232 /** 233 * get sim at index 'index'. 234 */ 235 public HardwareConfig getSim(int index) { 236 synchronized (mLock) { 237 if (mSims.isEmpty()) { 238 loge("getSim: no registered sim device?!?"); 239 return null; 240 } 241 242 if (index > getSimCount()) { 243 loge("getSim: out-of-bounds access for sim device " + index + " max: " + getSimCount()); 244 return null; 245 } 246 247 if (DBG) logd("getSim: " + index); 248 return mSims.get(index); 249 } 250 } 251 252 /** 253 * get modem associated with sim index 'simIndex'. 254 */ 255 public HardwareConfig getModemForSim(int simIndex) { 256 synchronized (mLock) { 257 if (mModems.isEmpty() || mSims.isEmpty()) { 258 loge("getModemForSim: no registered modem/sim device?!?"); 259 return null; 260 } 261 262 if (simIndex > getSimCount()) { 263 loge("getModemForSim: out-of-bounds access for sim device " + simIndex + " max: " + getSimCount()); 264 return null; 265 } 266 267 if (DBG) logd("getModemForSim " + simIndex); 268 269 HardwareConfig sim = getSim(simIndex); 270 for (HardwareConfig modem: mModems) { 271 if (modem.uuid.equals(sim.modemUuid)) { 272 return modem; 273 } 274 } 275 276 return null; 277 } 278 } 279 280 /** 281 * get all sim's associated with modem at index 'modemIndex'. 282 */ 283 public ArrayList<HardwareConfig> getAllSimsForModem(int modemIndex) { 284 synchronized (mLock) { 285 if (mSims.isEmpty()) { 286 loge("getAllSimsForModem: no registered sim device?!?"); 287 return null; 288 } 289 290 if (modemIndex > getModemCount()) { 291 loge("getAllSimsForModem: out-of-bounds access for modem device " + modemIndex + " max: " + getModemCount()); 292 return null; 293 } 294 295 if (DBG) logd("getAllSimsForModem " + modemIndex); 296 297 ArrayList<HardwareConfig> result = new ArrayList<HardwareConfig>(); 298 HardwareConfig modem = getModem(modemIndex); 299 for (HardwareConfig sim: mSims) { 300 if (sim.modemUuid.equals(modem.uuid)) { 301 result.add(sim); 302 } 303 } 304 return result; 305 } 306 } 307 308 /** 309 * get all modem's registered. 310 */ 311 public ArrayList<HardwareConfig> getAllModems() { 312 synchronized (mLock) { 313 ArrayList<HardwareConfig> modems = new ArrayList<HardwareConfig>(); 314 if (mModems.isEmpty()) { 315 if (DBG) logd("getAllModems: empty list."); 316 } else { 317 for (HardwareConfig modem: mModems) { 318 modems.add(modem); 319 } 320 } 321 322 return modems; 323 } 324 } 325 326 /** 327 * get all sim's registered. 328 */ 329 public ArrayList<HardwareConfig> getAllSims() { 330 synchronized (mLock) { 331 ArrayList<HardwareConfig> sims = new ArrayList<HardwareConfig>(); 332 if (mSims.isEmpty()) { 333 if (DBG) logd("getAllSims: empty list."); 334 } else { 335 for (HardwareConfig sim: mSims) { 336 sims.add(sim); 337 } 338 } 339 340 return sims; 341 } 342 } 343 } 344