EriManager.java revision c38bb60d867c5d61d90b7179a9ed2b2d1848124f
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
17package com.android.internal.telephony.cdma;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.content.res.XmlResourceParser;
22import android.os.Message;
23import android.util.Log;
24import android.util.Xml;
25
26import com.android.internal.telephony.Phone;
27import com.android.internal.telephony.PhoneBase;
28import com.android.internal.util.XmlUtils;
29
30
31import org.xmlpull.v1.XmlPullParser;
32import org.xmlpull.v1.XmlPullParserException;
33
34import java.io.FileInputStream;
35import java.io.FileNotFoundException;
36import java.io.IOException;
37import java.util.HashMap;
38
39/**
40 * EriManager loads the ERI file definitions and manages the CDMA roaming information.
41 *
42 */
43public 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
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
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
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
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
109    public void dispose() {
110        mEriFile = new EriFile();
111        isEriFileLoaded = false;
112    }
113
114
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     */
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     */
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     */
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     */
246    public int getEriFileVersion() {
247        return mEriFile.mVersionNumber;
248    }
249
250    /**
251     * Returns the number of ERI entries parsed
252     *
253     */
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     */
262    public int getEriFileType() {
263        return mEriFile.mEriFileType;
264    }
265
266    /**
267     * Returns if the ERI file has been loaded
268     *
269     */
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     */
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
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
481    public int getCdmaEriIconIndex(int roamInd, int defRoamInd){
482        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex;
483    }
484
485    public int getCdmaEriIconMode(int roamInd, int defRoamInd){
486        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode;
487    }
488
489    public String getCdmaEriText(int roamInd, int defRoamInd){
490        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText;
491    }
492}
493