Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2016 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.facade.telephony;
     18 
     19 import android.app.Activity;
     20 import android.app.Service;
     21 import android.content.ContentResolver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.database.Cursor;
     25 import android.net.Uri;
     26 import android.os.RemoteException;
     27 import android.provider.ContactsContract;
     28 import android.telephony.CellInfo;
     29 import android.telephony.CellLocation;
     30 import android.telephony.ModemActivityInfo;
     31 import android.telephony.NeighboringCellInfo;
     32 import android.telephony.PhoneStateListener;
     33 import android.telephony.SignalStrength;
     34 import android.telephony.SubscriptionManager;
     35 import android.telephony.TelephonyManager;
     36 import android.provider.Telephony;
     37 import android.telephony.SubscriptionInfo;
     38 import android.telecom.VideoProfile;
     39 import android.telecom.TelecomManager;
     40 import android.util.Base64;
     41 
     42 import com.android.internal.telephony.PhoneConstants;
     43 import com.android.internal.telephony.RILConstants;
     44 import com.android.internal.telephony.TelephonyProperties;
     45 import com.google.common.io.BaseEncoding;
     46 
     47 import android.content.ContentValues;
     48 import android.os.SystemProperties;
     49 
     50 import com.googlecode.android_scripting.facade.AndroidFacade;
     51 import com.googlecode.android_scripting.facade.EventFacade;
     52 import com.googlecode.android_scripting.facade.FacadeManager;
     53 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     54                                                    .CallStateChangeListener;
     55 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     56                                                    .CellInfoChangeListener;
     57 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     58                                                    .DataConnectionRealTimeInfoChangeListener;
     59 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     60                                                    .DataConnectionStateChangeListener;
     61 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     62                                                    .ServiceStateChangeListener;
     63 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     64                                                    .SignalStrengthChangeListener;
     65 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
     66                                                    .VoiceMailStateChangeListener;
     67 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
     68 import com.googlecode.android_scripting.rpc.Rpc;
     69 import com.googlecode.android_scripting.rpc.RpcDefault;
     70 import com.googlecode.android_scripting.rpc.RpcParameter;
     71 import com.googlecode.android_scripting.Log;
     72 import com.googlecode.android_scripting.MainThread;
     73 import com.googlecode.android_scripting.rpc.RpcOptional;
     74 
     75 import java.io.UnsupportedEncodingException;
     76 import java.lang.reflect.Field;
     77 import java.net.URLEncoder;
     78 import java.util.List;
     79 import java.util.concurrent.Callable;
     80 import java.util.HashMap;
     81 
     82 /**
     83  * Exposes TelephonyManager functionality.
     84  *
     85  * @author Damon Kohler (damonkohler (at) gmail.com)
     86  * @author Felix Arends (felix.arends (at) gmail.com)
     87  */
     88 public class TelephonyManagerFacade extends RpcReceiver {
     89 
     90     private final Service mService;
     91     private final AndroidFacade mAndroidFacade;
     92     private final EventFacade mEventFacade;
     93     private final TelephonyManager mTelephonyManager;
     94     private final SubscriptionManager mSubscriptionManager;
     95     private HashMap<Integer, StateChangeListener> mStateChangeListeners =
     96                              new HashMap<Integer, StateChangeListener>();
     97 
     98     private static final String[] sProjection = new String[] {
     99             Telephony.Carriers._ID, // 0
    100             Telephony.Carriers.NAME, // 1
    101             Telephony.Carriers.APN, // 2
    102             Telephony.Carriers.PROXY, // 3
    103             Telephony.Carriers.PORT, // 4
    104             Telephony.Carriers.USER, // 5
    105             Telephony.Carriers.SERVER, // 6
    106             Telephony.Carriers.PASSWORD, // 7
    107             Telephony.Carriers.MMSC, // 8
    108             Telephony.Carriers.MCC, // 9
    109             Telephony.Carriers.MNC, // 10
    110             Telephony.Carriers.NUMERIC, // 11
    111             Telephony.Carriers.MMSPROXY,// 12
    112             Telephony.Carriers.MMSPORT, // 13
    113             Telephony.Carriers.AUTH_TYPE, // 14
    114             Telephony.Carriers.TYPE, // 15
    115             Telephony.Carriers.PROTOCOL, // 16
    116             Telephony.Carriers.CARRIER_ENABLED, // 17
    117             Telephony.Carriers.BEARER_BITMASK, // 18
    118             Telephony.Carriers.ROAMING_PROTOCOL, // 19
    119             Telephony.Carriers.MVNO_TYPE, // 20
    120             Telephony.Carriers.MVNO_MATCH_DATA // 21
    121     };
    122 
    123     public TelephonyManagerFacade(FacadeManager manager) {
    124         super(manager);
    125         mService = manager.getService();
    126         mTelephonyManager =
    127                 (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE);
    128         mAndroidFacade = manager.getReceiver(AndroidFacade.class);
    129         mEventFacade = manager.getReceiver(EventFacade.class);
    130         mSubscriptionManager = SubscriptionManager.from(mService);
    131     }
    132 
    133     @Rpc(description = "Set network preference.")
    134     public boolean telephonySetPreferredNetworkTypes(
    135         @RpcParameter(name = "nwPreference") String nwPreference) {
    136         return telephonySetPreferredNetworkTypesForSubscription(nwPreference,
    137                 SubscriptionManager.getDefaultSubscriptionId());
    138     }
    139 
    140     @Rpc(description = "Set network preference for subscription.")
    141     public boolean telephonySetPreferredNetworkTypesForSubscription(
    142             @RpcParameter(name = "nwPreference") String nwPreference,
    143             @RpcParameter(name = "subId") Integer subId) {
    144         int networkPreferenceInt = TelephonyUtils.getNetworkModeIntfromString(
    145             nwPreference);
    146         if (RILConstants.RIL_ERRNO_INVALID_RESPONSE != networkPreferenceInt) {
    147             return mTelephonyManager.setPreferredNetworkType(
    148                 subId, networkPreferenceInt);
    149         } else {
    150             return false;
    151         }
    152     }
    153 
    154     @Rpc(description = "Get network preference.")
    155     public String telephonyGetPreferredNetworkTypes() {
    156         return telephonyGetPreferredNetworkTypesForSubscription(
    157                 SubscriptionManager.getDefaultSubscriptionId());
    158     }
    159 
    160     @Rpc(description = "Get network preference for subscription.")
    161     public String telephonyGetPreferredNetworkTypesForSubscription(
    162             @RpcParameter(name = "subId") Integer subId) {
    163         int networkPreferenceInt = mTelephonyManager.getPreferredNetworkType(subId);
    164         return TelephonyUtils.getNetworkModeStringfromInt(networkPreferenceInt);
    165     }
    166 
    167     @Rpc(description = "Get current voice network type")
    168     public String telephonyGetCurrentVoiceNetworkType() {
    169         return telephonyGetCurrentVoiceNetworkTypeForSubscription(
    170                 SubscriptionManager.getDefaultSubscriptionId());
    171     }
    172 
    173     @Rpc(description = "Get current voice network type for subscription")
    174     public String telephonyGetCurrentVoiceNetworkTypeForSubscription(
    175             @RpcParameter(name = "subId") Integer subId) {
    176         return TelephonyUtils.getNetworkTypeString(
    177             mTelephonyManager.getVoiceNetworkType(subId));
    178     }
    179 
    180     @Rpc(description = "Get current data network type")
    181     public String telephonyGetCurrentDataNetworkType() {
    182         return telephonyGetCurrentDataNetworkTypeForSubscription(
    183                 SubscriptionManager.getDefaultSubscriptionId());
    184     }
    185 
    186     @Rpc(description = "Get current data network type for subscription")
    187     public String telephonyGetCurrentDataNetworkTypeForSubscription(
    188             @RpcParameter(name = "subId") Integer subId) {
    189         return TelephonyUtils.getNetworkTypeString(
    190             mTelephonyManager.getDataNetworkType(subId));
    191     }
    192 
    193     @Rpc(description = "Get if phone have voice capability")
    194     public Boolean telephonyIsVoiceCapable() {
    195         return mTelephonyManager.isVoiceCapable();
    196     }
    197 
    198     @Rpc(description = "Get preferred network setting for " +
    199                        "default subscription ID .Return value is integer.")
    200     public int telephonyGetPreferredNetworkTypeInteger() {
    201         return telephonyGetPreferredNetworkTypeIntegerForSubscription(
    202                                          SubscriptionManager.getDefaultSubscriptionId());
    203     }
    204 
    205     @Rpc(description = "Get preferred network setting for " +
    206                        "specified subscription ID .Return value is integer.")
    207     public int telephonyGetPreferredNetworkTypeIntegerForSubscription(
    208                @RpcParameter(name = "subId") Integer subId) {
    209         return mTelephonyManager.getPreferredNetworkType(subId);
    210     }
    211 
    212     @Rpc(description = "Starts tracking call state change" +
    213                        "for default subscription ID.")
    214     public Boolean telephonyStartTrackingCallState() {
    215         return telephonyStartTrackingCallStateForSubscription(
    216                               SubscriptionManager.getDefaultVoiceSubscriptionId());
    217     }
    218 
    219     @Rpc(description = "Starts tracking call state change" +
    220                        "for specified subscription ID.")
    221     public Boolean telephonyStartTrackingCallStateForSubscription(
    222                 @RpcParameter(name = "subId") Integer subId) {
    223         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    224         if(listener == null) {
    225             Log.e("Invalid subscription ID");
    226             return false;
    227         }
    228         mTelephonyManager.listen(
    229             listener.mCallStateChangeListener,
    230             CallStateChangeListener.sListeningStates);
    231         return true;
    232     }
    233 
    234     @Rpc(description = "Starts tracking cell info change" +
    235                        "for default subscription ID.")
    236     public Boolean telephonyStartTrackingCellInfoChange() {
    237         return telephonyStartTrackingCellInfoChangeForSubscription(
    238                               SubscriptionManager.getDefaultVoiceSubscriptionId());
    239     }
    240 
    241     @Rpc(description = "Starts tracking cell info change" +
    242                        "for specified subscription ID.")
    243     public Boolean telephonyStartTrackingCellInfoChangeForSubscription(
    244                 @RpcParameter(name = "subId") Integer subId) {
    245         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    246         if(listener == null) {
    247             Log.e("Invalid subscription ID");
    248             return false;
    249         }
    250         mTelephonyManager.listen(
    251             listener.mCellInfoChangeListener,
    252             PhoneStateListener.LISTEN_CELL_INFO);
    253         return true;
    254     }
    255 
    256     @Rpc(description = "Turn on/off precise listening on fore/background or" +
    257                        " ringing calls for default voice subscription ID.")
    258     public Boolean telephonyAdjustPreciseCallStateListenLevel(
    259             @RpcParameter(name = "type") String type,
    260             @RpcParameter(name = "listen") Boolean listen) {
    261         return telephonyAdjustPreciseCallStateListenLevelForSubscription(type, listen,
    262                                  SubscriptionManager.getDefaultVoiceSubscriptionId());
    263     }
    264 
    265     @Rpc(description = "Turn on/off precise listening on fore/background or" +
    266                        " ringing calls for specified subscription ID.")
    267     public Boolean telephonyAdjustPreciseCallStateListenLevelForSubscription(
    268             @RpcParameter(name = "type") String type,
    269             @RpcParameter(name = "listen") Boolean listen,
    270             @RpcParameter(name = "subId") Integer subId) {
    271         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    272         if(listener == null) {
    273             Log.e("Invalid subscription ID");
    274             return false;
    275         }
    276 
    277         if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND)) {
    278             listener.mCallStateChangeListener.listenForeground = listen;
    279         } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING)) {
    280             listener.mCallStateChangeListener.listenRinging = listen;
    281         } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND)) {
    282             listener.mCallStateChangeListener.listenBackground = listen;
    283         } else {
    284             throw new IllegalArgumentException("Invalid listen level type " + type);
    285         }
    286 
    287         return true;
    288     }
    289 
    290     @Rpc(description = "Stops tracking cell info change " +
    291             "for default voice subscription ID.")
    292     public Boolean telephonyStopTrackingCellInfoChange() {
    293         return telephonyStopTrackingCellInfoChangeForSubscription(
    294                 SubscriptionManager.getDefaultVoiceSubscriptionId());
    295     }
    296 
    297     @Rpc(description = "Stops tracking cell info change " +
    298                        "for specified subscription ID.")
    299     public Boolean telephonyStopTrackingCellInfoChangeForSubscription(
    300                    @RpcParameter(name = "subId") Integer subId) {
    301         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    302         if(listener == null) {
    303             Log.e("Invalid subscription ID");
    304             return false;
    305         }
    306         mTelephonyManager.listen(
    307             listener.mCellInfoChangeListener,
    308             PhoneStateListener.LISTEN_NONE);
    309         return true;
    310     }
    311     @Rpc(description = "Stops tracking call state change " +
    312             "for default voice subscription ID.")
    313     public Boolean telephonyStopTrackingCallStateChange() {
    314         return telephonyStopTrackingCallStateChangeForSubscription(
    315                 SubscriptionManager.getDefaultVoiceSubscriptionId());
    316     }
    317 
    318     @Rpc(description = "Stops tracking call state change " +
    319                        "for specified subscription ID.")
    320     public Boolean telephonyStopTrackingCallStateChangeForSubscription(
    321                    @RpcParameter(name = "subId") Integer subId) {
    322         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    323         if(listener == null) {
    324             Log.e("Invalid subscription ID");
    325             return false;
    326         }
    327         mTelephonyManager.listen(
    328             listener.mCallStateChangeListener,
    329             PhoneStateListener.LISTEN_NONE);
    330         return true;
    331     }
    332 
    333     @Rpc(description = "Starts tracking data connection real time info change" +
    334                        "for default subscription ID.")
    335     public Boolean telephonyStartTrackingDataConnectionRTInfoChange() {
    336         return telephonyStartTrackingDataConnectionRTInfoChangeForSubscription(
    337                                  SubscriptionManager.getDefaultDataSubscriptionId());
    338     }
    339 
    340     @Rpc(description = "Starts tracking data connection real time info change" +
    341                        "for specified subscription ID.")
    342     public Boolean telephonyStartTrackingDataConnectionRTInfoChangeForSubscription(
    343                    @RpcParameter(name = "subId") Integer subId) {
    344         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    345         if(listener == null) {
    346             Log.e("Invalid subscription ID");
    347             return false;
    348         }
    349         mTelephonyManager.listen(
    350             listener.mDataConnectionRTInfoChangeListener,
    351             DataConnectionRealTimeInfoChangeListener.sListeningStates);
    352         return true;
    353     }
    354 
    355     @Rpc(description = "Stops tracking data connection real time info change" +
    356                        "for default subscription ID.")
    357     public Boolean telephonyStopTrackingDataConnectionRTInfoChange() {
    358         return telephonyStopTrackingDataConnectionRTInfoChangeForSubscription(
    359                                  SubscriptionManager.getDefaultDataSubscriptionId());
    360     }
    361 
    362     @Rpc(description = "Stops tracking data connection real time info change" +
    363                        "for specified subscription ID.")
    364     public Boolean telephonyStopTrackingDataConnectionRTInfoChangeForSubscription(
    365                    @RpcParameter(name = "subId") Integer subId) {
    366         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    367         if(listener == null) {
    368             Log.e("Invalid subscription ID");
    369             return false;
    370         }
    371         mTelephonyManager.listen(
    372             listener.mDataConnectionRTInfoChangeListener,
    373             PhoneStateListener.LISTEN_NONE);
    374         return true;
    375     }
    376 
    377     @Rpc(description = "Starts tracking data connection state change" +
    378                        "for default subscription ID..")
    379     public Boolean telephonyStartTrackingDataConnectionStateChange() {
    380         return telephonyStartTrackingDataConnectionStateChangeForSubscription(
    381                                  SubscriptionManager.getDefaultDataSubscriptionId());
    382     }
    383 
    384     @Rpc(description = "Starts tracking data connection state change" +
    385                        "for specified subscription ID.")
    386     public Boolean telephonyStartTrackingDataConnectionStateChangeForSubscription(
    387                    @RpcParameter(name = "subId") Integer subId) {
    388         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    389         if(listener == null) {
    390             Log.e("Invalid subscription ID");
    391             return false;
    392         }
    393         mTelephonyManager.listen(
    394             listener.mDataConnectionStateChangeListener,
    395             DataConnectionStateChangeListener.sListeningStates);
    396         return true;
    397     }
    398 
    399     @Rpc(description = "Stops tracking data connection state change " +
    400                        "for default subscription ID..")
    401     public Boolean telephonyStopTrackingDataConnectionStateChange() {
    402         return telephonyStopTrackingDataConnectionStateChangeForSubscription(
    403                                  SubscriptionManager.getDefaultDataSubscriptionId());
    404     }
    405 
    406     @Rpc(description = "Stops tracking data connection state change " +
    407                        "for specified subscription ID..")
    408     public Boolean telephonyStopTrackingDataConnectionStateChangeForSubscription(
    409                    @RpcParameter(name = "subId") Integer subId) {
    410         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    411         if(listener == null) {
    412             Log.e("Invalid subscription ID");
    413             return false;
    414         }
    415         mTelephonyManager.listen(
    416             listener.mDataConnectionStateChangeListener,
    417             PhoneStateListener.LISTEN_NONE);
    418         return true;
    419     }
    420 
    421     @Rpc(description = "Starts tracking service state change " +
    422                        "for default subscription ID.")
    423     public Boolean telephonyStartTrackingServiceStateChange() {
    424         return telephonyStartTrackingServiceStateChangeForSubscription(
    425                                  SubscriptionManager.getDefaultSubscriptionId());
    426     }
    427 
    428     @Rpc(description = "Starts tracking service state change " +
    429                        "for specified subscription ID.")
    430     public Boolean telephonyStartTrackingServiceStateChangeForSubscription(
    431                    @RpcParameter(name = "subId") Integer subId) {
    432         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    433         if(listener == null) {
    434             Log.e("Invalid subscription ID");
    435             return false;
    436         }
    437         mTelephonyManager.listen(
    438             listener.mServiceStateChangeListener,
    439             ServiceStateChangeListener.sListeningStates);
    440         return true;
    441     }
    442 
    443     @Rpc(description = "Stops tracking service state change " +
    444                        "for default subscription ID.")
    445     public Boolean telephonyStopTrackingServiceStateChange() {
    446         return telephonyStopTrackingServiceStateChangeForSubscription(
    447                                  SubscriptionManager.getDefaultSubscriptionId());
    448     }
    449 
    450     @Rpc(description = "Stops tracking service state change " +
    451                        "for specified subscription ID.")
    452     public Boolean telephonyStopTrackingServiceStateChangeForSubscription(
    453                    @RpcParameter(name = "subId") Integer subId) {
    454         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    455         if(listener == null) {
    456             Log.e("Invalid subscription ID");
    457             return false;
    458         }
    459         mTelephonyManager.listen(
    460             listener.mServiceStateChangeListener,
    461             PhoneStateListener.LISTEN_NONE);
    462             return true;
    463     }
    464 
    465     @Rpc(description = "Starts tracking signal strength change " +
    466                        "for default subscription ID.")
    467     public Boolean telephonyStartTrackingSignalStrengthChange() {
    468         return telephonyStartTrackingSignalStrengthChangeForSubscription(
    469                                  SubscriptionManager.getDefaultSubscriptionId());
    470     }
    471 
    472     @Rpc(description = "Starts tracking signal strength change " +
    473                        "for specified subscription ID.")
    474     public Boolean telephonyStartTrackingSignalStrengthChangeForSubscription(
    475                    @RpcParameter(name = "subId") Integer subId) {
    476         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    477         if(listener == null) {
    478             Log.e("Invalid subscription ID");
    479             return false;
    480         }
    481         mTelephonyManager.listen(
    482             listener.mSignalStrengthChangeListener,
    483             SignalStrengthChangeListener.sListeningStates);
    484         return true;
    485     }
    486 
    487     @Rpc(description = "Stops tracking signal strength change " +
    488                        "for default subscription ID.")
    489     public Boolean telephonyStopTrackingSignalStrengthChange() {
    490         return telephonyStopTrackingSignalStrengthChangeForSubscription(
    491                                  SubscriptionManager.getDefaultSubscriptionId());
    492     }
    493 
    494     @Rpc(description = "Stops tracking signal strength change " +
    495                        "for specified subscription ID.")
    496     public Boolean telephonyStopTrackingSignalStrengthChangeForSubscription(
    497                    @RpcParameter(name = "subId") Integer subId) {
    498         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    499         if(listener == null) {
    500             Log.e("Invalid subscription ID");
    501             return false;
    502         }
    503         mTelephonyManager.listen(
    504             listener.mSignalStrengthChangeListener,
    505             PhoneStateListener.LISTEN_NONE);
    506         return true;
    507     }
    508 
    509     @Rpc(description = "Starts tracking voice mail state change " +
    510                        "for default subscription ID.")
    511     public Boolean telephonyStartTrackingVoiceMailStateChange() {
    512         return telephonyStartTrackingVoiceMailStateChangeForSubscription(
    513                                  SubscriptionManager.getDefaultSubscriptionId());
    514     }
    515 
    516     @Rpc(description = "Starts tracking voice mail state change " +
    517                        "for specified subscription ID.")
    518     public Boolean telephonyStartTrackingVoiceMailStateChangeForSubscription(
    519                    @RpcParameter(name = "subId") Integer subId) {
    520         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
    521         if(listener == null) {
    522             Log.e("Invalid subscription ID");
    523             return false;
    524         }
    525         mTelephonyManager.listen(
    526             listener.mVoiceMailStateChangeListener,
    527             VoiceMailStateChangeListener.sListeningStates);
    528         return true;
    529     }
    530 
    531     @Rpc(description = "Stops tracking voice mail state change " +
    532                        "for default subscription ID.")
    533     public Boolean telephonyStopTrackingVoiceMailStateChange() {
    534         return telephonyStopTrackingVoiceMailStateChangeForSubscription(
    535                                  SubscriptionManager.getDefaultSubscriptionId());
    536     }
    537 
    538     @Rpc(description = "Stops tracking voice mail state change " +
    539                        "for specified subscription ID.")
    540     public Boolean telephonyStopTrackingVoiceMailStateChangeForSubscription(
    541                    @RpcParameter(name = "subId") Integer subId) {
    542         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
    543         if(listener == null) {
    544             Log.e("Invalid subscription ID");
    545             return false;
    546         }
    547         mTelephonyManager.listen(
    548             listener.mVoiceMailStateChangeListener,
    549             PhoneStateListener.LISTEN_NONE);
    550         return true;
    551     }
    552 
    553     @Rpc(description = "Answers an incoming ringing call.")
    554     public void telephonyAnswerCall() throws RemoteException {
    555         mTelephonyManager.silenceRinger();
    556         mTelephonyManager.answerRingingCall();
    557     }
    558 
    559     @Rpc(description = "Returns the current cell location.")
    560     public CellLocation telephonyGetCellLocation() {
    561         return mTelephonyManager.getCellLocation();
    562     }
    563 
    564     @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator." +
    565                        "for default subscription ID")
    566     public String telephonyGetNetworkOperator() {
    567         return telephonyGetNetworkOperatorForSubscription(
    568                         SubscriptionManager.getDefaultSubscriptionId());
    569     }
    570 
    571     @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator" +
    572                        "for specified subscription ID.")
    573     public String telephonyGetNetworkOperatorForSubscription(
    574                   @RpcParameter(name = "subId") Integer subId) {
    575         return mTelephonyManager.getNetworkOperator(subId);
    576     }
    577 
    578     @Rpc(description = "Returns the alphabetic name of current registered operator" +
    579                        "for specified subscription ID.")
    580     public String telephonyGetNetworkOperatorName() {
    581         return telephonyGetNetworkOperatorNameForSubscription(
    582                         SubscriptionManager.getDefaultSubscriptionId());
    583     }
    584 
    585     @Rpc(description = "Returns the alphabetic name of registered operator " +
    586                        "for specified subscription ID.")
    587     public String telephonyGetNetworkOperatorNameForSubscription(
    588                   @RpcParameter(name = "subId") Integer subId) {
    589         return mTelephonyManager.getNetworkOperatorName(subId);
    590     }
    591 
    592     @Rpc(description = "Returns the current RAT in use on the device.+" +
    593                        "for default subscription ID")
    594     public String telephonyGetNetworkType() {
    595 
    596         Log.d("sl4a:getNetworkType() is deprecated!" +
    597                 "Please use getVoiceNetworkType()" +
    598                 " or getDataNetworkTpe()");
    599 
    600         return telephonyGetNetworkTypeForSubscription(
    601                        SubscriptionManager.getDefaultSubscriptionId());
    602     }
    603 
    604     @Rpc(description = "Returns the current RAT in use on the device" +
    605             " for a given Subscription.")
    606     public String telephonyGetNetworkTypeForSubscription(
    607                   @RpcParameter(name = "subId") Integer subId) {
    608 
    609         Log.d("sl4a:getNetworkTypeForSubscriber() is deprecated!" +
    610                 "Please use getVoiceNetworkType()" +
    611                 " or getDataNetworkTpe()");
    612 
    613         return TelephonyUtils.getNetworkTypeString(
    614             mTelephonyManager.getNetworkType(subId));
    615     }
    616 
    617     @Rpc(description = "Returns the current voice RAT for" +
    618             " the default voice subscription.")
    619     public String telephonyGetVoiceNetworkType() {
    620         return telephonyGetVoiceNetworkTypeForSubscription(
    621                          SubscriptionManager.getDefaultVoiceSubscriptionId());
    622     }
    623 
    624     @Rpc(description = "Returns the current voice RAT for" +
    625             " the specified voice subscription.")
    626     public String telephonyGetVoiceNetworkTypeForSubscription(
    627                   @RpcParameter(name = "subId") Integer subId) {
    628         return TelephonyUtils.getNetworkTypeString(
    629             mTelephonyManager.getVoiceNetworkType(subId));
    630     }
    631 
    632     @Rpc(description = "Returns the current data RAT for" +
    633             " the defaut data subscription")
    634     public String telephonyGetDataNetworkType() {
    635         return telephonyGetDataNetworkTypeForSubscription(
    636                          SubscriptionManager.getDefaultDataSubscriptionId());
    637     }
    638 
    639     @Rpc(description = "Returns the current data RAT for" +
    640             " the specified data subscription")
    641     public String telephonyGetDataNetworkTypeForSubscription(
    642                   @RpcParameter(name = "subId") Integer subId) {
    643         return TelephonyUtils.getNetworkTypeString(
    644             mTelephonyManager.getDataNetworkType(subId));
    645     }
    646 
    647     @Rpc(description = "Returns the device phone type.")
    648     public String telephonyGetPhoneType() {
    649         return TelephonyUtils.getPhoneTypeString(
    650             mTelephonyManager.getPhoneType());
    651     }
    652 
    653     @Rpc(description = "Returns the MCC for default subscription ID")
    654     public String telephonyGetSimCountryIso() {
    655          return telephonyGetSimCountryIsoForSubscription(
    656                       SubscriptionManager.getDefaultSubscriptionId());
    657     }
    658 
    659     @Rpc(description = "Returns the MCC for specified subscription ID")
    660     public String telephonyGetSimCountryIsoForSubscription(
    661                   @RpcParameter(name = "subId") Integer subId) {
    662         return mTelephonyManager.getSimCountryIso(subId);
    663     }
    664 
    665     @Rpc(description = "Returns the MCC+MNC for default subscription ID")
    666     public String telephonyGetSimOperator() {
    667         return telephonyGetSimOperatorForSubscription(
    668                   SubscriptionManager.getDefaultSubscriptionId());
    669     }
    670 
    671     @Rpc(description = "Returns the MCC+MNC for specified subscription ID")
    672     public String telephonyGetSimOperatorForSubscription(
    673                   @RpcParameter(name = "subId") Integer subId) {
    674         return mTelephonyManager.getSimOperator(subId);
    675     }
    676 
    677     @Rpc(description = "Returns the Service Provider Name (SPN)" +
    678                        "for default subscription ID")
    679     public String telephonyGetSimOperatorName() {
    680         return telephonyGetSimOperatorNameForSubscription(
    681                   SubscriptionManager.getDefaultSubscriptionId());
    682     }
    683 
    684     @Rpc(description = "Returns the Service Provider Name (SPN)" +
    685                        " for specified subscription ID.")
    686     public String telephonyGetSimOperatorNameForSubscription(
    687                   @RpcParameter(name = "subId") Integer subId) {
    688         return mTelephonyManager.getSimOperatorName(subId);
    689     }
    690 
    691     @Rpc(description = "Returns the serial number of the SIM for " +
    692                        "default subscription ID, or Null if unavailable")
    693     public String telephonyGetSimSerialNumber() {
    694         return telephonyGetSimSerialNumberForSubscription(
    695                   SubscriptionManager.getDefaultSubscriptionId());
    696     }
    697 
    698     @Rpc(description = "Returns the serial number of the SIM for " +
    699                        "specified subscription ID, or Null if unavailable")
    700     public String telephonyGetSimSerialNumberForSubscription(
    701                   @RpcParameter(name = "subId") Integer subId) {
    702         return mTelephonyManager.getSimSerialNumber(subId);
    703     }
    704 
    705     @Rpc(description = "Returns the state of the SIM card for default slot ID.")
    706     public String telephonyGetSimState() {
    707         return telephonyGetSimStateForSlotId(
    708                   mTelephonyManager.getDefaultSim());
    709     }
    710 
    711     @Rpc(description = "Returns the state of the SIM card for specified slot ID.")
    712     public String telephonyGetSimStateForSlotId(
    713                   @RpcParameter(name = "slotId") Integer slotId) {
    714         return TelephonyUtils.getSimStateString(
    715             mTelephonyManager.getSimState(slotId));
    716     }
    717 
    718     @Rpc(description = "Get Authentication Challenge Response from a " +
    719             "given SIM Application")
    720     public String telephonyGetIccSimChallengeResponse(
    721             @RpcParameter(name = "appType") Integer appType,
    722             @RpcParameter(name = "authType") Integer authType,
    723             @RpcParameter(name = "hexChallenge") String hexChallenge) {
    724         return telephonyGetIccSimChallengeResponseForSubscription(
    725                 SubscriptionManager.getDefaultSubscriptionId(), appType, authType, hexChallenge);
    726     }
    727 
    728     @Rpc(description = "Get Authentication Challenge Response from a " +
    729             "given SIM Application for a specified Subscription")
    730     public String telephonyGetIccSimChallengeResponseForSubscription(
    731             @RpcParameter(name = "subId") Integer subId,
    732             @RpcParameter(name = "appType") Integer appType,
    733             @RpcParameter(name = "authType") Integer authType,
    734             @RpcParameter(name = "hexChallenge") String hexChallenge) {
    735 
    736         try {
    737             String b64Data = BaseEncoding.base64().encode(BaseEncoding.base16().decode(hexChallenge));
    738             String b64Result = mTelephonyManager.getIccAuthentication(subId, appType, authType, b64Data);
    739             return (b64Result != null)
    740                     ? BaseEncoding.base16().encode(BaseEncoding.base64().decode(b64Result)) : null;
    741         } catch(Exception e) {
    742             Log.e("Exception in phoneGetIccSimChallengeResponseForSubscription" + e.toString());
    743             return null;
    744         }
    745     }
    746 
    747     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
    748             "for default subscription ID, or null if unavailable")
    749     public String telephonyGetSubscriberId() {
    750         return telephonyGetSubscriberIdForSubscription(
    751                 SubscriptionManager.getDefaultSubscriptionId());
    752     }
    753 
    754     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
    755                        "for specified subscription ID, or null if unavailable")
    756     public String telephonyGetSubscriberIdForSubscription(
    757                   @RpcParameter(name = "subId") Integer subId) {
    758         return mTelephonyManager.getSubscriberId(subId);
    759     }
    760 
    761     @Rpc(description = "Retrieves the alphabetic id associated with the" +
    762                        " voice mail number for default subscription ID.")
    763     public String telephonyGetVoiceMailAlphaTag() {
    764         return telephonyGetVoiceMailAlphaTagForSubscription(
    765                    SubscriptionManager.getDefaultSubscriptionId());
    766     }
    767 
    768 
    769     @Rpc(description = "Retrieves the alphabetic id associated with the " +
    770                        "voice mail number for specified subscription ID.")
    771     public String telephonyGetVoiceMailAlphaTagForSubscription(
    772                   @RpcParameter(name = "subId") Integer subId) {
    773         return mTelephonyManager.getVoiceMailAlphaTag(subId);
    774     }
    775 
    776     @Rpc(description = "Returns the voice mail number " +
    777                        "for default subscription ID; null if unavailable.")
    778     public String telephonyGetVoiceMailNumber() {
    779         return telephonyGetVoiceMailNumberForSubscription(
    780                    SubscriptionManager.getDefaultSubscriptionId());
    781     }
    782 
    783     @Rpc(description = "Returns the voice mail number " +
    784                         "for specified subscription ID; null if unavailable.")
    785     public String telephonyGetVoiceMailNumberForSubscription(
    786                   @RpcParameter(name = "subId") Integer subId) {
    787         return mTelephonyManager.getVoiceMailNumber(subId);
    788     }
    789 
    790     @Rpc(description = "Get voice message count for specified subscription ID.")
    791     public Integer telephonyGetVoiceMailCountForSubscription(
    792                    @RpcParameter(name = "subId") Integer subId) {
    793         return mTelephonyManager.getVoiceMessageCount(subId);
    794     }
    795 
    796     @Rpc(description = "Get voice message count for default subscription ID.")
    797     public Integer telephonyGetVoiceMailCount() {
    798         return mTelephonyManager.getVoiceMessageCount();
    799     }
    800 
    801     @Rpc(description = "Returns true if the device is in  roaming state" +
    802                        "for default subscription ID")
    803     public Boolean telephonyCheckNetworkRoaming() {
    804         return telephonyCheckNetworkRoamingForSubscription(
    805                              SubscriptionManager.getDefaultSubscriptionId());
    806     }
    807 
    808     @Rpc(description = "Returns true if the device is in roaming state " +
    809                        "for specified subscription ID")
    810     public Boolean telephonyCheckNetworkRoamingForSubscription(
    811                    @RpcParameter(name = "subId") Integer subId) {
    812         return mTelephonyManager.isNetworkRoaming(subId);
    813     }
    814 
    815     @Rpc(description = "Returns the unique device ID such as MEID or IMEI " +
    816                        "for deault sim slot ID, null if unavailable")
    817     public String telephonyGetDeviceId() {
    818         return telephonyGetDeviceIdForSlotId(mTelephonyManager.getDefaultSim());
    819     }
    820 
    821     @Rpc(description = "Returns the unique device ID such as MEID or IMEI for" +
    822                        " specified slot ID, null if unavailable")
    823     public String telephonyGetDeviceIdForSlotId(
    824                   @RpcParameter(name = "slotId")
    825                   Integer slotId){
    826         return mTelephonyManager.getDeviceId(slotId);
    827     }
    828 
    829     @Rpc(description = "Returns the modem sw version, such as IMEI-SV;" +
    830                        " null if unavailable")
    831     public String telephonyGetDeviceSoftwareVersion() {
    832         return mTelephonyManager.getDeviceSoftwareVersion();
    833     }
    834 
    835     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
    836                        "for default subscription ID; null if unavailable")
    837     public String telephonyGetLine1Number() {
    838         return mTelephonyManager.getLine1Number();
    839     }
    840 
    841     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
    842                        "for specified subscription ID; null if unavailable")
    843     public String telephonyGetLine1NumberForSubscription(
    844                   @RpcParameter(name = "subId") Integer subId) {
    845         return mTelephonyManager.getLine1Number(subId);
    846     }
    847 
    848     @Rpc(description = "Returns the Alpha Tag for the default subscription " +
    849                        "ID; null if unavailable")
    850     public String telephonyGetLine1AlphaTag() {
    851         return mTelephonyManager.getLine1AlphaTag();
    852     }
    853 
    854     @Rpc(description = "Returns the Alpha Tag for the specified subscription " +
    855                        "ID; null if unavailable")
    856     public String telephonyGetLine1AlphaTagForSubscription(
    857                   @RpcParameter(name = "subId") Integer subId) {
    858         return mTelephonyManager.getLine1AlphaTag(subId);
    859     }
    860 
    861     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
    862                        "for the default subscription")
    863     public Boolean telephonySetLine1Number(
    864                 @RpcParameter(name = "number") String number,
    865                 @RpcOptional
    866                 @RpcParameter(name = "alphaTag") String alphaTag) {
    867         return mTelephonyManager.setLine1NumberForDisplay(alphaTag, number);
    868     }
    869 
    870     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
    871                        "for the specified subscription")
    872     public Boolean telephonySetLine1NumberForSubscription(
    873                 @RpcParameter(name = "subId") Integer subId,
    874                 @RpcParameter(name = "number") String number,
    875                 @RpcOptional
    876                 @RpcParameter(name = "alphaTag") String alphaTag) {
    877         return mTelephonyManager.setLine1NumberForDisplay(subId, alphaTag, number);
    878     }
    879 
    880     @Rpc(description = "Returns the neighboring cell information of the device.")
    881     public List<NeighboringCellInfo> telephonyGetNeighboringCellInfo() {
    882         return mTelephonyManager.getNeighboringCellInfo();
    883     }
    884 
    885     @Rpc(description =  "Sets the minimum reporting interval for CellInfo" +
    886                         "0-as quickly as possible, 0x7FFFFFF-off")
    887     public void telephonySetCellInfoListRate(
    888                 @RpcParameter(name = "rate") Integer rate
    889             ) {
    890         mTelephonyManager.setCellInfoListRate(rate);
    891     }
    892 
    893     @Rpc(description = "Returns all observed cell information from all radios"+
    894                        "on the device including the primary and neighboring cells")
    895     public List<CellInfo> telephonyGetAllCellInfo() {
    896         return mTelephonyManager.getAllCellInfo();
    897     }
    898 
    899     @Rpc(description = "Returns True if cellular data is enabled for" +
    900                        "default data subscription ID.")
    901     public Boolean telephonyIsDataEnabled() {
    902         return telephonyIsDataEnabledForSubscription(
    903                    SubscriptionManager.getDefaultDataSubscriptionId());
    904     }
    905 
    906     @Rpc(description = "Returns True if data connection is enabled.")
    907     public Boolean telephonyIsDataEnabledForSubscription(
    908                    @RpcParameter(name = "subId") Integer subId) {
    909         return mTelephonyManager.getDataEnabled(subId);
    910     }
    911 
    912     @Rpc(description = "Toggles data connection on /off for" +
    913                        " default data subscription ID.")
    914     public void telephonyToggleDataConnection(
    915                 @RpcParameter(name = "enabled")
    916                 @RpcOptional Boolean enabled) {
    917         telephonyToggleDataConnectionForSubscription(
    918                          SubscriptionManager.getDefaultDataSubscriptionId(), enabled);
    919     }
    920 
    921     @Rpc(description = "Toggles data connection on/off for" +
    922                        " specified subscription ID")
    923     public void telephonyToggleDataConnectionForSubscription(
    924                 @RpcParameter(name = "subId") Integer subId,
    925                 @RpcParameter(name = "enabled")
    926                 @RpcOptional Boolean enabled) {
    927         if (enabled == null) {
    928             enabled = !telephonyIsDataEnabledForSubscription(subId);
    929         }
    930         mTelephonyManager.setDataEnabled(subId, enabled);
    931     }
    932 
    933     @Rpc(description = "Sets an APN and make that as preferred APN.")
    934     public void telephonySetAPN(@RpcParameter(name = "name") final String name,
    935                        @RpcParameter(name = "apn") final String apn,
    936                        @RpcParameter(name = "type") @RpcOptional @RpcDefault("")
    937                        final String type,
    938                        @RpcParameter(name = "subId") @RpcOptional Integer subId) {
    939         //TODO: b/26273471 Need to find out how to set APN for specific subId
    940         Uri uri;
    941         Cursor cursor;
    942 
    943         String mcc = "";
    944         String mnc = "";
    945 
    946         String numeric = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
    947         // MCC is first 3 chars and then in 2 - 3 chars of MNC
    948         if (numeric != null && numeric.length() > 4) {
    949             // Country code
    950             mcc = numeric.substring(0, 3);
    951             // Network code
    952             mnc = numeric.substring(3);
    953         }
    954 
    955         uri = mService.getContentResolver().insert(
    956                 Telephony.Carriers.CONTENT_URI, new ContentValues());
    957         if (uri == null) {
    958             Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI);
    959             return;
    960         }
    961 
    962         cursor = mService.getContentResolver().query(uri, sProjection, null, null, null);
    963         cursor.moveToFirst();
    964 
    965         ContentValues values = new ContentValues();
    966 
    967         values.put(Telephony.Carriers.NAME, name);
    968         values.put(Telephony.Carriers.APN, apn);
    969         values.put(Telephony.Carriers.PROXY, "");
    970         values.put(Telephony.Carriers.PORT, "");
    971         values.put(Telephony.Carriers.MMSPROXY, "");
    972         values.put(Telephony.Carriers.MMSPORT, "");
    973         values.put(Telephony.Carriers.USER, "");
    974         values.put(Telephony.Carriers.SERVER, "");
    975         values.put(Telephony.Carriers.PASSWORD, "");
    976         values.put(Telephony.Carriers.MMSC, "");
    977         values.put(Telephony.Carriers.TYPE, type);
    978         values.put(Telephony.Carriers.MCC, mcc);
    979         values.put(Telephony.Carriers.MNC, mnc);
    980         values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
    981 
    982         int ret = mService.getContentResolver().update(uri, values, null, null);
    983         Log.d("after update " + ret);
    984         cursor.close();
    985 
    986         // Make this APN as the preferred
    987         String where = "name=\"" + name + "\"";
    988 
    989         Cursor c = mService.getContentResolver().query(
    990                 Telephony.Carriers.CONTENT_URI,
    991                 new String[] {
    992                         "_id", "name", "apn", "type"
    993                 }, where, null,
    994                 Telephony.Carriers.DEFAULT_SORT_ORDER);
    995         if (c != null) {
    996             c.moveToFirst();
    997             String key = c.getString(0);
    998             final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
    999             ContentResolver resolver = mService.getContentResolver();
   1000             ContentValues prefAPN = new ContentValues();
   1001             prefAPN.put("apn_id", key);
   1002             resolver.update(Uri.parse(PREFERRED_APN_URI), prefAPN, null, null);
   1003         }
   1004         c.close();
   1005     }
   1006 
   1007     @Rpc(description = "Returns the number of APNs defined")
   1008     public int telephonyGetNumberOfAPNs(
   1009                @RpcParameter(name = "subId")
   1010                @RpcOptional Integer subId) {
   1011         //TODO: b/26273471 Need to find out how to get Number of APNs for specific subId
   1012         int result = 0;
   1013         String where = "numeric=\"" + android.os.SystemProperties.get(
   1014                         TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\"";
   1015 
   1016         Cursor cursor = mService.getContentResolver().query(
   1017                 Telephony.Carriers.CONTENT_URI,
   1018                 new String[] {"_id", "name", "apn", "type"}, where, null,
   1019                 Telephony.Carriers.DEFAULT_SORT_ORDER);
   1020 
   1021         if (cursor != null) {
   1022             result = cursor.getCount();
   1023         }
   1024         cursor.close();
   1025         return result;
   1026     }
   1027 
   1028     @Rpc(description = "Returns the currently selected APN name")
   1029     public String telephonyGetSelectedAPN(
   1030                   @RpcParameter(name = "subId")
   1031                   @RpcOptional Integer subId) {
   1032         //TODO: b/26273471 Need to find out how to get selected APN for specific subId
   1033         String key = null;
   1034         int ID_INDEX = 0;
   1035         final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
   1036 
   1037         Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI),
   1038                 new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
   1039 
   1040         if (cursor.getCount() > 0) {
   1041             cursor.moveToFirst();
   1042             key = cursor.getString(ID_INDEX);
   1043         }
   1044         cursor.close();
   1045         return key;
   1046     }
   1047 
   1048     @Rpc(description = "Returns the current data connection state")
   1049     public String telephonyGetDataConnectionState() {
   1050         return TelephonyUtils.getDataConnectionStateString(
   1051             mTelephonyManager.getDataState());
   1052     }
   1053 
   1054     @Rpc(description = "Enables or Disables Video Calling()")
   1055     public void telephonyEnableVideoCalling(
   1056             @RpcParameter(name = "enable") boolean enable) {
   1057         mTelephonyManager.enableVideoCalling(enable);
   1058     }
   1059 
   1060     @Rpc(description = "Returns a boolean of whether or not " +
   1061             "video calling setting is enabled by the user")
   1062     public Boolean telephonyIsVideoCallingEnabled() {
   1063         return mTelephonyManager.isVideoCallingEnabled();
   1064     }
   1065 
   1066     @Rpc(description = "Returns a boolean of whether video calling is available for use")
   1067     public Boolean telephonyIsVideoCallingAvailable() {
   1068         return mTelephonyManager.isVideoTelephonyAvailable();
   1069     }
   1070 
   1071     @Rpc(description = "Returns a boolean of whether or not the device is ims registered")
   1072     public Boolean telephonyIsImsRegistered() {
   1073         return mTelephonyManager.isImsRegistered();
   1074     }
   1075 
   1076     @Rpc(description = "Returns a boolean of whether or not volte calling is available for use")
   1077     public Boolean telephonyIsVolteAvailable() {
   1078         return mTelephonyManager.isVolteAvailable();
   1079     }
   1080 
   1081     @Rpc(description = "Returns a boolean of whether or not wifi calling is available for use")
   1082     public Boolean telephonyIsWifiCallingAvailable() {
   1083         return mTelephonyManager.isWifiCallingAvailable();
   1084     }
   1085 
   1086     @Rpc(description = "Returns the service state for default subscription ID")
   1087     public String telephonyGetServiceState() {
   1088         //TODO: b/26273807 need to have framework API to get service state.
   1089         return telephonyGetServiceStateForSubscription(
   1090                                  SubscriptionManager.getDefaultSubscriptionId());
   1091     }
   1092 
   1093     @Rpc(description = "Returns the service state for specified subscription ID")
   1094     public String telephonyGetServiceStateForSubscription(
   1095                   @RpcParameter(name = "subId") Integer subId) {
   1096         //TODO: b/26273807 need to have framework API to get service state.
   1097         return null;
   1098     }
   1099 
   1100     @Rpc(description = "Returns the call state for default subscription ID")
   1101     public String telephonyGetCallState() {
   1102         return telephonyGetCallStateForSubscription(
   1103                                SubscriptionManager.getDefaultSubscriptionId());
   1104     }
   1105 
   1106     @Rpc(description = "Returns the call state for specified subscription ID")
   1107     public String telephonyGetCallStateForSubscription(
   1108                   @RpcParameter(name = "subId") Integer subId) {
   1109         return TelephonyUtils.getTelephonyCallStateString(
   1110             mTelephonyManager.getCallState(subId));
   1111     }
   1112 
   1113     @Rpc(description = "Returns current signal strength for default subscription ID.")
   1114     public SignalStrength telephonyGetSignalStrength() {
   1115         return telephonyGetSignalStrengthForSubscription(
   1116                                SubscriptionManager.getDefaultSubscriptionId());
   1117     }
   1118 
   1119     @Rpc(description = "Returns current signal strength for specified subscription ID.")
   1120     public SignalStrength telephonyGetSignalStrengthForSubscription(
   1121                     @RpcParameter(name = "subId") Integer subId) {
   1122         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
   1123         if(listener == null) {
   1124             Log.e("Invalid subscription ID");
   1125             return null;
   1126         }
   1127         return listener.mSignalStrengthChangeListener.mSignalStrengths;
   1128     }
   1129 
   1130     @Rpc(description = "Returns the sim count.")
   1131     public int telephonyGetSimCount() {
   1132         return mTelephonyManager.getSimCount();
   1133     }
   1134 
   1135     private StateChangeListener getStateChangeListenerForSubscription(
   1136             int subId,
   1137             boolean createIfNeeded) {
   1138 
   1139        if(mStateChangeListeners.get(subId) == null) {
   1140             if(createIfNeeded == false) {
   1141                 return null;
   1142             }
   1143 
   1144             if(mSubscriptionManager.getActiveSubscriptionInfo(subId) == null) {
   1145                 Log.e("Cannot get listener for invalid/inactive subId");
   1146                 return null;
   1147             }
   1148 
   1149             mStateChangeListeners.put(subId, new StateChangeListener(subId));
   1150         }
   1151 
   1152         return mStateChangeListeners.get(subId);
   1153     }
   1154 
   1155     //FIXME: This whole class needs reworking. Why do we have separate listeners for everything?
   1156     //We need one listener that overrides multiple methods.
   1157     private final class StateChangeListener {
   1158         public ServiceStateChangeListener mServiceStateChangeListener;
   1159         public SignalStrengthChangeListener mSignalStrengthChangeListener;
   1160         public CallStateChangeListener mCallStateChangeListener;
   1161         public CellInfoChangeListener mCellInfoChangeListener;
   1162         public DataConnectionStateChangeListener mDataConnectionStateChangeListener;
   1163         public DataConnectionRealTimeInfoChangeListener mDataConnectionRTInfoChangeListener;
   1164         public VoiceMailStateChangeListener mVoiceMailStateChangeListener;
   1165 
   1166         public StateChangeListener(int subId) {
   1167             mServiceStateChangeListener =
   1168                 new ServiceStateChangeListener(mEventFacade, subId, mService.getMainLooper());
   1169             mSignalStrengthChangeListener =
   1170                 new SignalStrengthChangeListener(mEventFacade, subId, mService.getMainLooper());
   1171             mDataConnectionStateChangeListener =
   1172                 new DataConnectionStateChangeListener(
   1173                         mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
   1174             mCallStateChangeListener =
   1175                 new CallStateChangeListener(mEventFacade, subId, mService.getMainLooper());
   1176             mCellInfoChangeListener =
   1177                 new CellInfoChangeListener(mEventFacade, subId, mService.getMainLooper());
   1178             mDataConnectionRTInfoChangeListener =
   1179                 new DataConnectionRealTimeInfoChangeListener(
   1180                         mEventFacade, subId, mService.getMainLooper());
   1181             mVoiceMailStateChangeListener =
   1182                 new VoiceMailStateChangeListener(mEventFacade, subId, mService.getMainLooper());
   1183         }
   1184 
   1185         public void shutdown() {
   1186             mTelephonyManager.listen(
   1187                     mServiceStateChangeListener,
   1188                     PhoneStateListener.LISTEN_NONE);
   1189             mTelephonyManager.listen(
   1190                     mSignalStrengthChangeListener,
   1191                     PhoneStateListener.LISTEN_NONE);
   1192             mTelephonyManager.listen(
   1193                     mCallStateChangeListener,
   1194                     PhoneStateListener.LISTEN_NONE);
   1195             mTelephonyManager.listen(
   1196                     mCellInfoChangeListener,
   1197                     PhoneStateListener.LISTEN_NONE);
   1198             mTelephonyManager.listen(
   1199                     mDataConnectionStateChangeListener,
   1200                     PhoneStateListener.LISTEN_NONE);
   1201             mTelephonyManager.listen(
   1202                     mDataConnectionRTInfoChangeListener,
   1203                     PhoneStateListener.LISTEN_NONE);
   1204             mTelephonyManager.listen(
   1205                     mVoiceMailStateChangeListener,
   1206                     PhoneStateListener.LISTEN_NONE);
   1207         }
   1208 
   1209         protected void finalize() {
   1210             try {
   1211                 shutdown();
   1212             } catch(Exception e) {}
   1213         }
   1214     }
   1215 
   1216     @Override
   1217     public void shutdown() {
   1218         for(StateChangeListener listener : mStateChangeListeners.values()) {
   1219             listener.shutdown();
   1220         }
   1221     }
   1222 }
   1223