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