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