1 /* 2 * Copyright (C) 2009 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.cdma; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.content.res.XmlResourceParser; 22 import android.os.Message; 23 import android.util.Log; 24 import android.util.Xml; 25 26 import com.android.internal.telephony.Phone; 27 import com.android.internal.telephony.PhoneBase; 28 import com.android.internal.util.XmlUtils; 29 30 31 import org.xmlpull.v1.XmlPullParser; 32 import org.xmlpull.v1.XmlPullParserException; 33 34 import java.io.FileInputStream; 35 import java.io.FileNotFoundException; 36 import java.io.IOException; 37 import java.util.HashMap; 38 39 /** 40 * EriManager loads the ERI file definitions and manages the CDMA roaming information. 41 * 42 */ 43 public final class EriManager { 44 45 class EriFile { 46 47 public int mVersionNumber; // File version number 48 public int mNumberOfEriEntries; // Number of entries 49 public int mEriFileType; // Eri Phase 0/1 50 //public int mNumberOfIconImages; // reserved for future use 51 //public int mIconImageType; // reserved for future use 52 public String[] mCallPromptId; // reserved for future use 53 public HashMap<Integer, EriInfo> mRoamIndTable; // Roaming Indicator Table 54 EriFile()55 public EriFile() { 56 this.mVersionNumber = -1; 57 this.mNumberOfEriEntries = 0; 58 this.mEriFileType = -1; 59 this.mCallPromptId = new String[] { "", "", "" }; 60 this.mRoamIndTable = new HashMap<Integer, EriInfo>(); 61 } 62 } 63 64 class EriDisplayInformation { 65 public int mEriIconIndex; 66 public int mEriIconMode; 67 public String mEriIconText; 68 EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText)69 public EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) { 70 mEriIconIndex = eriIconIndex; 71 mEriIconMode = eriIconMode; 72 mEriIconText = eriIconText; 73 } 74 75 // public void setParameters(int eriIconIndex, int eriIconMode, String eriIconText){ 76 // this.mEriIconIndex = eriIconIndex; 77 // this.mEriIconMode = eriIconMode; 78 // this.mEriIconText = eriIconText; 79 // } 80 81 @Override toString()82 public String toString() { 83 return "EriDisplayInformation: {" + " IconIndex: " + mEriIconIndex + " EriIconMode: " 84 + mEriIconMode + " EriIconText: " + mEriIconText + " }"; 85 } 86 } 87 88 private static final String LOG_TAG = "CDMA"; 89 private static final boolean DBG = true; 90 private static final boolean VDBG = false; 91 92 public static final int ERI_FROM_XML = 0; 93 public static final int ERI_FROM_FILE_SYSTEM = 1; 94 public static final int ERI_FROM_MODEM = 2; 95 96 private PhoneBase mPhone; 97 private Context mContext; 98 private int mEriFileSource = ERI_FROM_XML; 99 private boolean isEriFileLoaded; 100 private EriFile mEriFile; 101 EriManager(PhoneBase phone, Context context, int eriFileSource)102 public EriManager(PhoneBase phone, Context context, int eriFileSource) { 103 this.mPhone = phone; 104 this.mContext = context; 105 this.mEriFileSource = eriFileSource; 106 this.mEriFile = new EriFile(); 107 } 108 dispose()109 public void dispose() { 110 mEriFile = new EriFile(); 111 isEriFileLoaded = false; 112 } 113 114 loadEriFile()115 public void loadEriFile() { 116 switch (mEriFileSource) { 117 case ERI_FROM_MODEM: 118 loadEriFileFromModem(); 119 break; 120 121 case ERI_FROM_FILE_SYSTEM: 122 loadEriFileFromFileSystem(); 123 break; 124 125 case ERI_FROM_XML: 126 default: 127 loadEriFileFromXml(); 128 break; 129 } 130 } 131 132 /** 133 * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK 134 * 135 * In this case the ERI file can be updated from the Phone Support Tool available 136 * from the Chipset vendor 137 */ loadEriFileFromModem()138 private void loadEriFileFromModem() { 139 // NOT IMPLEMENTED, Chipset vendor/Operator specific 140 } 141 142 /** 143 * Load the ERI file from a File System file 144 * 145 * In this case the a Phone Support Tool to update the ERI file must be provided 146 * to the Operator 147 */ loadEriFileFromFileSystem()148 private void loadEriFileFromFileSystem() { 149 // NOT IMPLEMENTED, Chipset vendor/Operator specific 150 } 151 152 /** 153 * Load the ERI file from the application framework resources encoded in XML 154 * 155 */ loadEriFileFromXml()156 private void loadEriFileFromXml() { 157 XmlPullParser parser = null; 158 FileInputStream stream = null; 159 Resources r = mContext.getResources(); 160 161 try { 162 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: check for alternate file"); 163 stream = new FileInputStream( 164 r.getString(com.android.internal.R.string.alternate_eri_file)); 165 parser = Xml.newPullParser(); 166 parser.setInput(stream, null); 167 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: opened alternate file"); 168 } catch (FileNotFoundException e) { 169 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no alternate file"); 170 parser = null; 171 } catch (XmlPullParserException e) { 172 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no parser for alternate file"); 173 parser = null; 174 } 175 176 if (parser == null) { 177 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: open normal file"); 178 parser = r.getXml(com.android.internal.R.xml.eri); 179 } 180 181 try { 182 XmlUtils.beginDocument(parser, "EriFile"); 183 mEriFile.mVersionNumber = Integer.parseInt( 184 parser.getAttributeValue(null, "VersionNumber")); 185 mEriFile.mNumberOfEriEntries = Integer.parseInt( 186 parser.getAttributeValue(null, "NumberOfEriEntries")); 187 mEriFile.mEriFileType = Integer.parseInt( 188 parser.getAttributeValue(null, "EriFileType")); 189 190 int parsedEriEntries = 0; 191 while(true) { 192 XmlUtils.nextElement(parser); 193 String name = parser.getName(); 194 if (name == null) { 195 if (parsedEriEntries != mEriFile.mNumberOfEriEntries) 196 Log.e(LOG_TAG, "Error Parsing ERI file: " + mEriFile.mNumberOfEriEntries 197 + " defined, " + parsedEriEntries + " parsed!"); 198 break; 199 } else if (name.equals("CallPromptId")) { 200 int id = Integer.parseInt(parser.getAttributeValue(null, "Id")); 201 String text = parser.getAttributeValue(null, "CallPromptText"); 202 if (id >= 0 && id <= 2) { 203 mEriFile.mCallPromptId[id] = text; 204 } else { 205 Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId"); 206 } 207 208 } else if (name.equals("EriInfo")) { 209 int roamingIndicator = Integer.parseInt( 210 parser.getAttributeValue(null, "RoamingIndicator")); 211 int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex")); 212 int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode")); 213 String eriText = parser.getAttributeValue(null, "EriText"); 214 int callPromptId = Integer.parseInt( 215 parser.getAttributeValue(null, "CallPromptId")); 216 int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId")); 217 parsedEriEntries++; 218 mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator, 219 iconIndex, iconMode, eriText, callPromptId, alertId)); 220 } 221 } 222 223 if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: eri parsing successful, file loaded"); 224 isEriFileLoaded = true; 225 226 } catch (Exception e) { 227 Log.e(LOG_TAG, "Got exception while loading ERI file.", e); 228 } finally { 229 if (parser instanceof XmlResourceParser) { 230 ((XmlResourceParser)parser).close(); 231 } 232 try { 233 if (stream != null) { 234 stream.close(); 235 } 236 } catch (IOException e) { 237 // Ignore 238 } 239 } 240 } 241 242 /** 243 * Returns the version of the ERI file 244 * 245 */ getEriFileVersion()246 public int getEriFileVersion() { 247 return mEriFile.mVersionNumber; 248 } 249 250 /** 251 * Returns the number of ERI entries parsed 252 * 253 */ getEriNumberOfEntries()254 public int getEriNumberOfEntries() { 255 return mEriFile.mNumberOfEriEntries; 256 } 257 258 /** 259 * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1) 260 * 261 */ getEriFileType()262 public int getEriFileType() { 263 return mEriFile.mEriFileType; 264 } 265 266 /** 267 * Returns if the ERI file has been loaded 268 * 269 */ isEriFileLoaded()270 public boolean isEriFileLoaded() { 271 return isEriFileLoaded; 272 } 273 274 /** 275 * Returns the EriInfo record associated with roamingIndicator 276 * or null if the entry is not found 277 */ getEriInfo(int roamingIndicator)278 private EriInfo getEriInfo(int roamingIndicator) { 279 if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) { 280 return mEriFile.mRoamIndTable.get(roamingIndicator); 281 } else { 282 return null; 283 } 284 } 285 getEriDisplayInformation(int roamInd, int defRoamInd)286 private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){ 287 EriDisplayInformation ret; 288 289 // Carrier can use eri.xml to customize any built-in roaming display indications 290 if (isEriFileLoaded) { 291 EriInfo eriInfo = getEriInfo(roamInd); 292 if (eriInfo != null) { 293 if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file"); 294 ret = new EriDisplayInformation( 295 eriInfo.mIconIndex, 296 eriInfo.mIconMode, 297 eriInfo.mEriText); 298 return ret; 299 } 300 } 301 302 switch (roamInd) { 303 // Handling the standard roaming indicator (non-ERI) 304 case EriInfo.ROAMING_INDICATOR_ON: 305 ret = new EriDisplayInformation( 306 EriInfo.ROAMING_INDICATOR_ON, 307 EriInfo.ROAMING_ICON_MODE_NORMAL, 308 mContext.getText(com.android.internal.R.string.roamingText0).toString()); 309 break; 310 311 case EriInfo.ROAMING_INDICATOR_OFF: 312 ret = new EriDisplayInformation( 313 EriInfo.ROAMING_INDICATOR_OFF, 314 EriInfo.ROAMING_ICON_MODE_NORMAL, 315 mContext.getText(com.android.internal.R.string.roamingText1).toString()); 316 break; 317 318 case EriInfo.ROAMING_INDICATOR_FLASH: 319 ret = new EriDisplayInformation( 320 EriInfo.ROAMING_INDICATOR_FLASH, 321 EriInfo.ROAMING_ICON_MODE_FLASH, 322 mContext.getText(com.android.internal.R.string.roamingText2).toString()); 323 break; 324 325 326 // Handling the standard ERI 327 case 3: 328 ret = new EriDisplayInformation( 329 roamInd, 330 EriInfo.ROAMING_ICON_MODE_NORMAL, 331 mContext.getText(com.android.internal.R.string.roamingText3).toString()); 332 break; 333 334 case 4: 335 ret = new EriDisplayInformation( 336 roamInd, 337 EriInfo.ROAMING_ICON_MODE_NORMAL, 338 mContext.getText(com.android.internal.R.string.roamingText4).toString()); 339 break; 340 341 case 5: 342 ret = new EriDisplayInformation( 343 roamInd, 344 EriInfo.ROAMING_ICON_MODE_NORMAL, 345 mContext.getText(com.android.internal.R.string.roamingText5).toString()); 346 break; 347 348 case 6: 349 ret = new EriDisplayInformation( 350 roamInd, 351 EriInfo.ROAMING_ICON_MODE_NORMAL, 352 mContext.getText(com.android.internal.R.string.roamingText6).toString()); 353 break; 354 355 case 7: 356 ret = new EriDisplayInformation( 357 roamInd, 358 EriInfo.ROAMING_ICON_MODE_NORMAL, 359 mContext.getText(com.android.internal.R.string.roamingText7).toString()); 360 break; 361 362 case 8: 363 ret = new EriDisplayInformation( 364 roamInd, 365 EriInfo.ROAMING_ICON_MODE_NORMAL, 366 mContext.getText(com.android.internal.R.string.roamingText8).toString()); 367 break; 368 369 case 9: 370 ret = new EriDisplayInformation( 371 roamInd, 372 EriInfo.ROAMING_ICON_MODE_NORMAL, 373 mContext.getText(com.android.internal.R.string.roamingText9).toString()); 374 break; 375 376 case 10: 377 ret = new EriDisplayInformation( 378 roamInd, 379 EriInfo.ROAMING_ICON_MODE_NORMAL, 380 mContext.getText(com.android.internal.R.string.roamingText10).toString()); 381 break; 382 383 case 11: 384 ret = new EriDisplayInformation( 385 roamInd, 386 EriInfo.ROAMING_ICON_MODE_NORMAL, 387 mContext.getText(com.android.internal.R.string.roamingText11).toString()); 388 break; 389 390 case 12: 391 ret = new EriDisplayInformation( 392 roamInd, 393 EriInfo.ROAMING_ICON_MODE_NORMAL, 394 mContext.getText(com.android.internal.R.string.roamingText12).toString()); 395 break; 396 397 // Handling the non standard Enhanced Roaming Indicator (roamInd > 63) 398 default: 399 if (!isEriFileLoaded) { 400 // ERI file NOT loaded 401 if (DBG) Log.d(LOG_TAG, "ERI File not loaded"); 402 if(defRoamInd > 2) { 403 if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd > 2 ...flashing"); 404 ret = new EriDisplayInformation( 405 EriInfo.ROAMING_INDICATOR_FLASH, 406 EriInfo.ROAMING_ICON_MODE_FLASH, 407 mContext.getText(com.android.internal 408 .R.string.roamingText2).toString()); 409 } else { 410 if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd <= 2"); 411 switch (defRoamInd) { 412 case EriInfo.ROAMING_INDICATOR_ON: 413 ret = new EriDisplayInformation( 414 EriInfo.ROAMING_INDICATOR_ON, 415 EriInfo.ROAMING_ICON_MODE_NORMAL, 416 mContext.getText(com.android.internal 417 .R.string.roamingText0).toString()); 418 break; 419 420 case EriInfo.ROAMING_INDICATOR_OFF: 421 ret = new EriDisplayInformation( 422 EriInfo.ROAMING_INDICATOR_OFF, 423 EriInfo.ROAMING_ICON_MODE_NORMAL, 424 mContext.getText(com.android.internal 425 .R.string.roamingText1).toString()); 426 break; 427 428 case EriInfo.ROAMING_INDICATOR_FLASH: 429 ret = new EriDisplayInformation( 430 EriInfo.ROAMING_INDICATOR_FLASH, 431 EriInfo.ROAMING_ICON_MODE_FLASH, 432 mContext.getText(com.android.internal 433 .R.string.roamingText2).toString()); 434 break; 435 436 default: 437 ret = new EriDisplayInformation(-1, -1, "ERI text"); 438 } 439 } 440 } else { 441 // ERI file loaded 442 EriInfo eriInfo = getEriInfo(roamInd); 443 EriInfo defEriInfo = getEriInfo(defRoamInd); 444 if (eriInfo == null) { 445 if (VDBG) { 446 Log.v(LOG_TAG, "ERI roamInd " + roamInd 447 + " not found in ERI file ...using defRoamInd " + defRoamInd); 448 } 449 if(defEriInfo == null) { 450 Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd 451 + " not found in ERI file ...on"); 452 ret = new EriDisplayInformation( 453 EriInfo.ROAMING_INDICATOR_ON, 454 EriInfo.ROAMING_ICON_MODE_NORMAL, 455 mContext.getText(com.android.internal 456 .R.string.roamingText0).toString()); 457 458 } else { 459 if (VDBG) { 460 Log.v(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file"); 461 } 462 ret = new EriDisplayInformation( 463 defEriInfo.mIconIndex, 464 defEriInfo.mIconMode, 465 defEriInfo.mEriText); 466 } 467 } else { 468 if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file"); 469 ret = new EriDisplayInformation( 470 eriInfo.mIconIndex, 471 eriInfo.mIconMode, 472 eriInfo.mEriText); 473 } 474 } 475 break; 476 } 477 if (VDBG) Log.v(LOG_TAG, "Displaying ERI " + ret.toString()); 478 return ret; 479 } 480 getCdmaEriIconIndex(int roamInd, int defRoamInd)481 public int getCdmaEriIconIndex(int roamInd, int defRoamInd){ 482 return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex; 483 } 484 getCdmaEriIconMode(int roamInd, int defRoamInd)485 public int getCdmaEriIconMode(int roamInd, int defRoamInd){ 486 return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode; 487 } 488 getCdmaEriText(int roamInd, int defRoamInd)489 public String getCdmaEriText(int roamInd, int defRoamInd){ 490 return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText; 491 } 492 } 493