Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2008 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 android.telephony;
     18 
     19 import android.annotation.PrivateApi;
     20 import android.annotation.SdkConstant;
     21 import android.annotation.SdkConstant.SdkConstantType;
     22 import android.content.Context;
     23 import android.os.Bundle;
     24 import android.os.Handler;
     25 import android.os.Message;
     26 import android.os.RemoteException;
     27 import android.os.ServiceManager;
     28 import android.os.SystemProperties;
     29 import android.telephony.Rlog;
     30 import android.util.Log;
     31 
     32 import com.android.internal.telephony.IPhoneSubInfo;
     33 import com.android.internal.telephony.ITelephony;
     34 import com.android.internal.telephony.ITelephonyListener;
     35 import com.android.internal.telephony.ITelephonyRegistry;
     36 import com.android.internal.telephony.PhoneConstants;
     37 import com.android.internal.telephony.RILConstants;
     38 import com.android.internal.telephony.TelephonyProperties;
     39 
     40 import java.io.FileInputStream;
     41 import java.io.IOException;
     42 import java.util.HashMap;
     43 import java.util.List;
     44 import java.util.regex.Matcher;
     45 import java.util.regex.Pattern;
     46 
     47 /**
     48  * Provides access to information about the telephony services on
     49  * the device. Applications can use the methods in this class to
     50  * determine telephony services and states, as well as to access some
     51  * types of subscriber information. Applications can also register
     52  * a listener to receive notification of telephony state changes.
     53  * <p>
     54  * You do not instantiate this class directly; instead, you retrieve
     55  * a reference to an instance through
     56  * {@link android.content.Context#getSystemService
     57  * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
     58  * <p>
     59  * Note that access to some telephony information is
     60  * permission-protected. Your application cannot access the protected
     61  * information unless it has the appropriate permissions declared in
     62  * its manifest file. Where permissions apply, they are noted in the
     63  * the methods through which you access the protected information.
     64  */
     65 public class TelephonyManager {
     66     private static final String TAG = "TelephonyManager";
     67 
     68     private static ITelephonyRegistry sRegistry;
     69 
     70     private final HashMap<CallStateListener,Listener> mListeners
     71             = new HashMap<CallStateListener,Listener>();
     72     private final Context mContext;
     73 
     74     private static class Listener extends ITelephonyListener.Stub {
     75         final CallStateListener mListener;
     76         private static final int WHAT = 1;
     77 
     78         private Handler mHandler = new Handler() {
     79             @Override
     80             public void handleMessage(Message msg) {
     81                 mListener.onCallStateChanged(msg.arg1, msg.arg2, (String)msg.obj);
     82             }
     83         };
     84 
     85         Listener(CallStateListener listener) {
     86             mListener = listener;
     87         }
     88 
     89         @Override
     90         public void onUpdate(final int callId, final int state, final String number) {
     91             if (mHandler != null) {
     92                 mHandler.sendMessage(mHandler.obtainMessage(WHAT, callId, state, number));
     93             }
     94         }
     95 
     96         void clearQueue() {
     97             mHandler.removeMessages(WHAT);
     98 
     99             // Don't accept more incoming binder calls either.
    100             mHandler = null;
    101         }
    102     }
    103 
    104     /** @hide */
    105     public TelephonyManager(Context context) {
    106         Context appContext = context.getApplicationContext();
    107         if (appContext != null) {
    108             mContext = appContext;
    109         } else {
    110             mContext = context;
    111         }
    112 
    113         if (sRegistry == null) {
    114             sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
    115                     "telephony.registry"));
    116         }
    117     }
    118 
    119     /** @hide */
    120     private TelephonyManager() {
    121         mContext = null;
    122     }
    123 
    124     private static TelephonyManager sInstance = new TelephonyManager();
    125 
    126     /** @hide
    127     /* @deprecated - use getSystemService as described above */
    128     public static TelephonyManager getDefault() {
    129         return sInstance;
    130     }
    131 
    132     /** {@hide} */
    133     public static TelephonyManager from(Context context) {
    134         return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    135     }
    136 
    137     //
    138     // Broadcast Intent actions
    139     //
    140 
    141     /**
    142      * Broadcast intent action indicating that the call state (cellular)
    143      * on the device has changed.
    144      *
    145      * <p>
    146      * The {@link #EXTRA_STATE} extra indicates the new call state.
    147      * If the new state is RINGING, a second extra
    148      * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
    149      * a String.
    150      *
    151      * <p class="note">
    152      * Requires the READ_PHONE_STATE permission.
    153      *
    154      * <p class="note">
    155      * This was a {@link android.content.Context#sendStickyBroadcast sticky}
    156      * broadcast in version 1.0, but it is no longer sticky.
    157      * Instead, use {@link #getCallState} to synchronously query the current call state.
    158      *
    159      * @see #EXTRA_STATE
    160      * @see #EXTRA_INCOMING_NUMBER
    161      * @see #getCallState
    162      */
    163     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    164     public static final String ACTION_PHONE_STATE_CHANGED =
    165             "android.intent.action.PHONE_STATE";
    166 
    167     /**
    168      * The Phone app sends this intent when a user opts to respond-via-message during an incoming
    169      * call. By default, the device's default SMS app consumes this message and sends a text message
    170      * to the caller. A third party app can also provide this functionality by consuming this Intent
    171      * with a {@link android.app.Service} and sending the message using its own messaging system.
    172      * <p>The intent contains a URI (available from {@link android.content.Intent#getData})
    173      * describing the recipient, using either the {@code sms:}, {@code smsto:}, {@code mms:},
    174      * or {@code mmsto:} URI schema. Each of these URI schema carry the recipient information the
    175      * same way: the path part of the URI contains the recipient's phone number or a comma-separated
    176      * set of phone numbers if there are multiple recipients. For example, {@code
    177      * smsto:2065551234}.</p>
    178      *
    179      * <p>The intent may also contain extras for the message text (in {@link
    180      * android.content.Intent#EXTRA_TEXT}) and a message subject
    181      * (in {@link android.content.Intent#EXTRA_SUBJECT}).</p>
    182      *
    183      * <p class="note"><strong>Note:</strong>
    184      * The intent-filter that consumes this Intent needs to be in a {@link android.app.Service}
    185      * that requires the
    186      * permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
    187      * <p>For example, the service that receives this intent can be declared in the manifest file
    188      * with an intent filter like this:</p>
    189      * <pre>
    190      * &lt;!-- Service that delivers SMS messages received from the phone "quick response" -->
    191      * &lt;service android:name=".HeadlessSmsSendService"
    192      *          android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
    193      *          android:exported="true" >
    194      *   &lt;intent-filter>
    195      *     &lt;action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
    196      *     &lt;category android:name="android.intent.category.DEFAULT" />
    197      *     &lt;data android:scheme="sms" />
    198      *     &lt;data android:scheme="smsto" />
    199      *     &lt;data android:scheme="mms" />
    200      *     &lt;data android:scheme="mmsto" />
    201      *   &lt;/intent-filter>
    202      * &lt;/service></pre>
    203      * <p>
    204      * Output: nothing.
    205      */
    206     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    207     public static final String ACTION_RESPOND_VIA_MESSAGE =
    208             "android.intent.action.RESPOND_VIA_MESSAGE";
    209 
    210     /**
    211      * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
    212      * for a String containing the new call state.
    213      *
    214      * @see #EXTRA_STATE_IDLE
    215      * @see #EXTRA_STATE_RINGING
    216      * @see #EXTRA_STATE_OFFHOOK
    217      *
    218      * <p class="note">
    219      * Retrieve with
    220      * {@link android.content.Intent#getStringExtra(String)}.
    221      */
    222     public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
    223 
    224     /**
    225      * Value used with {@link #EXTRA_STATE} corresponding to
    226      * {@link #CALL_STATE_IDLE}.
    227      */
    228     public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
    229 
    230     /**
    231      * Value used with {@link #EXTRA_STATE} corresponding to
    232      * {@link #CALL_STATE_RINGING}.
    233      */
    234     public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
    235 
    236     /**
    237      * Value used with {@link #EXTRA_STATE} corresponding to
    238      * {@link #CALL_STATE_OFFHOOK}.
    239      */
    240     public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
    241 
    242     /**
    243      * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
    244      * for a String containing the incoming phone number.
    245      * Only valid when the new call state is RINGING.
    246      *
    247      * <p class="note">
    248      * Retrieve with
    249      * {@link android.content.Intent#getStringExtra(String)}.
    250      */
    251     public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
    252 
    253 
    254     //
    255     //
    256     // Device Info
    257     //
    258     //
    259 
    260     /**
    261      * Returns the software version number for the device, for example,
    262      * the IMEI/SV for GSM phones. Return null if the software version is
    263      * not available.
    264      *
    265      * <p>Requires Permission:
    266      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
    267      */
    268     public String getDeviceSoftwareVersion() {
    269         try {
    270             return getSubscriberInfo().getDeviceSvn();
    271         } catch (RemoteException ex) {
    272             return null;
    273         } catch (NullPointerException ex) {
    274             return null;
    275         }
    276     }
    277 
    278     /**
    279      * Returns the unique device ID, for example, the IMEI for GSM and the MEID
    280      * or ESN for CDMA phones. Return null if device ID is not available.
    281      *
    282      * <p>Requires Permission:
    283      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
    284      */
    285     public String getDeviceId() {
    286         try {
    287             return getSubscriberInfo().getDeviceId();
    288         } catch (RemoteException ex) {
    289             return null;
    290         } catch (NullPointerException ex) {
    291             return null;
    292         }
    293     }
    294 
    295     /**
    296      * Returns the current location of the device.
    297      *<p>
    298      * If there is only one radio in the device and that radio has an LTE connection,
    299      * this method will return null. The implementation must not to try add LTE
    300      * identifiers into the existing cdma/gsm classes.
    301      *<p>
    302      * In the future this call will be deprecated.
    303      *<p>
    304      * @return Current location of the device or null if not available.
    305      *
    306      * <p>Requires Permission:
    307      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
    308      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
    309      */
    310     public CellLocation getCellLocation() {
    311         try {
    312             Bundle bundle = getITelephony().getCellLocation();
    313             if (bundle.isEmpty()) return null;
    314             CellLocation cl = CellLocation.newFromBundle(bundle);
    315             if (cl.isEmpty())
    316                 return null;
    317             return cl;
    318         } catch (RemoteException ex) {
    319             return null;
    320         } catch (NullPointerException ex) {
    321             return null;
    322         }
    323     }
    324 
    325     /**
    326      * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
    327      * PhoneStateListener.onCellLocationChanged} will be called on location updates.
    328      *
    329      * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
    330      * CONTROL_LOCATION_UPDATES}
    331      *
    332      * @hide
    333      */
    334     public void enableLocationUpdates() {
    335         try {
    336             getITelephony().enableLocationUpdates();
    337         } catch (RemoteException ex) {
    338         } catch (NullPointerException ex) {
    339         }
    340     }
    341 
    342     /**
    343      * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
    344      * PhoneStateListener.onCellLocationChanged} will be called on location updates.
    345      *
    346      * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
    347      * CONTROL_LOCATION_UPDATES}
    348      *
    349      * @hide
    350      */
    351     public void disableLocationUpdates() {
    352         try {
    353             getITelephony().disableLocationUpdates();
    354         } catch (RemoteException ex) {
    355         } catch (NullPointerException ex) {
    356         }
    357     }
    358 
    359     /**
    360      * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
    361      * and use this only if getAllCellInfo return nulls or an empty list.
    362      *<p>
    363      * In the future this call will be deprecated.
    364      *<p>
    365      * @return List of NeighboringCellInfo or null if info unavailable.
    366      *
    367      * <p>Requires Permission:
    368      * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
    369      */
    370     public List<NeighboringCellInfo> getNeighboringCellInfo() {
    371         try {
    372             return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName());
    373         } catch (RemoteException ex) {
    374             return null;
    375         } catch (NullPointerException ex) {
    376             return null;
    377         }
    378     }
    379 
    380     /** No phone radio. */
    381     public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
    382     /** Phone radio is GSM. */
    383     public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
    384     /** Phone radio is CDMA. */
    385     public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
    386     /** Phone is via SIP. */
    387     public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
    388 
    389     /**
    390      * Returns the current phone type.
    391      * TODO: This is a last minute change and hence hidden.
    392      *
    393      * @see #PHONE_TYPE_NONE
    394      * @see #PHONE_TYPE_GSM
    395      * @see #PHONE_TYPE_CDMA
    396      * @see #PHONE_TYPE_SIP
    397      *
    398      * {@hide}
    399      */
    400     public int getCurrentPhoneType() {
    401         try{
    402             ITelephony telephony = getITelephony();
    403             if (telephony != null) {
    404                 return telephony.getActivePhoneType();
    405             } else {
    406                 // This can happen when the ITelephony interface is not up yet.
    407                 return getPhoneTypeFromProperty();
    408             }
    409         } catch (RemoteException ex) {
    410             // This shouldn't happen in the normal case, as a backup we
    411             // read from the system property.
    412             return getPhoneTypeFromProperty();
    413         } catch (NullPointerException ex) {
    414             // This shouldn't happen in the normal case, as a backup we
    415             // read from the system property.
    416             return getPhoneTypeFromProperty();
    417         }
    418     }
    419 
    420     /**
    421      * Returns a constant indicating the device phone type.  This
    422      * indicates the type of radio used to transmit voice calls.
    423      *
    424      * @see #PHONE_TYPE_NONE
    425      * @see #PHONE_TYPE_GSM
    426      * @see #PHONE_TYPE_CDMA
    427      * @see #PHONE_TYPE_SIP
    428      */
    429     public int getPhoneType() {
    430         if (!isVoiceCapable()) {
    431             return PHONE_TYPE_NONE;
    432         }
    433         return getCurrentPhoneType();
    434     }
    435 
    436     private int getPhoneTypeFromProperty() {
    437         int type =
    438             SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE,
    439                     getPhoneTypeFromNetworkType());
    440         return type;
    441     }
    442 
    443     private int getPhoneTypeFromNetworkType() {
    444         // When the system property CURRENT_ACTIVE_PHONE, has not been set,
    445         // use the system property for default network type.
    446         // This is a fail safe, and can only happen at first boot.
    447         int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
    448         if (mode == -1)
    449             return PHONE_TYPE_NONE;
    450         return getPhoneType(mode);
    451     }
    452 
    453     /**
    454      * This function returns the type of the phone, depending
    455      * on the network mode.
    456      *
    457      * @param networkMode
    458      * @return Phone Type
    459      *
    460      * @hide
    461      */
    462     public static int getPhoneType(int networkMode) {
    463         switch(networkMode) {
    464         case RILConstants.NETWORK_MODE_CDMA:
    465         case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
    466         case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
    467             return PhoneConstants.PHONE_TYPE_CDMA;
    468 
    469         case RILConstants.NETWORK_MODE_WCDMA_PREF:
    470         case RILConstants.NETWORK_MODE_GSM_ONLY:
    471         case RILConstants.NETWORK_MODE_WCDMA_ONLY:
    472         case RILConstants.NETWORK_MODE_GSM_UMTS:
    473         case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
    474         case RILConstants.NETWORK_MODE_LTE_WCDMA:
    475         case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
    476             return PhoneConstants.PHONE_TYPE_GSM;
    477 
    478         // Use CDMA Phone for the global mode including CDMA
    479         case RILConstants.NETWORK_MODE_GLOBAL:
    480         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
    481             return PhoneConstants.PHONE_TYPE_CDMA;
    482 
    483         case RILConstants.NETWORK_MODE_LTE_ONLY:
    484             if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
    485                 return PhoneConstants.PHONE_TYPE_CDMA;
    486             } else {
    487                 return PhoneConstants.PHONE_TYPE_GSM;
    488             }
    489         default:
    490             return PhoneConstants.PHONE_TYPE_GSM;
    491         }
    492     }
    493 
    494     /**
    495      * The contents of the /proc/cmdline file
    496      */
    497     private static String getProcCmdLine()
    498     {
    499         String cmdline = "";
    500         FileInputStream is = null;
    501         try {
    502             is = new FileInputStream("/proc/cmdline");
    503             byte [] buffer = new byte[2048];
    504             int count = is.read(buffer);
    505             if (count > 0) {
    506                 cmdline = new String(buffer, 0, count);
    507             }
    508         } catch (IOException e) {
    509             Rlog.d(TAG, "No /proc/cmdline exception=" + e);
    510         } finally {
    511             if (is != null) {
    512                 try {
    513                     is.close();
    514                 } catch (IOException e) {
    515                 }
    516             }
    517         }
    518         Rlog.d(TAG, "/proc/cmdline=" + cmdline);
    519         return cmdline;
    520     }
    521 
    522     /** Kernel command line */
    523     private static final String sKernelCmdLine = getProcCmdLine();
    524 
    525     /** Pattern for selecting the product type from the kernel command line */
    526     private static final Pattern sProductTypePattern =
    527         Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
    528 
    529     /** The ProductType used for LTE on CDMA devices */
    530     private static final String sLteOnCdmaProductType =
    531         SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
    532 
    533     /**
    534      * Return if the current radio is LTE on CDMA. This
    535      * is a tri-state return value as for a period of time
    536      * the mode may be unknown.
    537      *
    538      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
    539      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
    540      *
    541      * @hide
    542      */
    543     public static int getLteOnCdmaModeStatic() {
    544         int retVal;
    545         int curVal;
    546         String productType = "";
    547 
    548         curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
    549                     PhoneConstants.LTE_ON_CDMA_UNKNOWN);
    550         retVal = curVal;
    551         if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
    552             Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
    553             if (matcher.find()) {
    554                 productType = matcher.group(1);
    555                 if (sLteOnCdmaProductType.equals(productType)) {
    556                     retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
    557                 } else {
    558                     retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
    559                 }
    560             } else {
    561                 retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
    562             }
    563         }
    564 
    565         Rlog.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
    566                 " product_type='" + productType +
    567                 "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
    568         return retVal;
    569     }
    570 
    571     //
    572     //
    573     // Current Network
    574     //
    575     //
    576 
    577     /**
    578      * Returns the alphabetic name of current registered operator.
    579      * <p>
    580      * Availability: Only when user is registered to a network. Result may be
    581      * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
    582      * on a CDMA network).
    583      */
    584     public String getNetworkOperatorName() {
    585         return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
    586     }
    587 
    588     /**
    589      * Returns the numeric name (MCC+MNC) of current registered operator.
    590      * <p>
    591      * Availability: Only when user is registered to a network. Result may be
    592      * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
    593      * on a CDMA network).
    594      */
    595     public String getNetworkOperator() {
    596         return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
    597     }
    598 
    599     /**
    600      * Returns true if the device is considered roaming on the current
    601      * network, for GSM purposes.
    602      * <p>
    603      * Availability: Only when user registered to a network.
    604      */
    605     public boolean isNetworkRoaming() {
    606         return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
    607     }
    608 
    609     /**
    610      * Returns the ISO country code equivalent of the current registered
    611      * operator's MCC (Mobile Country Code).
    612      * <p>
    613      * Availability: Only when user is registered to a network. Result may be
    614      * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
    615      * on a CDMA network).
    616      */
    617     public String getNetworkCountryIso() {
    618         return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
    619     }
    620 
    621     /** Network type is unknown */
    622     public static final int NETWORK_TYPE_UNKNOWN = 0;
    623     /** Current network is GPRS */
    624     public static final int NETWORK_TYPE_GPRS = 1;
    625     /** Current network is EDGE */
    626     public static final int NETWORK_TYPE_EDGE = 2;
    627     /** Current network is UMTS */
    628     public static final int NETWORK_TYPE_UMTS = 3;
    629     /** Current network is CDMA: Either IS95A or IS95B*/
    630     public static final int NETWORK_TYPE_CDMA = 4;
    631     /** Current network is EVDO revision 0*/
    632     public static final int NETWORK_TYPE_EVDO_0 = 5;
    633     /** Current network is EVDO revision A*/
    634     public static final int NETWORK_TYPE_EVDO_A = 6;
    635     /** Current network is 1xRTT*/
    636     public static final int NETWORK_TYPE_1xRTT = 7;
    637     /** Current network is HSDPA */
    638     public static final int NETWORK_TYPE_HSDPA = 8;
    639     /** Current network is HSUPA */
    640     public static final int NETWORK_TYPE_HSUPA = 9;
    641     /** Current network is HSPA */
    642     public static final int NETWORK_TYPE_HSPA = 10;
    643     /** Current network is iDen */
    644     public static final int NETWORK_TYPE_IDEN = 11;
    645     /** Current network is EVDO revision B*/
    646     public static final int NETWORK_TYPE_EVDO_B = 12;
    647     /** Current network is LTE */
    648     public static final int NETWORK_TYPE_LTE = 13;
    649     /** Current network is eHRPD */
    650     public static final int NETWORK_TYPE_EHRPD = 14;
    651     /** Current network is HSPA+ */
    652     public static final int NETWORK_TYPE_HSPAP = 15;
    653 
    654     /**
    655      * @return the NETWORK_TYPE_xxxx for current data connection.
    656      */
    657     public int getNetworkType() {
    658         return getDataNetworkType();
    659     }
    660 
    661     /**
    662      * Returns a constant indicating the radio technology (network type)
    663      * currently in use on the device for data transmission.
    664      * @return the network type
    665      *
    666      * @see #NETWORK_TYPE_UNKNOWN
    667      * @see #NETWORK_TYPE_GPRS
    668      * @see #NETWORK_TYPE_EDGE
    669      * @see #NETWORK_TYPE_UMTS
    670      * @see #NETWORK_TYPE_HSDPA
    671      * @see #NETWORK_TYPE_HSUPA
    672      * @see #NETWORK_TYPE_HSPA
    673      * @see #NETWORK_TYPE_CDMA
    674      * @see #NETWORK_TYPE_EVDO_0
    675      * @see #NETWORK_TYPE_EVDO_A
    676      * @see #NETWORK_TYPE_EVDO_B
    677      * @see #NETWORK_TYPE_1xRTT
    678      * @see #NETWORK_TYPE_IDEN
    679      * @see #NETWORK_TYPE_LTE
    680      * @see #NETWORK_TYPE_EHRPD
    681      * @see #NETWORK_TYPE_HSPAP
    682      *
    683      * @hide
    684      */
    685     public int getDataNetworkType() {
    686         try{
    687             ITelephony telephony = getITelephony();
    688             if (telephony != null) {
    689                 return telephony.getDataNetworkType();
    690             } else {
    691                 // This can happen when the ITelephony interface is not up yet.
    692                 return NETWORK_TYPE_UNKNOWN;
    693             }
    694         } catch(RemoteException ex) {
    695             // This shouldn't happen in the normal case
    696             return NETWORK_TYPE_UNKNOWN;
    697         } catch (NullPointerException ex) {
    698             // This could happen before phone restarts due to crashing
    699             return NETWORK_TYPE_UNKNOWN;
    700         }
    701     }
    702 
    703     /**
    704      * Returns the NETWORK_TYPE_xxxx for voice
    705      *
    706      * @hide
    707      */
    708     public int getVoiceNetworkType() {
    709         try{
    710             ITelephony telephony = getITelephony();
    711             if (telephony != null) {
    712                 return telephony.getVoiceNetworkType();
    713             } else {
    714                 // This can happen when the ITelephony interface is not up yet.
    715                 return NETWORK_TYPE_UNKNOWN;
    716             }
    717         } catch(RemoteException ex) {
    718             // This shouldn't happen in the normal case
    719             return NETWORK_TYPE_UNKNOWN;
    720         } catch (NullPointerException ex) {
    721             // This could happen before phone restarts due to crashing
    722             return NETWORK_TYPE_UNKNOWN;
    723         }
    724     }
    725 
    726     /** Unknown network class. {@hide} */
    727     public static final int NETWORK_CLASS_UNKNOWN = 0;
    728     /** Class of broadly defined "2G" networks. {@hide} */
    729     public static final int NETWORK_CLASS_2_G = 1;
    730     /** Class of broadly defined "3G" networks. {@hide} */
    731     public static final int NETWORK_CLASS_3_G = 2;
    732     /** Class of broadly defined "4G" networks. {@hide} */
    733     public static final int NETWORK_CLASS_4_G = 3;
    734 
    735     /**
    736      * Return general class of network type, such as "3G" or "4G". In cases
    737      * where classification is contentious, this method is conservative.
    738      *
    739      * @hide
    740      */
    741     public static int getNetworkClass(int networkType) {
    742         switch (networkType) {
    743             case NETWORK_TYPE_GPRS:
    744             case NETWORK_TYPE_EDGE:
    745             case NETWORK_TYPE_CDMA:
    746             case NETWORK_TYPE_1xRTT:
    747             case NETWORK_TYPE_IDEN:
    748                 return NETWORK_CLASS_2_G;
    749             case NETWORK_TYPE_UMTS:
    750             case NETWORK_TYPE_EVDO_0:
    751             case NETWORK_TYPE_EVDO_A:
    752             case NETWORK_TYPE_HSDPA:
    753             case NETWORK_TYPE_HSUPA:
    754             case NETWORK_TYPE_HSPA:
    755             case NETWORK_TYPE_EVDO_B:
    756             case NETWORK_TYPE_EHRPD:
    757             case NETWORK_TYPE_HSPAP:
    758                 return NETWORK_CLASS_3_G;
    759             case NETWORK_TYPE_LTE:
    760                 return NETWORK_CLASS_4_G;
    761             default:
    762                 return NETWORK_CLASS_UNKNOWN;
    763         }
    764     }
    765 
    766     /**
    767      * Returns a string representation of the radio technology (network type)
    768      * currently in use on the device.
    769      * @return the name of the radio technology
    770      *
    771      * @hide pending API council review
    772      */
    773     public String getNetworkTypeName() {
    774         return getNetworkTypeName(getNetworkType());
    775     }
    776 
    777     /** {@hide} */
    778     public static String getNetworkTypeName(int type) {
    779         switch (type) {
    780             case NETWORK_TYPE_GPRS:
    781                 return "GPRS";
    782             case NETWORK_TYPE_EDGE:
    783                 return "EDGE";
    784             case NETWORK_TYPE_UMTS:
    785                 return "UMTS";
    786             case NETWORK_TYPE_HSDPA:
    787                 return "HSDPA";
    788             case NETWORK_TYPE_HSUPA:
    789                 return "HSUPA";
    790             case NETWORK_TYPE_HSPA:
    791                 return "HSPA";
    792             case NETWORK_TYPE_CDMA:
    793                 return "CDMA";
    794             case NETWORK_TYPE_EVDO_0:
    795                 return "CDMA - EvDo rev. 0";
    796             case NETWORK_TYPE_EVDO_A:
    797                 return "CDMA - EvDo rev. A";
    798             case NETWORK_TYPE_EVDO_B:
    799                 return "CDMA - EvDo rev. B";
    800             case NETWORK_TYPE_1xRTT:
    801                 return "CDMA - 1xRTT";
    802             case NETWORK_TYPE_LTE:
    803                 return "LTE";
    804             case NETWORK_TYPE_EHRPD:
    805                 return "CDMA - eHRPD";
    806             case NETWORK_TYPE_IDEN:
    807                 return "iDEN";
    808             case NETWORK_TYPE_HSPAP:
    809                 return "HSPA+";
    810             default:
    811                 return "UNKNOWN";
    812         }
    813     }
    814 
    815     //
    816     //
    817     // SIM Card
    818     //
    819     //
    820 
    821     /** SIM card state: Unknown. Signifies that the SIM is in transition
    822      *  between states. For example, when the user inputs the SIM pin
    823      *  under PIN_REQUIRED state, a query for sim status returns
    824      *  this state before turning to SIM_STATE_READY. */
    825     public static final int SIM_STATE_UNKNOWN = 0;
    826     /** SIM card state: no SIM card is available in the device */
    827     public static final int SIM_STATE_ABSENT = 1;
    828     /** SIM card state: Locked: requires the user's SIM PIN to unlock */
    829     public static final int SIM_STATE_PIN_REQUIRED = 2;
    830     /** SIM card state: Locked: requires the user's SIM PUK to unlock */
    831     public static final int SIM_STATE_PUK_REQUIRED = 3;
    832     /** SIM card state: Locked: requries a network PIN to unlock */
    833     public static final int SIM_STATE_NETWORK_LOCKED = 4;
    834     /** SIM card state: Ready */
    835     public static final int SIM_STATE_READY = 5;
    836 
    837     /**
    838      * @return true if a ICC card is present
    839      */
    840     public boolean hasIccCard() {
    841         try {
    842             return getITelephony().hasIccCard();
    843         } catch (RemoteException ex) {
    844             // Assume no ICC card if remote exception which shouldn't happen
    845             return false;
    846         } catch (NullPointerException ex) {
    847             // This could happen before phone restarts due to crashing
    848             return false;
    849         }
    850     }
    851 
    852     /**
    853      * Returns a constant indicating the state of the
    854      * device SIM card.
    855      *
    856      * @see #SIM_STATE_UNKNOWN
    857      * @see #SIM_STATE_ABSENT
    858      * @see #SIM_STATE_PIN_REQUIRED
    859      * @see #SIM_STATE_PUK_REQUIRED
    860      * @see #SIM_STATE_NETWORK_LOCKED
    861      * @see #SIM_STATE_READY
    862      */
    863     public int getSimState() {
    864         String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
    865         if ("ABSENT".equals(prop)) {
    866             return SIM_STATE_ABSENT;
    867         }
    868         else if ("PIN_REQUIRED".equals(prop)) {
    869             return SIM_STATE_PIN_REQUIRED;
    870         }
    871         else if ("PUK_REQUIRED".equals(prop)) {
    872             return SIM_STATE_PUK_REQUIRED;
    873         }
    874         else if ("NETWORK_LOCKED".equals(prop)) {
    875             return SIM_STATE_NETWORK_LOCKED;
    876         }
    877         else if ("READY".equals(prop)) {
    878             return SIM_STATE_READY;
    879         }
    880         else {
    881             return SIM_STATE_UNKNOWN;
    882         }
    883     }
    884 
    885     /**
    886      * Returns the MCC+MNC (mobile country code + mobile network code) of the
    887      * provider of the SIM. 5 or 6 decimal digits.
    888      * <p>
    889      * Availability: SIM state must be {@link #SIM_STATE_READY}
    890      *
    891      * @see #getSimState
    892      */
    893     public String getSimOperator() {
    894         return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
    895     }
    896 
    897     /**
    898      * Returns the Service Provider Name (SPN).
    899      * <p>
    900      * Availability: SIM state must be {@link #SIM_STATE_READY}
    901      *
    902      * @see #getSimState
    903      */
    904     public String getSimOperatorName() {
    905         return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
    906     }
    907 
    908     /**
    909      * Returns the ISO country code equivalent for the SIM provider's country code.
    910      */
    911     public String getSimCountryIso() {
    912         return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY);
    913     }
    914 
    915     /**
    916      * Returns the serial number of the SIM, if applicable. Return null if it is
    917      * unavailable.
    918      * <p>
    919      * Requires Permission:
    920      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
    921      */
    922     public String getSimSerialNumber() {
    923         try {
    924             return getSubscriberInfo().getIccSerialNumber();
    925         } catch (RemoteException ex) {
    926             return null;
    927         } catch (NullPointerException ex) {
    928             // This could happen before phone restarts due to crashing
    929             return null;
    930         }
    931     }
    932 
    933     /**
    934      * Return if the current radio is LTE on CDMA. This
    935      * is a tri-state return value as for a period of time
    936      * the mode may be unknown.
    937      *
    938      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
    939      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
    940      *
    941      * @hide
    942      */
    943     public int getLteOnCdmaMode() {
    944         try {
    945             return getITelephony().getLteOnCdmaMode();
    946         } catch (RemoteException ex) {
    947             // Assume no ICC card if remote exception which shouldn't happen
    948             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
    949         } catch (NullPointerException ex) {
    950             // This could happen before phone restarts due to crashing
    951             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
    952         }
    953     }
    954 
    955     //
    956     //
    957     // Subscriber Info
    958     //
    959     //
    960 
    961     /**
    962      * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
    963      * Return null if it is unavailable.
    964      * <p>
    965      * Requires Permission:
    966      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
    967      */
    968     public String getSubscriberId() {
    969         try {
    970             return getSubscriberInfo().getSubscriberId();
    971         } catch (RemoteException ex) {
    972             return null;
    973         } catch (NullPointerException ex) {
    974             // This could happen before phone restarts due to crashing
    975             return null;
    976         }
    977     }
    978 
    979     /**
    980      * Returns the Group Identifier Level1 for a GSM phone.
    981      * Return null if it is unavailable.
    982      * <p>
    983      * Requires Permission:
    984      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
    985      */
    986     public String getGroupIdLevel1() {
    987         try {
    988             return getSubscriberInfo().getGroupIdLevel1();
    989         } catch (RemoteException ex) {
    990             return null;
    991         } catch (NullPointerException ex) {
    992             // This could happen before phone restarts due to crashing
    993             return null;
    994         }
    995     }
    996 
    997     /**
    998      * Returns the phone number string for line 1, for example, the MSISDN
    999      * for a GSM phone. Return null if it is unavailable.
   1000      * <p>
   1001      * Requires Permission:
   1002      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1003      */
   1004     public String getLine1Number() {
   1005         try {
   1006             return getSubscriberInfo().getLine1Number();
   1007         } catch (RemoteException ex) {
   1008             return null;
   1009         } catch (NullPointerException ex) {
   1010             // This could happen before phone restarts due to crashing
   1011             return null;
   1012         }
   1013     }
   1014 
   1015     /**
   1016      * Returns the alphabetic identifier associated with the line 1 number.
   1017      * Return null if it is unavailable.
   1018      * <p>
   1019      * Requires Permission:
   1020      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1021      * @hide
   1022      * nobody seems to call this.
   1023      */
   1024     public String getLine1AlphaTag() {
   1025         try {
   1026             return getSubscriberInfo().getLine1AlphaTag();
   1027         } catch (RemoteException ex) {
   1028             return null;
   1029         } catch (NullPointerException ex) {
   1030             // This could happen before phone restarts due to crashing
   1031             return null;
   1032         }
   1033     }
   1034 
   1035     /**
   1036      * Returns the MSISDN string.
   1037      * for a GSM phone. Return null if it is unavailable.
   1038      * <p>
   1039      * Requires Permission:
   1040      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1041      *
   1042      * @hide
   1043      */
   1044     public String getMsisdn() {
   1045         try {
   1046             return getSubscriberInfo().getMsisdn();
   1047         } catch (RemoteException ex) {
   1048             return null;
   1049         } catch (NullPointerException ex) {
   1050             // This could happen before phone restarts due to crashing
   1051             return null;
   1052         }
   1053     }
   1054 
   1055     /**
   1056      * Returns the voice mail number. Return null if it is unavailable.
   1057      * <p>
   1058      * Requires Permission:
   1059      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1060      */
   1061     public String getVoiceMailNumber() {
   1062         try {
   1063             return getSubscriberInfo().getVoiceMailNumber();
   1064         } catch (RemoteException ex) {
   1065             return null;
   1066         } catch (NullPointerException ex) {
   1067             // This could happen before phone restarts due to crashing
   1068             return null;
   1069         }
   1070     }
   1071 
   1072     /**
   1073      * Returns the complete voice mail number. Return null if it is unavailable.
   1074      * <p>
   1075      * Requires Permission:
   1076      *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
   1077      *
   1078      * @hide
   1079      */
   1080     public String getCompleteVoiceMailNumber() {
   1081         try {
   1082             return getSubscriberInfo().getCompleteVoiceMailNumber();
   1083         } catch (RemoteException ex) {
   1084             return null;
   1085         } catch (NullPointerException ex) {
   1086             // This could happen before phone restarts due to crashing
   1087             return null;
   1088         }
   1089     }
   1090 
   1091     /**
   1092      * Returns the voice mail count. Return 0 if unavailable.
   1093      * <p>
   1094      * Requires Permission:
   1095      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1096      * @hide
   1097      */
   1098     public int getVoiceMessageCount() {
   1099         try {
   1100             return getITelephony().getVoiceMessageCount();
   1101         } catch (RemoteException ex) {
   1102             return 0;
   1103         } catch (NullPointerException ex) {
   1104             // This could happen before phone restarts due to crashing
   1105             return 0;
   1106         }
   1107     }
   1108 
   1109     /**
   1110      * Retrieves the alphabetic identifier associated with the voice
   1111      * mail number.
   1112      * <p>
   1113      * Requires Permission:
   1114      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
   1115      */
   1116     public String getVoiceMailAlphaTag() {
   1117         try {
   1118             return getSubscriberInfo().getVoiceMailAlphaTag();
   1119         } catch (RemoteException ex) {
   1120             return null;
   1121         } catch (NullPointerException ex) {
   1122             // This could happen before phone restarts due to crashing
   1123             return null;
   1124         }
   1125     }
   1126 
   1127     /**
   1128      * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
   1129      * @return the IMPI, or null if not present or not loaded
   1130      * @hide
   1131      */
   1132     public String getIsimImpi() {
   1133         try {
   1134             return getSubscriberInfo().getIsimImpi();
   1135         } catch (RemoteException ex) {
   1136             return null;
   1137         } catch (NullPointerException ex) {
   1138             // This could happen before phone restarts due to crashing
   1139             return null;
   1140         }
   1141     }
   1142 
   1143     /**
   1144      * Returns the IMS home network domain name that was loaded from the ISIM.
   1145      * @return the IMS domain name, or null if not present or not loaded
   1146      * @hide
   1147      */
   1148     public String getIsimDomain() {
   1149         try {
   1150             return getSubscriberInfo().getIsimDomain();
   1151         } catch (RemoteException ex) {
   1152             return null;
   1153         } catch (NullPointerException ex) {
   1154             // This could happen before phone restarts due to crashing
   1155             return null;
   1156         }
   1157     }
   1158 
   1159     /**
   1160      * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
   1161      * @return an array of IMPU strings, with one IMPU per string, or null if
   1162      *      not present or not loaded
   1163      * @hide
   1164      */
   1165     public String[] getIsimImpu() {
   1166         try {
   1167             return getSubscriberInfo().getIsimImpu();
   1168         } catch (RemoteException ex) {
   1169             return null;
   1170         } catch (NullPointerException ex) {
   1171             // This could happen before phone restarts due to crashing
   1172             return null;
   1173         }
   1174     }
   1175 
   1176     private IPhoneSubInfo getSubscriberInfo() {
   1177         // get it each time because that process crashes a lot
   1178         return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
   1179     }
   1180 
   1181 
   1182     /** Device call state: No activity. */
   1183     public static final int CALL_STATE_IDLE = 0;
   1184     /** Device call state: Ringing. A new call arrived and is
   1185      *  ringing or waiting. In the latter case, another call is
   1186      *  already active. */
   1187     public static final int CALL_STATE_RINGING = 1;
   1188     /** Device call state: Off-hook. At least one call exists
   1189       * that is dialing, active, or on hold, and no calls are ringing
   1190       * or waiting. */
   1191     public static final int CALL_STATE_OFFHOOK = 2;
   1192 
   1193     /**
   1194      * Returns a constant indicating the call state (cellular) on the device.
   1195      */
   1196     public int getCallState() {
   1197         try {
   1198             return getITelephony().getCallState();
   1199         } catch (RemoteException ex) {
   1200             // the phone process is restarting.
   1201             return CALL_STATE_IDLE;
   1202         } catch (NullPointerException ex) {
   1203           // the phone process is restarting.
   1204           return CALL_STATE_IDLE;
   1205       }
   1206     }
   1207 
   1208     /** Data connection activity: No traffic. */
   1209     public static final int DATA_ACTIVITY_NONE = 0x00000000;
   1210     /** Data connection activity: Currently receiving IP PPP traffic. */
   1211     public static final int DATA_ACTIVITY_IN = 0x00000001;
   1212     /** Data connection activity: Currently sending IP PPP traffic. */
   1213     public static final int DATA_ACTIVITY_OUT = 0x00000002;
   1214     /** Data connection activity: Currently both sending and receiving
   1215      *  IP PPP traffic. */
   1216     public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
   1217     /**
   1218      * Data connection is active, but physical link is down
   1219      */
   1220     public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
   1221 
   1222     /**
   1223      * Returns a constant indicating the type of activity on a data connection
   1224      * (cellular).
   1225      *
   1226      * @see #DATA_ACTIVITY_NONE
   1227      * @see #DATA_ACTIVITY_IN
   1228      * @see #DATA_ACTIVITY_OUT
   1229      * @see #DATA_ACTIVITY_INOUT
   1230      * @see #DATA_ACTIVITY_DORMANT
   1231      */
   1232     public int getDataActivity() {
   1233         try {
   1234             return getITelephony().getDataActivity();
   1235         } catch (RemoteException ex) {
   1236             // the phone process is restarting.
   1237             return DATA_ACTIVITY_NONE;
   1238         } catch (NullPointerException ex) {
   1239           // the phone process is restarting.
   1240           return DATA_ACTIVITY_NONE;
   1241       }
   1242     }
   1243 
   1244     /** Data connection state: Unknown.  Used before we know the state.
   1245      * @hide
   1246      */
   1247     public static final int DATA_UNKNOWN        = -1;
   1248     /** Data connection state: Disconnected. IP traffic not available. */
   1249     public static final int DATA_DISCONNECTED   = 0;
   1250     /** Data connection state: Currently setting up a data connection. */
   1251     public static final int DATA_CONNECTING     = 1;
   1252     /** Data connection state: Connected. IP traffic should be available. */
   1253     public static final int DATA_CONNECTED      = 2;
   1254     /** Data connection state: Suspended. The connection is up, but IP
   1255      * traffic is temporarily unavailable. For example, in a 2G network,
   1256      * data activity may be suspended when a voice call arrives. */
   1257     public static final int DATA_SUSPENDED      = 3;
   1258 
   1259     /**
   1260      * Returns a constant indicating the current data connection state
   1261      * (cellular).
   1262      *
   1263      * @see #DATA_DISCONNECTED
   1264      * @see #DATA_CONNECTING
   1265      * @see #DATA_CONNECTED
   1266      * @see #DATA_SUSPENDED
   1267      */
   1268     public int getDataState() {
   1269         try {
   1270             return getITelephony().getDataState();
   1271         } catch (RemoteException ex) {
   1272             // the phone process is restarting.
   1273             return DATA_DISCONNECTED;
   1274         } catch (NullPointerException ex) {
   1275             return DATA_DISCONNECTED;
   1276         }
   1277     }
   1278 
   1279     private ITelephony getITelephony() {
   1280         return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
   1281     }
   1282 
   1283     //
   1284     //
   1285     // PhoneStateListener
   1286     //
   1287     //
   1288 
   1289     /**
   1290      * Registers a listener object to receive notification of changes
   1291      * in specified telephony states.
   1292      * <p>
   1293      * To register a listener, pass a {@link PhoneStateListener}
   1294      * and specify at least one telephony state of interest in
   1295      * the events argument.
   1296      *
   1297      * At registration, and when a specified telephony state
   1298      * changes, the telephony manager invokes the appropriate
   1299      * callback method on the listener object and passes the
   1300      * current (udpated) values.
   1301      * <p>
   1302      * To unregister a listener, pass the listener object and set the
   1303      * events argument to
   1304      * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
   1305      *
   1306      * @param listener The {@link PhoneStateListener} object to register
   1307      *                 (or unregister)
   1308      * @param events The telephony state(s) of interest to the listener,
   1309      *               as a bitwise-OR combination of {@link PhoneStateListener}
   1310      *               LISTEN_ flags.
   1311      */
   1312     public void listen(PhoneStateListener listener, int events) {
   1313         String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
   1314         try {
   1315             Boolean notifyNow = true;
   1316             sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
   1317         } catch (RemoteException ex) {
   1318             // system process dead
   1319         } catch (NullPointerException ex) {
   1320             // system process dead
   1321         }
   1322     }
   1323 
   1324     /**
   1325      * Returns the CDMA ERI icon index to display
   1326      *
   1327      * @hide
   1328      */
   1329     public int getCdmaEriIconIndex() {
   1330         try {
   1331             return getITelephony().getCdmaEriIconIndex();
   1332         } catch (RemoteException ex) {
   1333             // the phone process is restarting.
   1334             return -1;
   1335         } catch (NullPointerException ex) {
   1336             return -1;
   1337         }
   1338     }
   1339 
   1340     /**
   1341      * Returns the CDMA ERI icon mode,
   1342      * 0 - ON
   1343      * 1 - FLASHING
   1344      *
   1345      * @hide
   1346      */
   1347     public int getCdmaEriIconMode() {
   1348         try {
   1349             return getITelephony().getCdmaEriIconMode();
   1350         } catch (RemoteException ex) {
   1351             // the phone process is restarting.
   1352             return -1;
   1353         } catch (NullPointerException ex) {
   1354             return -1;
   1355         }
   1356     }
   1357 
   1358     /**
   1359      * Returns the CDMA ERI text,
   1360      *
   1361      * @hide
   1362      */
   1363     public String getCdmaEriText() {
   1364         try {
   1365             return getITelephony().getCdmaEriText();
   1366         } catch (RemoteException ex) {
   1367             // the phone process is restarting.
   1368             return null;
   1369         } catch (NullPointerException ex) {
   1370             return null;
   1371         }
   1372     }
   1373 
   1374     /**
   1375      * @return true if the current device is "voice capable".
   1376      * <p>
   1377      * "Voice capable" means that this device supports circuit-switched
   1378      * (i.e. voice) phone calls over the telephony network, and is allowed
   1379      * to display the in-call UI while a cellular voice call is active.
   1380      * This will be false on "data only" devices which can't make voice
   1381      * calls and don't support any in-call UI.
   1382      * <p>
   1383      * Note: the meaning of this flag is subtly different from the
   1384      * PackageManager.FEATURE_TELEPHONY system feature, which is available
   1385      * on any device with a telephony radio, even if the device is
   1386      * data-only.
   1387      *
   1388      * @hide pending API review
   1389      */
   1390     public boolean isVoiceCapable() {
   1391         if (mContext == null) return true;
   1392         return mContext.getResources().getBoolean(
   1393                 com.android.internal.R.bool.config_voice_capable);
   1394     }
   1395 
   1396     /**
   1397      * @return true if the current device supports sms service.
   1398      * <p>
   1399      * If true, this means that the device supports both sending and
   1400      * receiving sms via the telephony network.
   1401      * <p>
   1402      * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
   1403      *       disabled when device doesn't support sms.
   1404      *
   1405      * @hide pending API review
   1406      */
   1407     public boolean isSmsCapable() {
   1408         if (mContext == null) return true;
   1409         return mContext.getResources().getBoolean(
   1410                 com.android.internal.R.bool.config_sms_capable);
   1411     }
   1412 
   1413     /**
   1414      * Returns all observed cell information from all radios on the
   1415      * device including the primary and neighboring cells. This does
   1416      * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
   1417      *<p>
   1418      * The list can include one or more of {@link android.telephony.CellInfoGsm CellInfoGsm},
   1419      * {@link android.telephony.CellInfoCdma CellInfoCdma},
   1420      * {@link android.telephony.CellInfoLte CellInfoLte} and
   1421      * {@link android.telephony.CellInfoWcdma CellInfoCdma} in any combination.
   1422      * Specifically on devices with multiple radios it is typical to see instances of
   1423      * one or more of any these in the list. In addition 0, 1 or more CellInfo
   1424      * objects may return isRegistered() true.
   1425      *<p>
   1426      * This is preferred over using getCellLocation although for older
   1427      * devices this may return null in which case getCellLocation should
   1428      * be called.
   1429      *<p>
   1430      * @return List of CellInfo or null if info unavailable.
   1431      *
   1432      * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
   1433      */
   1434     public List<CellInfo> getAllCellInfo() {
   1435         try {
   1436             return getITelephony().getAllCellInfo();
   1437         } catch (RemoteException ex) {
   1438             return null;
   1439         } catch (NullPointerException ex) {
   1440             return null;
   1441         }
   1442     }
   1443 
   1444     /**
   1445      * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
   1446      * PhoneStateListener.onCellInfoChanged} will be invoked.
   1447      *<p>
   1448      * The default, 0, means invoke onCellInfoChanged when any of the reported
   1449      * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
   1450      * A onCellInfoChanged.
   1451      *<p>
   1452      * @param rateInMillis the rate
   1453      *
   1454      * @hide
   1455      */
   1456     public void setCellInfoListRate(int rateInMillis) {
   1457         try {
   1458             getITelephony().setCellInfoListRate(rateInMillis);
   1459         } catch (RemoteException ex) {
   1460         } catch (NullPointerException ex) {
   1461         }
   1462     }
   1463 
   1464     /**
   1465      * Returns the MMS user agent.
   1466      */
   1467     public String getMmsUserAgent() {
   1468         if (mContext == null) return null;
   1469         return mContext.getResources().getString(
   1470                 com.android.internal.R.string.config_mms_user_agent);
   1471     }
   1472 
   1473     /**
   1474      * Returns the MMS user agent profile URL.
   1475      */
   1476     public String getMmsUAProfUrl() {
   1477         if (mContext == null) return null;
   1478         return mContext.getResources().getString(
   1479                 com.android.internal.R.string.config_mms_user_agent_profile_url);
   1480     }
   1481 
   1482     /** @hide */
   1483     @PrivateApi
   1484     public void dial(String number) {
   1485         try {
   1486             getITelephony().dial(number);
   1487         } catch (RemoteException e) {
   1488             Log.e(TAG, "Error calling ITelephony#dial", e);
   1489         }
   1490     }
   1491 
   1492     /** @hide */
   1493     @PrivateApi
   1494     public void call(String callingPackage, String number) {
   1495         try {
   1496             getITelephony().call(callingPackage, number);
   1497         } catch (RemoteException e) {
   1498             Log.e(TAG, "Error calling ITelephony#call", e);
   1499         }
   1500     }
   1501 
   1502     /** @hide */
   1503     @PrivateApi
   1504     public boolean showCallScreen() {
   1505         try {
   1506             return getITelephony().showCallScreen();
   1507         } catch (RemoteException e) {
   1508             Log.e(TAG, "Error calling ITelephony#showCallScreen", e);
   1509         }
   1510         return false;
   1511     }
   1512 
   1513     /** @hide */
   1514     @PrivateApi
   1515     public boolean showCallScreenWithDialpad(boolean showDialpad) {
   1516         try {
   1517             return getITelephony().showCallScreenWithDialpad(showDialpad);
   1518         } catch (RemoteException e) {
   1519             Log.e(TAG, "Error calling ITelephony#showCallScreenWithDialpad", e);
   1520         }
   1521         return false;
   1522     }
   1523 
   1524     /** @hide */
   1525     @PrivateApi
   1526     public boolean endCall() {
   1527         try {
   1528             return getITelephony().endCall();
   1529         } catch (RemoteException e) {
   1530             Log.e(TAG, "Error calling ITelephony#endCall", e);
   1531         }
   1532         return false;
   1533     }
   1534 
   1535     /** @hide */
   1536     @PrivateApi
   1537     public void answerRingingCall() {
   1538         try {
   1539             getITelephony().answerRingingCall();
   1540         } catch (RemoteException e) {
   1541             Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
   1542         }
   1543     }
   1544 
   1545     /** @hide */
   1546     @PrivateApi
   1547     public void toggleHold() {
   1548         try {
   1549             getITelephony().toggleHold();
   1550         } catch (RemoteException e) {
   1551             Log.e(TAG, "Error calling ITelephony#toggleHold", e);
   1552         }
   1553     }
   1554 
   1555     /** @hide */
   1556     @PrivateApi
   1557     public void merge() {
   1558         try {
   1559             getITelephony().merge();
   1560         } catch (RemoteException e) {
   1561             Log.e(TAG, "Error calling ITelephony#merge", e);
   1562         }
   1563     }
   1564 
   1565     /** @hide */
   1566     @PrivateApi
   1567     public void swap() {
   1568         try {
   1569             getITelephony().swap();
   1570         } catch (RemoteException e) {
   1571             Log.e(TAG, "Error calling ITelephony#swap", e);
   1572         }
   1573     }
   1574 
   1575     /** @hide */
   1576     @PrivateApi
   1577     public void mute(boolean mute) {
   1578         try {
   1579             getITelephony().mute(mute);
   1580         } catch (RemoteException e) {
   1581             Log.e(TAG, "Error calling ITelephony#mute", e);
   1582         }
   1583     }
   1584 
   1585     /** @hide */
   1586     @PrivateApi
   1587     public void silenceRinger() {
   1588         try {
   1589             getITelephony().silenceRinger();
   1590         } catch (RemoteException e) {
   1591             Log.e(TAG, "Error calling ITelephony#silenceRinger", e);
   1592         }
   1593     }
   1594 
   1595     /** @hide */
   1596     @PrivateApi
   1597     public boolean isOffhook() {
   1598         try {
   1599             return getITelephony().isOffhook();
   1600         } catch (RemoteException e) {
   1601             Log.e(TAG, "Error calling ITelephony#isOffhook", e);
   1602         }
   1603         return false;
   1604     }
   1605 
   1606     /** @hide */
   1607     @PrivateApi
   1608     public boolean isRinging() {
   1609         try {
   1610             return getITelephony().isRinging();
   1611         } catch (RemoteException e) {
   1612             Log.e(TAG, "Error calling ITelephony#isRinging", e);
   1613         }
   1614         return false;
   1615     }
   1616 
   1617     /** @hide */
   1618     @PrivateApi
   1619     public boolean isIdle() {
   1620         try {
   1621             return getITelephony().isIdle();
   1622         } catch (RemoteException e) {
   1623             Log.e(TAG, "Error calling ITelephony#isIdle", e);
   1624         }
   1625         return true;
   1626     }
   1627 
   1628     /** @hide */
   1629     @PrivateApi
   1630     public boolean isRadioOn() {
   1631         try {
   1632             return getITelephony().isRadioOn();
   1633         } catch (RemoteException e) {
   1634             Log.e(TAG, "Error calling ITelephony#isRadioOn", e);
   1635         }
   1636         return false;
   1637     }
   1638 
   1639     /** @hide */
   1640     @PrivateApi
   1641     public boolean isSimPinEnabled() {
   1642         try {
   1643             return getITelephony().isSimPinEnabled();
   1644         } catch (RemoteException e) {
   1645             Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
   1646         }
   1647         return false;
   1648     }
   1649 
   1650     /** @hide */
   1651     @PrivateApi
   1652     public void cancelMissedCallsNotification() {
   1653         try {
   1654             getITelephony().cancelMissedCallsNotification();
   1655         } catch (RemoteException e) {
   1656             Log.e(TAG, "Error calling ITelephony#cancelMissedCallsNotification", e);
   1657         }
   1658     }
   1659 
   1660     /** @hide */
   1661     @PrivateApi
   1662     public boolean supplyPin(String pin) {
   1663         try {
   1664             return getITelephony().supplyPin(pin);
   1665         } catch (RemoteException e) {
   1666             Log.e(TAG, "Error calling ITelephony#supplyPin", e);
   1667         }
   1668         return false;
   1669     }
   1670 
   1671     /** @hide */
   1672     @PrivateApi
   1673     public boolean supplyPuk(String puk, String pin) {
   1674         try {
   1675             return getITelephony().supplyPuk(puk, pin);
   1676         } catch (RemoteException e) {
   1677             Log.e(TAG, "Error calling ITelephony#supplyPuk", e);
   1678         }
   1679         return false;
   1680     }
   1681 
   1682     /** @hide */
   1683     @PrivateApi
   1684     public int[] supplyPinReportResult(String pin) {
   1685         try {
   1686             return getITelephony().supplyPinReportResult(pin);
   1687         } catch (RemoteException e) {
   1688             Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e);
   1689         }
   1690         return new int[0];
   1691     }
   1692 
   1693     /** @hide */
   1694     @PrivateApi
   1695     public int[] supplyPukReportResult(String puk, String pin) {
   1696         try {
   1697             return getITelephony().supplyPukReportResult(puk, pin);
   1698         } catch (RemoteException e) {
   1699             Log.e(TAG, "Error calling ITelephony#]", e);
   1700         }
   1701         return new int[0];
   1702     }
   1703 
   1704     /** @hide */
   1705     @PrivateApi
   1706     public boolean handlePinMmi(String dialString) {
   1707         try {
   1708             return getITelephony().handlePinMmi(dialString);
   1709         } catch (RemoteException e) {
   1710             Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
   1711         }
   1712         return false;
   1713     }
   1714 
   1715     /** @hide */
   1716     @PrivateApi
   1717     public void toggleRadioOnOff() {
   1718         try {
   1719             getITelephony().toggleRadioOnOff();
   1720         } catch (RemoteException e) {
   1721             Log.e(TAG, "Error calling ITelephony#toggleRadioOnOff", e);
   1722         }
   1723     }
   1724 
   1725     /** @hide */
   1726     @PrivateApi
   1727     public boolean setRadio(boolean turnOn) {
   1728         try {
   1729             return getITelephony().setRadio(turnOn);
   1730         } catch (RemoteException e) {
   1731             Log.e(TAG, "Error calling ITelephony#setRadio", e);
   1732         }
   1733         return false;
   1734     }
   1735 
   1736     /** @hide */
   1737     @PrivateApi
   1738     public boolean setRadioPower(boolean turnOn) {
   1739         try {
   1740             return getITelephony().setRadioPower(turnOn);
   1741         } catch (RemoteException e) {
   1742             Log.e(TAG, "Error calling ITelephony#setRadioPower", e);
   1743         }
   1744         return false;
   1745     }
   1746 
   1747     /** @hide */
   1748     @PrivateApi
   1749     public void updateServiceLocation() {
   1750         try {
   1751             getITelephony().updateServiceLocation();
   1752         } catch (RemoteException e) {
   1753             Log.e(TAG, "Error calling ITelephony#updateServiceLocation", e);
   1754         }
   1755     }
   1756 
   1757     /** @hide */
   1758     @PrivateApi
   1759     public int enableApnType(String type) {
   1760         try {
   1761             return getITelephony().enableApnType(type);
   1762         } catch (RemoteException e) {
   1763             Log.e(TAG, "Error calling ITelephony#enableApnType", e);
   1764         }
   1765         return PhoneConstants.APN_REQUEST_FAILED;
   1766     }
   1767 
   1768     /** @hide */
   1769     @PrivateApi
   1770     public int disableApnType(String type) {
   1771         try {
   1772             return getITelephony().disableApnType(type);
   1773         } catch (RemoteException e) {
   1774             Log.e(TAG, "Error calling ITelephony#disableApnType", e);
   1775         }
   1776         return PhoneConstants.APN_REQUEST_FAILED;
   1777     }
   1778 
   1779     /** @hide */
   1780     @PrivateApi
   1781     public boolean enableDataConnectivity() {
   1782         try {
   1783             return getITelephony().enableDataConnectivity();
   1784         } catch (RemoteException e) {
   1785             Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
   1786         }
   1787         return false;
   1788     }
   1789 
   1790     /** @hide */
   1791     @PrivateApi
   1792     public boolean disableDataConnectivity() {
   1793         try {
   1794             return getITelephony().disableDataConnectivity();
   1795         } catch (RemoteException e) {
   1796             Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
   1797         }
   1798         return false;
   1799     }
   1800 
   1801     /** @hide */
   1802     @PrivateApi
   1803     public boolean isDataConnectivityPossible() {
   1804         try {
   1805             return getITelephony().isDataConnectivityPossible();
   1806         } catch (RemoteException e) {
   1807             Log.e(TAG, "Error calling ITelephony#isDataConnectivityPossible", e);
   1808         }
   1809         return false;
   1810     }
   1811 
   1812     /** @hide */
   1813     @PrivateApi
   1814     public boolean needsOtaServiceProvisioning() {
   1815         try {
   1816             return getITelephony().needsOtaServiceProvisioning();
   1817         } catch (RemoteException e) {
   1818             Log.e(TAG, "Error calling ITelephony#needsOtaServiceProvisioning", e);
   1819         }
   1820         return false;
   1821     }
   1822 
   1823     /** @hide */
   1824     @PrivateApi
   1825     public void playDtmfTone(char digit, boolean timedShortCode) {
   1826         try {
   1827             getITelephony().playDtmfTone(digit, timedShortCode);
   1828         } catch (RemoteException e) {
   1829             Log.e(TAG, "Error calling ITelephony#playDtmfTone", e);
   1830         }
   1831     }
   1832 
   1833     /** @hide */
   1834     @PrivateApi
   1835     public void stopDtmfTone() {
   1836         try {
   1837             getITelephony().stopDtmfTone();
   1838         } catch (RemoteException e) {
   1839             Log.e(TAG, "Error calling ITelephony#stopDtmfTone", e);
   1840         }
   1841     }
   1842 
   1843     /** @hide */
   1844     @PrivateApi
   1845     public void addCallStateListener(CallStateListener listener) {
   1846         try {
   1847             if (listener == null) {
   1848                 throw new RuntimeException("Listener can't be null");
   1849             }
   1850             if (!mListeners.containsKey(listener)) {
   1851                 final Listener l = new Listener(listener);
   1852                 mListeners.put(listener, l);
   1853                 getITelephony().addListener(l);
   1854             }
   1855         } catch (RemoteException e) {
   1856             Log.e(TAG, "Error calling ITelephony#addListener", e);
   1857         }
   1858     }
   1859 
   1860     /** @hide */
   1861     @PrivateApi
   1862     public void removeCallStateListener(CallStateListener listener) {
   1863         try {
   1864             final Listener l = mListeners.remove(listener);
   1865             if (l != null) {
   1866                 // Make sure that no callbacks that are already in flight come.
   1867                 l.clearQueue();
   1868                 getITelephony().removeListener(l);
   1869             }
   1870         } catch (RemoteException e) {
   1871             Log.e(TAG, "Error calling ITelephony#removeListener", e);
   1872         }
   1873     }
   1874 }
   1875