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