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