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     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
793             "for default subscription ID, or null if unavailable")
telephonyGetSubscriberId()794     public String telephonyGetSubscriberId() {
795         return telephonyGetSubscriberIdForSubscription(
796                 SubscriptionManager.getDefaultSubscriptionId());
797     }
798 
799     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
800                        "for specified subscription ID, or null if unavailable")
telephonyGetSubscriberIdForSubscription( @pcParametername = "subId") Integer subId)801     public String telephonyGetSubscriberIdForSubscription(
802                   @RpcParameter(name = "subId") Integer subId) {
803         return mTelephonyManager.getSubscriberId(subId);
804     }
805 
806     @Rpc(description = "Retrieves the alphabetic id associated with the" +
807                        " voice mail number for default subscription ID.")
telephonyGetVoiceMailAlphaTag()808     public String telephonyGetVoiceMailAlphaTag() {
809         return telephonyGetVoiceMailAlphaTagForSubscription(
810                    SubscriptionManager.getDefaultSubscriptionId());
811     }
812 
813 
814     @Rpc(description = "Retrieves the alphabetic id associated with the " +
815                        "voice mail number for specified subscription ID.")
telephonyGetVoiceMailAlphaTagForSubscription( @pcParametername = "subId") Integer subId)816     public String telephonyGetVoiceMailAlphaTagForSubscription(
817                   @RpcParameter(name = "subId") Integer subId) {
818         return mTelephonyManager.getVoiceMailAlphaTag(subId);
819     }
820 
821     @Rpc(description = "Returns the voice mail number " +
822                        "for default subscription ID; null if unavailable.")
telephonyGetVoiceMailNumber()823     public String telephonyGetVoiceMailNumber() {
824         return telephonyGetVoiceMailNumberForSubscription(
825                    SubscriptionManager.getDefaultSubscriptionId());
826     }
827 
828     @Rpc(description = "Returns the voice mail number " +
829                         "for specified subscription ID; null if unavailable.")
telephonyGetVoiceMailNumberForSubscription( @pcParametername = "subId") Integer subId)830     public String telephonyGetVoiceMailNumberForSubscription(
831                   @RpcParameter(name = "subId") Integer subId) {
832         return mTelephonyManager.getVoiceMailNumber(subId);
833     }
834 
835     @Rpc(description = "Get voice message count for specified subscription ID.")
telephonyGetVoiceMailCountForSubscription( @pcParametername = "subId") Integer subId)836     public Integer telephonyGetVoiceMailCountForSubscription(
837                    @RpcParameter(name = "subId") Integer subId) {
838         return mTelephonyManager.getVoiceMessageCount(subId);
839     }
840 
841     @Rpc(description = "Get voice message count for default subscription ID.")
telephonyGetVoiceMailCount()842     public Integer telephonyGetVoiceMailCount() {
843         return mTelephonyManager.getVoiceMessageCount();
844     }
845 
846     @Rpc(description = "Returns true if the device is in  roaming state" +
847                        "for default subscription ID")
telephonyCheckNetworkRoaming()848     public Boolean telephonyCheckNetworkRoaming() {
849         return telephonyCheckNetworkRoamingForSubscription(
850                              SubscriptionManager.getDefaultSubscriptionId());
851     }
852 
853     @Rpc(description = "Returns true if the device is in roaming state " +
854                        "for specified subscription ID")
telephonyCheckNetworkRoamingForSubscription( @pcParametername = "subId") Integer subId)855     public Boolean telephonyCheckNetworkRoamingForSubscription(
856                    @RpcParameter(name = "subId") Integer subId) {
857         return mTelephonyManager.isNetworkRoaming(subId);
858     }
859 
860     @Rpc(description = "Returns the unique device ID such as MEID or IMEI " +
861                        "for deault sim slot ID, null if unavailable")
telephonyGetDeviceId()862     public String telephonyGetDeviceId() {
863         return telephonyGetDeviceIdForSlotId(mTelephonyManager.getSlotIndex());
864     }
865 
866     @Rpc(description = "Returns the unique device ID such as MEID or IMEI for" +
867                        " specified slot ID, null if unavailable")
telephonyGetDeviceIdForSlotId( @pcParametername = "slotId") Integer slotId)868     public String telephonyGetDeviceIdForSlotId(
869                   @RpcParameter(name = "slotId")
870                   Integer slotId){
871         return mTelephonyManager.getDeviceId(slotId);
872     }
873 
874     @Rpc(description = "Returns the modem sw version, such as IMEI-SV;" +
875                        " null if unavailable")
telephonyGetDeviceSoftwareVersion()876     public String telephonyGetDeviceSoftwareVersion() {
877         return mTelephonyManager.getDeviceSoftwareVersion();
878     }
879 
880     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
881                        "for default subscription ID; null if unavailable")
telephonyGetLine1Number()882     public String telephonyGetLine1Number() {
883         return mTelephonyManager.getLine1Number();
884     }
885 
886     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
887                        "for specified subscription ID; null if unavailable")
telephonyGetLine1NumberForSubscription( @pcParametername = "subId") Integer subId)888     public String telephonyGetLine1NumberForSubscription(
889                   @RpcParameter(name = "subId") Integer subId) {
890         return mTelephonyManager.getLine1Number(subId);
891     }
892 
893     @Rpc(description = "Returns the Alpha Tag for the default subscription " +
894                        "ID; null if unavailable")
telephonyGetLine1AlphaTag()895     public String telephonyGetLine1AlphaTag() {
896         return mTelephonyManager.getLine1AlphaTag();
897     }
898 
899     @Rpc(description = "Returns the Alpha Tag for the specified subscription " +
900                        "ID; null if unavailable")
telephonyGetLine1AlphaTagForSubscription( @pcParametername = "subId") Integer subId)901     public String telephonyGetLine1AlphaTagForSubscription(
902                   @RpcParameter(name = "subId") Integer subId) {
903         return mTelephonyManager.getLine1AlphaTag(subId);
904     }
905 
906     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
907                        "for the default subscription")
telephonySetLine1Number( @pcParametername = "number") String number, @RpcOptional @RpcParameter(name = "alphaTag") String alphaTag)908     public Boolean telephonySetLine1Number(
909                 @RpcParameter(name = "number") String number,
910                 @RpcOptional
911                 @RpcParameter(name = "alphaTag") String alphaTag) {
912         return mTelephonyManager.setLine1NumberForDisplay(alphaTag, number);
913     }
914 
915     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
916                        "for the specified subscription")
telephonySetLine1NumberForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "number") String number, @RpcOptional @RpcParameter(name = "alphaTag") String alphaTag)917     public Boolean telephonySetLine1NumberForSubscription(
918                 @RpcParameter(name = "subId") Integer subId,
919                 @RpcParameter(name = "number") String number,
920                 @RpcOptional
921                 @RpcParameter(name = "alphaTag") String alphaTag) {
922         return mTelephonyManager.setLine1NumberForDisplay(subId, alphaTag, number);
923     }
924 
925     @Rpc(description = "Returns the neighboring cell information of the device.")
telephonyGetNeighboringCellInfo()926     public List<NeighboringCellInfo> telephonyGetNeighboringCellInfo() {
927         return mTelephonyManager.getNeighboringCellInfo();
928     }
929 
930     @Rpc(description =  "Sets the minimum reporting interval for CellInfo" +
931                         "0-as quickly as possible, 0x7FFFFFF-off")
telephonySetCellInfoListRate( @pcParametername = "rate") Integer rate )932     public void telephonySetCellInfoListRate(
933                 @RpcParameter(name = "rate") Integer rate
934             ) {
935         mTelephonyManager.setCellInfoListRate(rate);
936     }
937 
938     @Rpc(description = "Returns all observed cell information from all radios"+
939                        "on the device including the primary and neighboring cells")
telephonyGetAllCellInfo()940     public List<CellInfo> telephonyGetAllCellInfo() {
941         return mTelephonyManager.getAllCellInfo();
942     }
943 
944     @Rpc(description = "Returns True if cellular data is enabled for" +
945                        "default data subscription ID.")
telephonyIsDataEnabled()946     public Boolean telephonyIsDataEnabled() {
947         return telephonyIsDataEnabledForSubscription(
948                    SubscriptionManager.getDefaultDataSubscriptionId());
949     }
950 
951     @Rpc(description = "Returns True if data connection is enabled.")
telephonyIsDataEnabledForSubscription( @pcParametername = "subId") Integer subId)952     public Boolean telephonyIsDataEnabledForSubscription(
953                    @RpcParameter(name = "subId") Integer subId) {
954         return mTelephonyManager.getDataEnabled(subId);
955     }
956 
957     @Rpc(description = "Toggles data connection on /off for" +
958                        " default data subscription ID.")
telephonyToggleDataConnection( @pcParametername = "enabled") @pcOptional Boolean enabled)959     public void telephonyToggleDataConnection(
960                 @RpcParameter(name = "enabled")
961                 @RpcOptional Boolean enabled) {
962         telephonyToggleDataConnectionForSubscription(
963                          SubscriptionManager.getDefaultDataSubscriptionId(), enabled);
964     }
965 
966     @Rpc(description = "Toggles data connection on/off for" +
967                        " specified subscription ID")
telephonyToggleDataConnectionForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "enabled") @RpcOptional Boolean enabled)968     public void telephonyToggleDataConnectionForSubscription(
969                 @RpcParameter(name = "subId") Integer subId,
970                 @RpcParameter(name = "enabled")
971                 @RpcOptional Boolean enabled) {
972         if (enabled == null) {
973             enabled = !telephonyIsDataEnabledForSubscription(subId);
974         }
975         mTelephonyManager.setDataEnabled(subId, enabled);
976     }
977 
978     @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)979     public void telephonySetAPN(@RpcParameter(name = "name") final String name,
980                        @RpcParameter(name = "apn") final String apn,
981                        @RpcParameter(name = "type") @RpcOptional @RpcDefault("")
982                        final String type,
983                        @RpcParameter(name = "subId") @RpcOptional Integer subId) {
984         //TODO: b/26273471 Need to find out how to set APN for specific subId
985         Uri uri;
986         Cursor cursor;
987 
988         String mcc = "";
989         String mnc = "";
990 
991         String numeric = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
992         // MCC is first 3 chars and then in 2 - 3 chars of MNC
993         if (numeric != null && numeric.length() > 4) {
994             // Country code
995             mcc = numeric.substring(0, 3);
996             // Network code
997             mnc = numeric.substring(3);
998         }
999 
1000         uri = mService.getContentResolver().insert(
1001                 Telephony.Carriers.CONTENT_URI, new ContentValues());
1002         if (uri == null) {
1003             Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI);
1004             return;
1005         }
1006 
1007         cursor = mService.getContentResolver().query(uri, sProjection, null, null, null);
1008         cursor.moveToFirst();
1009 
1010         ContentValues values = new ContentValues();
1011 
1012         values.put(Telephony.Carriers.NAME, name);
1013         values.put(Telephony.Carriers.APN, apn);
1014         values.put(Telephony.Carriers.PROXY, "");
1015         values.put(Telephony.Carriers.PORT, "");
1016         values.put(Telephony.Carriers.MMSPROXY, "");
1017         values.put(Telephony.Carriers.MMSPORT, "");
1018         values.put(Telephony.Carriers.USER, "");
1019         values.put(Telephony.Carriers.SERVER, "");
1020         values.put(Telephony.Carriers.PASSWORD, "");
1021         values.put(Telephony.Carriers.MMSC, "");
1022         values.put(Telephony.Carriers.TYPE, type);
1023         values.put(Telephony.Carriers.MCC, mcc);
1024         values.put(Telephony.Carriers.MNC, mnc);
1025         values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
1026 
1027         int ret = mService.getContentResolver().update(uri, values, null, null);
1028         Log.d("after update " + ret);
1029         cursor.close();
1030 
1031         // Make this APN as the preferred
1032         String where = "name=\"" + name + "\"";
1033 
1034         Cursor c = mService.getContentResolver().query(
1035                 Telephony.Carriers.CONTENT_URI,
1036                 new String[] {
1037                         "_id", "name", "apn", "type"
1038                 }, where, null,
1039                 Telephony.Carriers.DEFAULT_SORT_ORDER);
1040         if (c != null) {
1041             c.moveToFirst();
1042             String key = c.getString(0);
1043             final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
1044             ContentResolver resolver = mService.getContentResolver();
1045             ContentValues prefAPN = new ContentValues();
1046             prefAPN.put("apn_id", key);
1047             resolver.update(Uri.parse(PREFERRED_APN_URI), prefAPN, null, null);
1048         }
1049         c.close();
1050     }
1051 
1052     @Rpc(description = "Returns the number of APNs defined")
telephonyGetNumberOfAPNs( @pcParametername = "subId") @pcOptional Integer subId)1053     public int telephonyGetNumberOfAPNs(
1054                @RpcParameter(name = "subId")
1055                @RpcOptional Integer subId) {
1056         //TODO: b/26273471 Need to find out how to get Number of APNs for specific subId
1057         int result = 0;
1058         String where = "numeric=\"" + android.os.SystemProperties.get(
1059                         TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\"";
1060 
1061         Cursor cursor = mService.getContentResolver().query(
1062                 Telephony.Carriers.CONTENT_URI,
1063                 new String[] {"_id", "name", "apn", "type"}, where, null,
1064                 Telephony.Carriers.DEFAULT_SORT_ORDER);
1065 
1066         if (cursor != null) {
1067             result = cursor.getCount();
1068         }
1069         cursor.close();
1070         return result;
1071     }
1072 
1073     @Rpc(description = "Returns the currently selected APN name")
telephonyGetSelectedAPN( @pcParametername = "subId") @pcOptional Integer subId)1074     public String telephonyGetSelectedAPN(
1075                   @RpcParameter(name = "subId")
1076                   @RpcOptional Integer subId) {
1077         //TODO: b/26273471 Need to find out how to get selected APN for specific subId
1078         String key = null;
1079         int ID_INDEX = 0;
1080         final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
1081 
1082         Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI),
1083                 new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
1084 
1085         if (cursor.getCount() > 0) {
1086             cursor.moveToFirst();
1087             key = cursor.getString(ID_INDEX);
1088         }
1089         cursor.close();
1090         return key;
1091     }
1092 
1093     @Rpc(description = "Returns the current data connection state")
telephonyGetDataConnectionState()1094     public String telephonyGetDataConnectionState() {
1095         return TelephonyUtils.getDataConnectionStateString(
1096             mTelephonyManager.getDataState());
1097     }
1098 
1099 
1100     @Rpc(description = "Returns Total Rx Bytes.")
getTotalRxBytes()1101     public long getTotalRxBytes() {
1102         return TrafficStats.getTotalRxBytes();
1103     }
1104 
1105     @Rpc(description = "Returns Total Tx Bytes.")
getTotalTxBytes()1106     public long getTotalTxBytes() {
1107         return TrafficStats.getTotalTxBytes();
1108     }
1109 
1110     @Rpc(description = "Returns Total Rx Packets.")
getTotalRxPackets()1111     public long getTotalRxPackets() {
1112         return TrafficStats.getTotalRxPackets();
1113     }
1114 
1115     @Rpc(description = "Returns Total Tx Packets.")
getTotalTxPackets()1116     public long getTotalTxPackets() {
1117         return TrafficStats.getTotalTxPackets();
1118     }
1119 
1120     @Rpc(description = "Returns Mobile Network Rx Bytes.")
getMobileRxBytes()1121     public long getMobileRxBytes() {
1122         return TrafficStats.getMobileRxBytes();
1123     }
1124 
1125     @Rpc(description = "Returns Mobile Network Tx Bytes.")
getMobileTxBytes()1126     public long getMobileTxBytes() {
1127         return TrafficStats.getMobileTxBytes();
1128     }
1129 
1130     @Rpc(description = "Returns Mobile Network Packets.")
getMobileRxPackets()1131     public long getMobileRxPackets() {
1132         return TrafficStats.getMobileRxPackets();
1133     }
1134 
1135     @Rpc(description = "Returns Mobile Network Packets.")
getMobileTxPackets()1136     public long getMobileTxPackets() {
1137         return TrafficStats.getMobileTxPackets();
1138     }
1139 
1140     @Rpc(description = "Returns a given UID Rx Bytes.")
getUidRxBytes(int uid)1141     public long getUidRxBytes(int uid) {
1142         return TrafficStats.getUidRxBytes(uid);
1143     }
1144 
1145     @Rpc(description = "Returns a given UID Rx Packets.")
getUidRxPackets(int uid)1146     public long getUidRxPackets(int uid) {
1147         return TrafficStats.getUidRxPackets(uid);
1148     }
1149 
1150     @Rpc(description = "Enables or Disables Video Calling()")
telephonyEnableVideoCalling( @pcParametername = "enable") boolean enable)1151     public void telephonyEnableVideoCalling(
1152             @RpcParameter(name = "enable") boolean enable) {
1153         mTelephonyManager.enableVideoCalling(enable);
1154     }
1155 
1156     @Rpc(description = "Returns a boolean of whether or not " +
1157             "video calling setting is enabled by the user")
telephonyIsVideoCallingEnabled()1158     public Boolean telephonyIsVideoCallingEnabled() {
1159         return mTelephonyManager.isVideoCallingEnabled();
1160     }
1161 
1162     @Rpc(description = "Returns a boolean of whether video calling is available for use")
telephonyIsVideoCallingAvailable()1163     public Boolean telephonyIsVideoCallingAvailable() {
1164         return mTelephonyManager.isVideoTelephonyAvailable();
1165     }
1166 
1167     @Rpc(description = "Returns a boolean of whether or not the device is ims registered")
telephonyIsImsRegistered()1168     public Boolean telephonyIsImsRegistered() {
1169         return mTelephonyManager.isImsRegistered();
1170     }
1171 
1172     @Rpc(description = "Returns a boolean of whether or not volte calling is available for use")
telephonyIsVolteAvailable()1173     public Boolean telephonyIsVolteAvailable() {
1174         return mTelephonyManager.isVolteAvailable();
1175     }
1176 
1177     @Rpc(description = "Returns a boolean of whether or not wifi calling is available for use")
telephonyIsWifiCallingAvailable()1178     public Boolean telephonyIsWifiCallingAvailable() {
1179         return mTelephonyManager.isWifiCallingAvailable();
1180     }
1181 
1182     @Rpc(description = "Returns the service state for default subscription ID")
telephonyGetServiceState()1183     public String telephonyGetServiceState() {
1184         //TODO: b/26273807 need to have framework API to get service state.
1185         return telephonyGetServiceStateForSubscription(
1186                                  SubscriptionManager.getDefaultSubscriptionId());
1187     }
1188 
1189     @Rpc(description = "Returns the service state for specified subscription ID")
telephonyGetServiceStateForSubscription( @pcParametername = "subId") Integer subId)1190     public String telephonyGetServiceStateForSubscription(
1191                   @RpcParameter(name = "subId") Integer subId) {
1192         //TODO: b/26273807 need to have framework API to get service state.
1193         return null;
1194     }
1195 
1196     @Rpc(description = "Returns the call state for default subscription ID")
telephonyGetCallState()1197     public String telephonyGetCallState() {
1198         return telephonyGetCallStateForSubscription(
1199                                SubscriptionManager.getDefaultSubscriptionId());
1200     }
1201 
1202     @Rpc(description = "Returns the call state for specified subscription ID")
telephonyGetCallStateForSubscription( @pcParametername = "subId") Integer subId)1203     public String telephonyGetCallStateForSubscription(
1204                   @RpcParameter(name = "subId") Integer subId) {
1205         return TelephonyUtils.getTelephonyCallStateString(
1206             mTelephonyManager.getCallState(subId));
1207     }
1208 
1209     @Rpc(description = "Returns current signal strength for default subscription ID.")
telephonyGetSignalStrength()1210     public SignalStrength telephonyGetSignalStrength() {
1211         return telephonyGetSignalStrengthForSubscription(
1212                                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
1213     }
1214 
1215     @Rpc(description = "Returns current signal strength for specified subscription ID.")
telephonyGetSignalStrengthForSubscription( @pcParametername = "subId") Integer subId)1216     public SignalStrength telephonyGetSignalStrengthForSubscription(
1217                     @RpcParameter(name = "subId") Integer subId) {
1218         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
1219         if(listener == null) {
1220             Log.e("Invalid subscription ID");
1221             return null;
1222         }
1223         return listener.mSignalStrengthChangeListener.mSignalStrengths;
1224     }
1225 
1226     @Rpc(description = "Returns the sim count.")
telephonyGetSimCount()1227     public int telephonyGetSimCount() {
1228         return mTelephonyManager.getSimCount();
1229     }
1230 
1231     /**
1232      * Get the list of Forbidden PLMNs stored on the USIM
1233      * profile of the SIM for the default subscription.
1234      */
1235     @Rpc(description = "Returns a list of forbidden PLMNs")
telephonyGetForbiddenPlmns()1236     public @Nullable List<String> telephonyGetForbiddenPlmns() {
1237         String[] fplmns = mTelephonyManager.getForbiddenPlmns(
1238                 SubscriptionManager.getDefaultSubscriptionId(),
1239                 TelephonyManager.APPTYPE_USIM);
1240 
1241         if (fplmns != null) {
1242             return Arrays.asList(fplmns);
1243         }
1244         return null;
1245     }
1246 
1247     /**
1248     * Read the value of a NV item.
1249     * @param itemId Integer the NV item id to be read.
1250     * @return the NV item value String.
1251     */
1252     @Rpc(description = "Returns the NV item as a String")
telephonyNvReadItem( @pcParametername = "itemId") Integer itemId)1253     public String telephonyNvReadItem(
1254                    @RpcParameter(name = "itemId") Integer itemId) {
1255         return mTelephonyManager.nvReadItem(itemId);
1256     }
1257 
1258     /**
1259     * Write a value to a NV item.
1260     * @param itemId Integer the NV item id to be written.
1261     * @param itemValue String the NV item value to be written.
1262     * @return true or false for successfully or unsuccessfully writing.
1263     */
1264     @Rpc(description = "Write the NV item by itemId and String value")
telephonyNvWriteItem( @pcParametername = "itemId") Integer itemId, @RpcParameter(name = "itemValue") String itemValue)1265     public Boolean telephonyNvWriteItem(
1266                    @RpcParameter(name = "itemId") Integer itemId,
1267                    @RpcParameter(name = "itemValue") String itemValue) {
1268         return mTelephonyManager.nvWriteItem(itemId, itemValue);
1269     }
1270 
getStateChangeListenerForSubscription( int subId, boolean createIfNeeded)1271     private StateChangeListener getStateChangeListenerForSubscription(
1272             int subId,
1273             boolean createIfNeeded) {
1274 
1275        if(mStateChangeListeners.get(subId) == null) {
1276             if(createIfNeeded == false) {
1277                 return null;
1278             }
1279 
1280             if(mSubscriptionManager.isValidSubscriptionId(subId) == false) {
1281                 Log.e("Cannot get listener for invalid/inactive subId");
1282                 return null;
1283             }
1284 
1285             mStateChangeListeners.put(subId, new StateChangeListener(subId));
1286         }
1287 
1288         return mStateChangeListeners.get(subId);
1289     }
1290 
1291     //FIXME: This whole class needs reworking. Why do we have separate listeners for everything?
1292     //We need one listener that overrides multiple methods.
1293     private final class StateChangeListener {
1294         public ServiceStateChangeListener mServiceStateChangeListener;
1295         public SignalStrengthChangeListener mSignalStrengthChangeListener;
1296         public CallStateChangeListener mCallStateChangeListener;
1297         public CellInfoChangeListener mCellInfoChangeListener;
1298         public DataConnectionStateChangeListener mDataConnectionStateChangeListener;
1299         public DataConnectionRealTimeInfoChangeListener mDataConnectionRTInfoChangeListener;
1300         public VoiceMailStateChangeListener mVoiceMailStateChangeListener;
1301 
StateChangeListener(int subId)1302         public StateChangeListener(int subId) {
1303             mServiceStateChangeListener =
1304                 new ServiceStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1305             mSignalStrengthChangeListener =
1306                 new SignalStrengthChangeListener(mEventFacade, subId, mService.getMainLooper());
1307             mDataConnectionStateChangeListener =
1308                 new DataConnectionStateChangeListener(
1309                         mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
1310             mCallStateChangeListener =
1311                 new CallStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1312             mCellInfoChangeListener =
1313                 new CellInfoChangeListener(mEventFacade, subId, mService.getMainLooper());
1314             mDataConnectionRTInfoChangeListener =
1315                 new DataConnectionRealTimeInfoChangeListener(
1316                         mEventFacade, subId, mService.getMainLooper());
1317             mVoiceMailStateChangeListener =
1318                 new VoiceMailStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1319         }
1320 
shutdown()1321         public void shutdown() {
1322             mTelephonyManager.listen(
1323                     mServiceStateChangeListener,
1324                     PhoneStateListener.LISTEN_NONE);
1325             mTelephonyManager.listen(
1326                     mSignalStrengthChangeListener,
1327                     PhoneStateListener.LISTEN_NONE);
1328             mTelephonyManager.listen(
1329                     mCallStateChangeListener,
1330                     PhoneStateListener.LISTEN_NONE);
1331             mTelephonyManager.listen(
1332                     mCellInfoChangeListener,
1333                     PhoneStateListener.LISTEN_NONE);
1334             mTelephonyManager.listen(
1335                     mDataConnectionStateChangeListener,
1336                     PhoneStateListener.LISTEN_NONE);
1337             mTelephonyManager.listen(
1338                     mDataConnectionRTInfoChangeListener,
1339                     PhoneStateListener.LISTEN_NONE);
1340             mTelephonyManager.listen(
1341                     mVoiceMailStateChangeListener,
1342                     PhoneStateListener.LISTEN_NONE);
1343         }
1344 
finalize()1345         protected void finalize() {
1346             try {
1347                 shutdown();
1348             } catch(Exception e) {}
1349         }
1350     }
1351 
1352     @Override
shutdown()1353     public void shutdown() {
1354         for(StateChangeListener listener : mStateChangeListeners.values()) {
1355             listener.shutdown();
1356         }
1357     }
1358 }
1359