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