Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 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.Context;
     20 import android.os.AsyncResult;
     21 import android.os.Handler;
     22 import android.os.Message;
     23 import android.os.Registrant;
     24 import android.os.RegistrantList;
     25 
     26 import com.android.internal.telephony.gsm.UsimServiceTable;
     27 import com.android.internal.telephony.ims.IsimRecords;
     28 
     29 /**
     30  * {@hide}
     31  */
     32 public abstract class IccRecords extends Handler implements IccConstants {
     33 
     34     protected static final boolean DBG = true;
     35     // ***** Instance Variables
     36     protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
     37     protected Context mContext;
     38     protected CommandsInterface mCi;
     39     protected IccFileHandler mFh;
     40     protected IccCard mParentCard;
     41 
     42     protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
     43     protected RegistrantList mRecordsEventsRegistrants = new RegistrantList();
     44     protected RegistrantList mNewSmsRegistrants = new RegistrantList();
     45     protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList();
     46 
     47     protected int recordsToLoad;  // number of pending load requests
     48 
     49     protected AdnRecordCache adnCache;
     50 
     51     // ***** Cached SIM State; cleared on channel close
     52 
     53     protected boolean recordsRequested = false; // true if we've made requests for the sim records
     54 
     55     public String iccid;
     56     protected String msisdn = null;  // My mobile number
     57     protected String msisdnTag = null;
     58     protected String voiceMailNum = null;
     59     protected String voiceMailTag = null;
     60     protected String newVoiceMailNum = null;
     61     protected String newVoiceMailTag = null;
     62     protected boolean isVoiceMailFixed = false;
     63     protected int countVoiceMessages = 0;
     64 
     65     protected int mncLength = UNINITIALIZED;
     66     protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
     67 
     68     protected String spn;
     69 
     70     // ***** Constants
     71 
     72     // Markers for mncLength
     73     protected static final int UNINITIALIZED = -1;
     74     protected static final int UNKNOWN = 0;
     75 
     76     // Bitmasks for SPN display rules.
     77     protected static final int SPN_RULE_SHOW_SPN  = 0x01;
     78     protected static final int SPN_RULE_SHOW_PLMN = 0x02;
     79 
     80     // ***** Event Constants
     81     protected static final int EVENT_SET_MSISDN_DONE = 30;
     82     public static final int EVENT_MWI = 0;
     83     public static final int EVENT_CFI = 1;
     84     public static final int EVENT_SPN = 2;
     85 
     86     public static final int EVENT_GET_ICC_RECORD_DONE = 100;
     87 
     88     /**
     89      * Generic ICC record loaded callback. Subclasses can call EF load methods on
     90      * {@link IccFileHandler} passing a Message for onLoaded with the what field set to
     91      * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance
     92      * of this interface. The {@link #handleMessage} method in this class will print a
     93      * log message using {@link #getEfName()} and decrement {@link #recordsToLoad}.
     94      *
     95      * If the record load was successful, {@link #onRecordLoaded} will be called with the result.
     96      * Otherwise, an error log message will be output by {@link #handleMessage} and
     97      * {@link #onRecordLoaded} will not be called.
     98      */
     99     public interface IccRecordLoaded {
    100         String getEfName();
    101         void onRecordLoaded(AsyncResult ar);
    102     }
    103 
    104     // ***** Constructor
    105     public IccRecords(IccCard card, Context c, CommandsInterface ci) {
    106         mContext = c;
    107         mCi = ci;
    108         mFh = card.getIccFileHandler();
    109         mParentCard = card;
    110     }
    111 
    112     /**
    113      * Call when the IccRecords object is no longer going to be used.
    114      */
    115     public void dispose() {
    116         mDestroyed = true;
    117         mParentCard = null;
    118         mFh = null;
    119         mCi = null;
    120         mContext = null;
    121     }
    122 
    123     protected abstract void onRadioOffOrNotAvailable();
    124     public abstract void onReady();
    125 
    126     //***** Public Methods
    127     public AdnRecordCache getAdnCache() {
    128         return adnCache;
    129     }
    130 
    131     public IccCard getIccCard() {
    132         return mParentCard;
    133     }
    134 
    135     public void registerForRecordsLoaded(Handler h, int what, Object obj) {
    136         if (mDestroyed) {
    137             return;
    138         }
    139 
    140         Registrant r = new Registrant(h, what, obj);
    141         recordsLoadedRegistrants.add(r);
    142 
    143         if (recordsToLoad == 0 && recordsRequested == true) {
    144             r.notifyRegistrant(new AsyncResult(null, null, null));
    145         }
    146     }
    147     public void unregisterForRecordsLoaded(Handler h) {
    148         recordsLoadedRegistrants.remove(h);
    149     }
    150 
    151     public void registerForRecordsEvents(Handler h, int what, Object obj) {
    152         Registrant r = new Registrant (h, what, obj);
    153         mRecordsEventsRegistrants.add(r);
    154     }
    155     public void unregisterForRecordsEvents(Handler h) {
    156         mRecordsEventsRegistrants.remove(h);
    157     }
    158 
    159     public void registerForNewSms(Handler h, int what, Object obj) {
    160         Registrant r = new Registrant (h, what, obj);
    161         mNewSmsRegistrants.add(r);
    162     }
    163     public void unregisterForNewSms(Handler h) {
    164         mNewSmsRegistrants.remove(h);
    165     }
    166 
    167     public void registerForNetworkSelectionModeAutomatic(
    168             Handler h, int what, Object obj) {
    169         Registrant r = new Registrant (h, what, obj);
    170         mNetworkSelectionModeAutomaticRegistrants.add(r);
    171     }
    172     public void unregisterForNetworkSelectionModeAutomatic(Handler h) {
    173         mNetworkSelectionModeAutomaticRegistrants.remove(h);
    174     }
    175 
    176     /**
    177      * Get the International Mobile Subscriber ID (IMSI) on a SIM
    178      * for GSM, UMTS and like networks. Default is null if IMSI is
    179      * not supported or unavailable.
    180      *
    181      * @return null if SIM is not yet ready or unavailable
    182      */
    183     public String getIMSI() {
    184         return null;
    185     }
    186 
    187     public String getMsisdnNumber() {
    188         return msisdn;
    189     }
    190 
    191     /**
    192      * Set subscriber number to SIM record
    193      *
    194      * The subscriber number is stored in EF_MSISDN (TS 51.011)
    195      *
    196      * When the operation is complete, onComplete will be sent to its handler
    197      *
    198      * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
    199      * @param number dailing nubmer (up to 20 digits)
    200      *        if the number starts with '+', then set to international TOA
    201      * @param onComplete
    202      *        onComplete.obj will be an AsyncResult
    203      *        ((AsyncResult)onComplete.obj).exception == null on success
    204      *        ((AsyncResult)onComplete.obj).exception != null on fail
    205      */
    206     public void setMsisdnNumber(String alphaTag, String number,
    207             Message onComplete) {
    208 
    209         msisdn = number;
    210         msisdnTag = alphaTag;
    211 
    212         if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn);
    213 
    214 
    215         AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
    216 
    217         new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
    218                 obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
    219     }
    220 
    221     public String getMsisdnAlphaTag() {
    222         return msisdnTag;
    223     }
    224 
    225     public String getVoiceMailNumber() {
    226         return voiceMailNum;
    227     }
    228 
    229     /**
    230      * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41)
    231      * @return null if SIM is not yet ready or no RUIM entry
    232      */
    233     public String getServiceProviderName() {
    234         return spn;
    235     }
    236 
    237     /**
    238      * Set voice mail number to SIM record
    239      *
    240      * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
    241      * EF_MAILBOX_CPHS (CPHS 4.2)
    242      *
    243      * If EF_MBDN is available, store the voice mail number to EF_MBDN
    244      *
    245      * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
    246      *
    247      * So the voice mail number will be stored in both EFs if both are available
    248      *
    249      * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
    250      *
    251      * When the operation is complete, onComplete will be sent to its handler
    252      *
    253      * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
    254      * @param voiceNumber dailing nubmer (upto 20 digits)
    255      *        if the number is start with '+', then set to international TOA
    256      * @param onComplete
    257      *        onComplete.obj will be an AsyncResult
    258      *        ((AsyncResult)onComplete.obj).exception == null on success
    259      *        ((AsyncResult)onComplete.obj).exception != null on fail
    260      */
    261     public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber,
    262             Message onComplete);
    263 
    264     public String getVoiceMailAlphaTag() {
    265         return voiceMailTag;
    266     }
    267 
    268     /**
    269      * Sets the SIM voice message waiting indicator records
    270      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
    271      * @param countWaiting The number of messages waiting, if known. Use
    272      *                     -1 to indicate that an unknown number of
    273      *                      messages are waiting
    274      */
    275     public abstract void setVoiceMessageWaiting(int line, int countWaiting);
    276 
    277     /** @return  true if there are messages waiting, false otherwise. */
    278     public boolean getVoiceMessageWaiting() {
    279         return countVoiceMessages != 0;
    280     }
    281 
    282     /**
    283      * Returns number of voice messages waiting, if available
    284      * If not available (eg, on an older CPHS SIM) -1 is returned if
    285      * getVoiceMessageWaiting() is true
    286      */
    287     public int getVoiceMessageCount() {
    288         return countVoiceMessages;
    289     }
    290 
    291     /**
    292      * Called by STK Service when REFRESH is received.
    293      * @param fileChanged indicates whether any files changed
    294      * @param fileList if non-null, a list of EF files that changed
    295      */
    296     public abstract void onRefresh(boolean fileChanged, int[] fileList);
    297 
    298 
    299     public boolean getRecordsLoaded() {
    300         if (recordsToLoad == 0 && recordsRequested == true) {
    301             return true;
    302         } else {
    303             return false;
    304         }
    305     }
    306 
    307     //***** Overridden from Handler
    308     @Override
    309     public void handleMessage(Message msg) {
    310         switch (msg.what) {
    311             case EVENT_GET_ICC_RECORD_DONE:
    312                 try {
    313                     AsyncResult ar = (AsyncResult) msg.obj;
    314                     IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj;
    315                     if (DBG) log(recordLoaded.getEfName() + " LOADED");
    316 
    317                     if (ar.exception != null) {
    318                         loge("Record Load Exception: " + ar.exception);
    319                     } else {
    320                         recordLoaded.onRecordLoaded(ar);
    321                     }
    322                 }catch (RuntimeException exc) {
    323                     // I don't want these exceptions to be fatal
    324                     loge("Exception parsing SIM record: " + exc);
    325                 } finally {
    326                     // Count up record load responses even if they are fails
    327                     onRecordLoaded();
    328                 }
    329                 break;
    330 
    331             default:
    332                 super.handleMessage(msg);
    333         }
    334     }
    335 
    336     protected abstract void onRecordLoaded();
    337 
    338     protected abstract void onAllRecordsLoaded();
    339 
    340     /**
    341      * Returns the SpnDisplayRule based on settings on the SIM and the
    342      * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
    343      * and TS 51.011 10.3.11 for details.
    344      *
    345      * If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
    346      * Generally used for GSM/UMTS and the like SIMs.
    347      */
    348     public abstract int getDisplayRule(String plmn);
    349 
    350     /**
    351      * Return true if "Restriction of menu options for manual PLMN selection"
    352      * bit is set or EF_CSP data is unavailable, return false otherwise.
    353      * Generally used for GSM/UMTS and the like SIMs.
    354      */
    355     public boolean isCspPlmnEnabled() {
    356         return false;
    357     }
    358 
    359     /**
    360      * Returns the 5 or 6 digit MCC/MNC of the operator that
    361      * provided the SIM card. Returns null of SIM is not yet ready
    362      * or is not valid for the type of IccCard. Generally used for
    363      * GSM/UMTS and the like SIMS
    364      */
    365     public String getOperatorNumeric() {
    366         return null;
    367     }
    368 
    369     /**
    370      * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs
    371      *
    372      * @return true if enabled
    373      */
    374     public boolean getVoiceCallForwardingFlag() {
    375         return false;
    376     }
    377 
    378     /**
    379      * Set the voice call forwarding flag for GSM/UMTS and the like SIMs
    380      *
    381      * @param line to enable/disable
    382      * @param enable
    383      */
    384     public void setVoiceCallForwardingFlag(int line, boolean enable) {
    385     }
    386 
    387     /**
    388      * Indicates wether SIM is in provisioned state or not.
    389      * Overridden only if SIM can be dynamically provisioned via OTA.
    390      *
    391      * @return true if provisioned
    392      */
    393     public boolean isProvisioned () {
    394         return true;
    395     }
    396 
    397     /**
    398      * Write string to log file
    399      *
    400      * @param s is the string to write
    401      */
    402     protected abstract void log(String s);
    403 
    404     /**
    405      * Write error string to log file.
    406      *
    407      * @param s is the string to write
    408      */
    409     protected abstract void loge(String s);
    410 
    411     /**
    412      * Return an interface to retrieve the ISIM records for IMS, if available.
    413      * @return the interface to retrieve the ISIM records, or null if not supported
    414      */
    415     public IsimRecords getIsimRecords() {
    416         return null;
    417     }
    418 
    419     public UsimServiceTable getUsimServiceTable() {
    420         return null;
    421     }
    422 }
    423