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.TrafficStats;
26 import android.net.Uri;
27 import android.os.RemoteException;
28 import android.provider.Telephony;
29 import android.sysprop.TelephonyProperties;
30 import android.telephony.AvailableNetworkInfo;
31 import android.telephony.CellInfo;
32 import android.telephony.CellLocation;
33 import android.telephony.NeighboringCellInfo;
34 import android.telephony.PhoneStateListener;
35 import android.telephony.RadioAccessFamily;
36 import android.telephony.ServiceState;
37 import android.telephony.SignalStrength;
38 import android.telephony.SubscriptionManager;
39 import android.telephony.TelephonyManager;
40 import android.telephony.PinResult;
41 
42 import com.android.internal.telephony.RILConstants;
43 
44 import com.google.common.io.BaseEncoding;
45 import com.googlecode.android_scripting.Log;
46 import com.googlecode.android_scripting.facade.AndroidFacade;
47 import com.googlecode.android_scripting.facade.EventFacade;
48 import com.googlecode.android_scripting.facade.FacadeManager;
49 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
50                                                    .ActiveDataSubIdChangeListener;
51 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
52                                                    .CallStateChangeListener;
53 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
54                                                    .CellInfoChangeListener;
55 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
56                                                    .DataConnectionRealTimeInfoChangeListener;
57 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
58                                                    .DataConnectionStateChangeListener;
59 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
60                                                    .DisplayInfoStateChangeListener;
61 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
62                                                    .ServiceStateChangeListener;
63 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
64                                                    .SignalStrengthChangeListener;
65 import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners
66                                                    .VoiceMailStateChangeListener;
67 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
68 import com.googlecode.android_scripting.rpc.Rpc;
69 import com.googlecode.android_scripting.rpc.RpcDefault;
70 import com.googlecode.android_scripting.rpc.RpcOptional;
71 import com.googlecode.android_scripting.rpc.RpcParameter;
72 
73 import java.util.ArrayList;
74 import java.util.Arrays;
75 import java.util.HashMap;
76 import java.util.List;
77 import java.util.concurrent.Executor;
78 
79 /**
80  * Exposes TelephonyManager functionality.
81  *
82  */
83 public class TelephonyManagerFacade extends RpcReceiver {
84 
85     private final Service mService;
86     private final AndroidFacade mAndroidFacade;
87     private final EventFacade mEventFacade;
88     private final TelephonyManager mTelephonyManager;
89     private final SubscriptionManager mSubscriptionManager;
90     private List<AvailableNetworkInfo> availableNetworkList;
91     private HashMap<Integer, StateChangeListener> mStateChangeListeners =
92                              new HashMap<Integer, StateChangeListener>();
93 
94     private static final String[] sProjection = new String[] {
95             Telephony.Carriers._ID, // 0
96             Telephony.Carriers.NAME, // 1
97             Telephony.Carriers.APN, // 2
98             Telephony.Carriers.PROXY, // 3
99             Telephony.Carriers.PORT, // 4
100             Telephony.Carriers.USER, // 5
101             Telephony.Carriers.SERVER, // 6
102             Telephony.Carriers.PASSWORD, // 7
103             Telephony.Carriers.MMSC, // 8
104             Telephony.Carriers.MCC, // 9
105             Telephony.Carriers.MNC, // 10
106             Telephony.Carriers.NUMERIC, // 11
107             Telephony.Carriers.MMSPROXY,// 12
108             Telephony.Carriers.MMSPORT, // 13
109             Telephony.Carriers.AUTH_TYPE, // 14
110             Telephony.Carriers.TYPE, // 15
111             Telephony.Carriers.PROTOCOL, // 16
112             Telephony.Carriers.CARRIER_ENABLED, // 17
113             Telephony.Carriers.BEARER_BITMASK, // 18
114             Telephony.Carriers.ROAMING_PROTOCOL, // 19
115             Telephony.Carriers.MVNO_TYPE, // 20
116             Telephony.Carriers.MVNO_MATCH_DATA // 21
117     };
118 
TelephonyManagerFacade(FacadeManager manager)119     public TelephonyManagerFacade(FacadeManager manager) {
120         super(manager);
121         mService = manager.getService();
122         mTelephonyManager =
123                 (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE);
124         mAndroidFacade = manager.getReceiver(AndroidFacade.class);
125         mEventFacade = manager.getReceiver(EventFacade.class);
126         mSubscriptionManager = SubscriptionManager.from(mService);
127     }
128 
129     /**
130     * Reset TelephonyManager settings to factory default.
131     * @param subId the subriber id to be reset, use default id if not provided.
132     */
133     @Rpc(description = "Resets TelephonyManager settings to factory default.")
telephonyFactoryReset( @pcOptional @pcParametername = "subId") Integer subId)134     public void telephonyFactoryReset(
135             @RpcOptional @RpcParameter(name = "subId") Integer subId) {
136         if (subId == null) {
137             subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
138         }
139         mTelephonyManager.factoryReset(subId);
140     }
141 
142     /**
143     * Reset TelephonyManager settings to factory default.
144     * @param subId the subriber id to be reset, use default id if not provided.
145     */
146     @Rpc(description = "Resets Telephony and IMS settings to factory default.")
telephonyResetSettings( @pcOptional @pcParametername = "subId") Integer subId)147     public void telephonyResetSettings(
148             @RpcOptional @RpcParameter(name = "subId") Integer subId) {
149         if (subId == null) {
150             subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
151         }
152         mTelephonyManager.createForSubscriptionId(subId).resetSettings();
153     }
154 
155     @Rpc(description = "Set network preference.")
telephonySetPreferredNetworkTypes( @pcParametername = "nwPreference") String nwPreference)156     public boolean telephonySetPreferredNetworkTypes(
157         @RpcParameter(name = "nwPreference") String nwPreference) {
158         return telephonySetPreferredNetworkTypesForSubscription(nwPreference,
159                 SubscriptionManager.getDefaultSubscriptionId());
160     }
161 
162     @Rpc(description = "Set network preference for subscription.")
telephonySetPreferredNetworkTypesForSubscription( @pcParametername = "nwPreference") String nwPreference, @RpcParameter(name = "subId") Integer subId)163     public boolean telephonySetPreferredNetworkTypesForSubscription(
164             @RpcParameter(name = "nwPreference") String nwPreference,
165             @RpcParameter(name = "subId") Integer subId) {
166         int networkPreferenceInt = TelephonyUtils.getNetworkModeIntfromString(
167             nwPreference);
168         if (RILConstants.RIL_ERRNO_INVALID_RESPONSE != networkPreferenceInt) {
169             return mTelephonyManager.setPreferredNetworkType(
170                 subId, networkPreferenceInt);
171         } else {
172             return false;
173         }
174     }
175 
176     /**
177     * Set network selection mode to automatic for subscriber.
178     * @param subId the subriber id to be set.
179     */
180     @Rpc(description = "Set network selection mode to automatic for subscriber.")
telephonySetNetworkSelectionModeAutomaticForSubscription( @pcParametername = "subId") Integer subId)181     public void telephonySetNetworkSelectionModeAutomaticForSubscription(
182             @RpcParameter(name = "subId") Integer subId) {
183         mTelephonyManager.setNetworkSelectionModeAutomatic();
184     }
185 
186     @Rpc(description = "Get network preference.")
telephonyGetPreferredNetworkTypes()187     public String telephonyGetPreferredNetworkTypes() {
188         return telephonyGetPreferredNetworkTypesForSubscription(
189                 SubscriptionManager.getDefaultSubscriptionId());
190     }
191 
192     @Rpc(description = "Get network preference for subscription.")
telephonyGetPreferredNetworkTypesForSubscription( @pcParametername = "subId") Integer subId)193     public String telephonyGetPreferredNetworkTypesForSubscription(
194             @RpcParameter(name = "subId") Integer subId) {
195         int networkPreferenceInt =
196             RadioAccessFamily.getNetworkTypeFromRaf(
197                 (int) mTelephonyManager.createForSubscriptionId(
198                     subId).getAllowedNetworkTypesBitmask());
199         return TelephonyUtils.getNetworkModeStringfromInt(networkPreferenceInt);
200     }
201 
202     @Rpc(description = "Get current voice network type")
telephonyGetCurrentVoiceNetworkType()203     public String telephonyGetCurrentVoiceNetworkType() {
204         return telephonyGetCurrentVoiceNetworkTypeForSubscription(
205                 SubscriptionManager.getDefaultSubscriptionId());
206     }
207 
208     @Rpc(description = "Get current voice network type for subscription")
telephonyGetCurrentVoiceNetworkTypeForSubscription( @pcParametername = "subId") Integer subId)209     public String telephonyGetCurrentVoiceNetworkTypeForSubscription(
210             @RpcParameter(name = "subId") Integer subId) {
211         return TelephonyUtils.getNetworkTypeString(
212             mTelephonyManager.getVoiceNetworkType(subId));
213     }
214 
215     @Rpc(description = "Get current data network type")
telephonyGetCurrentDataNetworkType()216     public String telephonyGetCurrentDataNetworkType() {
217         return telephonyGetCurrentDataNetworkTypeForSubscription(
218                 SubscriptionManager.getDefaultSubscriptionId());
219     }
220 
221     @Rpc(description = "Get current data network type for subscription")
telephonyGetCurrentDataNetworkTypeForSubscription( @pcParametername = "subId") Integer subId)222     public String telephonyGetCurrentDataNetworkTypeForSubscription(
223             @RpcParameter(name = "subId") Integer subId) {
224         return TelephonyUtils.getNetworkTypeString(
225             mTelephonyManager.getDataNetworkType(subId));
226     }
227 
228     @Rpc(description = "Get if phone have voice capability")
telephonyIsVoiceCapable()229     public Boolean telephonyIsVoiceCapable() {
230         return mTelephonyManager.isVoiceCapable();
231     }
232 
233     @Rpc(description = "Get preferred network setting for " +
234                        "default subscription ID .Return value is integer.")
telephonyGetPreferredNetworkTypeInteger()235     public int telephonyGetPreferredNetworkTypeInteger() {
236         return telephonyGetPreferredNetworkTypeIntegerForSubscription(
237                                          SubscriptionManager.getDefaultSubscriptionId());
238     }
239 
240     @Rpc(description = "Get preferred network setting for " +
241                        "specified subscription ID .Return value is integer.")
telephonyGetPreferredNetworkTypeIntegerForSubscription( @pcParametername = "subId") Integer subId)242     public int telephonyGetPreferredNetworkTypeIntegerForSubscription(
243                @RpcParameter(name = "subId") Integer subId) {
244         return mTelephonyManager.getPreferredNetworkType(subId);
245     }
246 
247     @Rpc(description = "Starts tracking call state change" +
248                        "for default subscription ID.")
telephonyStartTrackingCallState()249     public Boolean telephonyStartTrackingCallState() {
250         return telephonyStartTrackingCallStateForSubscription(
251                               SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
252     }
253 
254     @Rpc(description = "Starts tracking call state change" +
255                        "for specified subscription ID.")
telephonyStartTrackingCallStateForSubscription( @pcParametername = "subId") Integer subId)256     public Boolean telephonyStartTrackingCallStateForSubscription(
257                 @RpcParameter(name = "subId") Integer subId) {
258         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
259         if(listener == null) {
260             Log.e("Invalid subscription ID");
261             return false;
262         }
263         mTelephonyManager.createForSubscriptionId(subId).listen(
264             listener.mCallStateChangeListener,
265             CallStateChangeListener.sListeningStates);
266         return true;
267     }
268 
269     @Rpc(description = "Starts tracking cell info change" +
270                        "for default subscription ID.")
telephonyStartTrackingCellInfoChange()271     public Boolean telephonyStartTrackingCellInfoChange() {
272         return telephonyStartTrackingCellInfoChangeForSubscription(
273                               SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
274     }
275 
276     @Rpc(description = "Starts tracking cell info change" +
277                        "for specified subscription ID.")
telephonyStartTrackingCellInfoChangeForSubscription( @pcParametername = "subId") Integer subId)278     public Boolean telephonyStartTrackingCellInfoChangeForSubscription(
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         mTelephonyManager.createForSubscriptionId(subId).listen(
286             listener.mCellInfoChangeListener,
287             PhoneStateListener.LISTEN_CELL_INFO);
288         return true;
289     }
290 
291     @Rpc(description = "Starts tracking active opportunistic data change" +
292                        "for default subscription ID.")
telephonyStartTrackingActiveDataChange()293     public Boolean telephonyStartTrackingActiveDataChange() {
294         return telephonyStartTrackingActiveDataChangeForSubscription(
295                               SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
296     }
297 
298     @Rpc(description = "Starts tracking active opportunistic data change" +
299                        "for specified subscription ID.")
telephonyStartTrackingActiveDataChangeForSubscription( @pcParametername = "subId") Integer subId)300     public Boolean telephonyStartTrackingActiveDataChangeForSubscription(
301                 @RpcParameter(name = "subId") Integer subId) {
302         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
303         if(listener == null) {
304             Log.e("Invalid subscription ID");
305             return false;
306         }
307         mTelephonyManager.createForSubscriptionId(subId).listen(
308             listener.mActiveDataSubIdChangeListener,
309             PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
310         return true;
311     }
312 
313     @Rpc(description = "Starts tracking display info change" +
314                        "for default subscription ID.")
telephonyStartTrackingDisplayInfoChange()315     public Boolean telephonyStartTrackingDisplayInfoChange() {
316         return telephonyStartTrackingDisplayInfoChangeForSubscription(
317                               SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
318     }
319 
320     @Rpc(description = "Starts tracking display info change" +
321                        "for specified subscription ID.")
telephonyStartTrackingDisplayInfoChangeForSubscription( @pcParametername = "subId") Integer subId)322     public Boolean telephonyStartTrackingDisplayInfoChangeForSubscription(
323                 @RpcParameter(name = "subId") Integer subId) {
324         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
325         if(listener == null) {
326             Log.e("Invalid subscription ID");
327             return false;
328         }
329         mTelephonyManager.createForSubscriptionId(subId).listen(
330             listener.mDisplayInfoStateChangeListener,
331             PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED);
332         return true;
333     }
334 
335     @Rpc(description = "Turn on/off precise listening on fore/background or" +
336                        " ringing calls for default voice subscription ID.")
telephonyAdjustPreciseCallStateListenLevel( @pcParametername = "type") String type, @RpcParameter(name = "listen") Boolean listen)337     public Boolean telephonyAdjustPreciseCallStateListenLevel(
338             @RpcParameter(name = "type") String type,
339             @RpcParameter(name = "listen") Boolean listen) {
340         return telephonyAdjustPreciseCallStateListenLevelForSubscription(type, listen,
341                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
342     }
343 
344     @Rpc(description = "Turn on/off precise listening on fore/background or" +
345                        " ringing calls for specified subscription ID.")
telephonyAdjustPreciseCallStateListenLevelForSubscription( @pcParametername = "type") String type, @RpcParameter(name = "listen") Boolean listen, @RpcParameter(name = "subId") Integer subId)346     public Boolean telephonyAdjustPreciseCallStateListenLevelForSubscription(
347             @RpcParameter(name = "type") String type,
348             @RpcParameter(name = "listen") Boolean listen,
349             @RpcParameter(name = "subId") Integer subId) {
350         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
351         if(listener == null) {
352             Log.e("Invalid subscription ID");
353             return false;
354         }
355 
356         if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND)) {
357             listener.mCallStateChangeListener.listenForeground = listen;
358         } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING)) {
359             listener.mCallStateChangeListener.listenRinging = listen;
360         } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND)) {
361             listener.mCallStateChangeListener.listenBackground = listen;
362         } else {
363             throw new IllegalArgumentException("Invalid listen level type " + type);
364         }
365 
366         return true;
367     }
368 
369     @Rpc(description = "Stops tracking cell info change " +
370             "for default voice subscription ID.")
telephonyStopTrackingCellInfoChange()371     public Boolean telephonyStopTrackingCellInfoChange() {
372         return telephonyStopTrackingCellInfoChangeForSubscription(
373                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
374     }
375 
376     @Rpc(description = "Stops tracking cell info change " +
377                        "for specified subscription ID.")
telephonyStopTrackingCellInfoChangeForSubscription( @pcParametername = "subId") Integer subId)378     public Boolean telephonyStopTrackingCellInfoChangeForSubscription(
379                    @RpcParameter(name = "subId") Integer subId) {
380         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
381         if(listener == null) {
382             Log.e("Invalid subscription ID");
383             return false;
384         }
385         mTelephonyManager.createForSubscriptionId(subId).listen(
386             listener.mCellInfoChangeListener,
387             PhoneStateListener.LISTEN_NONE);
388         return true;
389     }
390 
391     @Rpc(description = "Stops tracking active opportunistic data " +
392             "for default subscription ID.")
telephonyStopTrackingActiveDataChange()393     public Boolean telephonyStopTrackingActiveDataChange() {
394         return telephonyStopTrackingActiveDataChangeForSubscription(
395                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
396     }
397 
398     @Rpc(description = "Stops tracking active opportunistic data " +
399                        "for specified subscription ID.")
telephonyStopTrackingActiveDataChangeForSubscription( @pcParametername = "subId") Integer subId)400     public Boolean telephonyStopTrackingActiveDataChangeForSubscription(
401                    @RpcParameter(name = "subId") Integer subId) {
402         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
403         if(listener == null) {
404             Log.e("Invalid subscription ID");
405             return false;
406         }
407         mTelephonyManager.createForSubscriptionId(subId).listen(
408             listener.mActiveDataSubIdChangeListener,
409             PhoneStateListener.LISTEN_NONE);
410         return true;
411     }
412 
413     @Rpc(description = "Stops tracking display info change " +
414                        "for default subscription ID.")
telephonyStopTrackingDisplayInfoChange()415     public Boolean telephonyStopTrackingDisplayInfoChange() {
416         return telephonyStopTrackingDisplayInfoChangeForSubscription(
417                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
418     }
419 
420     @Rpc(description = "Stops tracking display info change " +
421                        "for specified subscription ID.")
telephonyStopTrackingDisplayInfoChangeForSubscription( @pcParametername = "subId") Integer subId)422     public Boolean telephonyStopTrackingDisplayInfoChangeForSubscription(
423                    @RpcParameter(name = "subId") Integer subId) {
424         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
425         if(listener == null) {
426             Log.e("Invalid subscription ID");
427             return false;
428         }
429         mTelephonyManager.createForSubscriptionId(subId).listen(
430             listener.mDisplayInfoStateChangeListener,
431             PhoneStateListener.LISTEN_NONE);
432         return true;
433     }
434 
435     @Rpc(description = "Stops tracking call state change " +
436             "for default voice subscription ID.")
telephonyStopTrackingCallStateChange()437     public Boolean telephonyStopTrackingCallStateChange() {
438         return telephonyStopTrackingCallStateChangeForSubscription(
439                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
440     }
441 
442     @Rpc(description = "Stops tracking call state change " +
443                        "for specified subscription ID.")
telephonyStopTrackingCallStateChangeForSubscription( @pcParametername = "subId") Integer subId)444     public Boolean telephonyStopTrackingCallStateChangeForSubscription(
445                    @RpcParameter(name = "subId") Integer subId) {
446         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
447         if(listener == null) {
448             Log.e("Invalid subscription ID");
449             return false;
450         }
451         mTelephonyManager.createForSubscriptionId(subId).listen(
452             listener.mCallStateChangeListener,
453             PhoneStateListener.LISTEN_NONE);
454         return true;
455     }
456 
457     @Rpc(description = "Starts tracking data connection real time info change" +
458                        "for default subscription ID.")
telephonyStartTrackingDataConnectionRTInfoChange()459     public Boolean telephonyStartTrackingDataConnectionRTInfoChange() {
460         return telephonyStartTrackingDataConnectionRTInfoChangeForSubscription(
461                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
462     }
463 
464     @Rpc(description = "Starts tracking data connection real time info change" +
465                        "for specified subscription ID.")
telephonyStartTrackingDataConnectionRTInfoChangeForSubscription( @pcParametername = "subId") Integer subId)466     public Boolean telephonyStartTrackingDataConnectionRTInfoChangeForSubscription(
467                    @RpcParameter(name = "subId") Integer subId) {
468         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
469         if(listener == null) {
470             Log.e("Invalid subscription ID");
471             return false;
472         }
473         mTelephonyManager.createForSubscriptionId(subId).listen(
474             listener.mDataConnectionRTInfoChangeListener,
475             DataConnectionRealTimeInfoChangeListener.sListeningStates);
476         return true;
477     }
478 
479     @Rpc(description = "Stops tracking data connection real time info change" +
480                        "for default subscription ID.")
telephonyStopTrackingDataConnectionRTInfoChange()481     public Boolean telephonyStopTrackingDataConnectionRTInfoChange() {
482         return telephonyStopTrackingDataConnectionRTInfoChangeForSubscription(
483                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
484     }
485 
486     @Rpc(description = "Stops tracking data connection real time info change" +
487                        "for specified subscription ID.")
telephonyStopTrackingDataConnectionRTInfoChangeForSubscription( @pcParametername = "subId") Integer subId)488     public Boolean telephonyStopTrackingDataConnectionRTInfoChangeForSubscription(
489                    @RpcParameter(name = "subId") Integer subId) {
490         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
491         if(listener == null) {
492             Log.e("Invalid subscription ID");
493             return false;
494         }
495         mTelephonyManager.createForSubscriptionId(subId).listen(
496             listener.mDataConnectionRTInfoChangeListener,
497             PhoneStateListener.LISTEN_NONE);
498         return true;
499     }
500 
501     @Rpc(description = "Starts tracking data connection state change" +
502                        "for default subscription ID..")
telephonyStartTrackingDataConnectionStateChange()503     public Boolean telephonyStartTrackingDataConnectionStateChange() {
504         return telephonyStartTrackingDataConnectionStateChangeForSubscription(
505                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
506     }
507 
508     @Rpc(description = "Starts tracking data connection state change" +
509                        "for specified subscription ID.")
telephonyStartTrackingDataConnectionStateChangeForSubscription( @pcParametername = "subId") Integer subId)510     public Boolean telephonyStartTrackingDataConnectionStateChangeForSubscription(
511                    @RpcParameter(name = "subId") Integer subId) {
512         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
513         if(listener == null) {
514             Log.e("Invalid subscription ID");
515             return false;
516         }
517         mTelephonyManager.createForSubscriptionId(subId).listen(
518             listener.mDataConnectionStateChangeListener,
519             DataConnectionStateChangeListener.sListeningStates);
520         return true;
521     }
522 
523     @Rpc(description = "Stops tracking data connection state change " +
524                        "for default subscription ID..")
telephonyStopTrackingDataConnectionStateChange()525     public Boolean telephonyStopTrackingDataConnectionStateChange() {
526         return telephonyStopTrackingDataConnectionStateChangeForSubscription(
527                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
528     }
529 
530     @Rpc(description = "Stops tracking data connection state change " +
531                        "for specified subscription ID..")
telephonyStopTrackingDataConnectionStateChangeForSubscription( @pcParametername = "subId") Integer subId)532     public Boolean telephonyStopTrackingDataConnectionStateChangeForSubscription(
533                    @RpcParameter(name = "subId") Integer subId) {
534         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
535         if(listener == null) {
536             Log.e("Invalid subscription ID");
537             return false;
538         }
539         mTelephonyManager.createForSubscriptionId(subId).listen(
540             listener.mDataConnectionStateChangeListener,
541             PhoneStateListener.LISTEN_NONE);
542         return true;
543     }
544 
545     @Rpc(description = "Starts tracking service state change " +
546                        "for default subscription ID.")
telephonyStartTrackingServiceStateChange()547     public Boolean telephonyStartTrackingServiceStateChange() {
548         return telephonyStartTrackingServiceStateChangeForSubscription(
549                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
550     }
551 
552     @Rpc(description = "Starts tracking service state change " +
553                        "for specified subscription ID.")
telephonyStartTrackingServiceStateChangeForSubscription( @pcParametername = "subId") Integer subId)554     public Boolean telephonyStartTrackingServiceStateChangeForSubscription(
555                    @RpcParameter(name = "subId") Integer subId) {
556         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
557         if(listener == null) {
558             Log.e("Invalid subscription ID");
559             return false;
560         }
561         mTelephonyManager.createForSubscriptionId(subId).listen(
562             listener.mServiceStateChangeListener,
563             ServiceStateChangeListener.sListeningStates);
564         return true;
565     }
566 
567     @Rpc(description = "Stops tracking service state change " +
568                        "for default subscription ID.")
telephonyStopTrackingServiceStateChange()569     public Boolean telephonyStopTrackingServiceStateChange() {
570         return telephonyStopTrackingServiceStateChangeForSubscription(
571                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
572     }
573 
574     @Rpc(description = "Stops tracking service state change " +
575                        "for specified subscription ID.")
telephonyStopTrackingServiceStateChangeForSubscription( @pcParametername = "subId") Integer subId)576     public Boolean telephonyStopTrackingServiceStateChangeForSubscription(
577                    @RpcParameter(name = "subId") Integer subId) {
578         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
579         if(listener == null) {
580             Log.e("Invalid subscription ID");
581             return false;
582         }
583         mTelephonyManager.createForSubscriptionId(subId).listen(
584             listener.mServiceStateChangeListener,
585             PhoneStateListener.LISTEN_NONE);
586             return true;
587     }
588 
589     @Rpc(description = "Starts tracking signal strength change " +
590                        "for default subscription ID.")
telephonyStartTrackingSignalStrengthChange()591     public Boolean telephonyStartTrackingSignalStrengthChange() {
592         return telephonyStartTrackingSignalStrengthChangeForSubscription(
593                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
594     }
595 
596     @Rpc(description = "Starts tracking signal strength change " +
597                        "for specified subscription ID.")
telephonyStartTrackingSignalStrengthChangeForSubscription( @pcParametername = "subId") Integer subId)598     public Boolean telephonyStartTrackingSignalStrengthChangeForSubscription(
599                    @RpcParameter(name = "subId") Integer subId) {
600         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
601         if(listener == null) {
602             Log.e("Invalid subscription ID");
603             return false;
604         }
605         mTelephonyManager.createForSubscriptionId(subId).listen(
606             listener.mSignalStrengthChangeListener,
607             SignalStrengthChangeListener.sListeningStates);
608         return true;
609     }
610 
611     @Rpc(description = "Stops tracking signal strength change " +
612                        "for default subscription ID.")
telephonyStopTrackingSignalStrengthChange()613     public Boolean telephonyStopTrackingSignalStrengthChange() {
614         return telephonyStopTrackingSignalStrengthChangeForSubscription(
615                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
616     }
617 
618     @Rpc(description = "Stops tracking signal strength change " +
619                        "for specified subscription ID.")
telephonyStopTrackingSignalStrengthChangeForSubscription( @pcParametername = "subId") Integer subId)620     public Boolean telephonyStopTrackingSignalStrengthChangeForSubscription(
621                    @RpcParameter(name = "subId") Integer subId) {
622         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
623         if(listener == null) {
624             Log.e("Invalid subscription ID");
625             return false;
626         }
627         mTelephonyManager.createForSubscriptionId(subId).listen(
628             listener.mSignalStrengthChangeListener,
629             PhoneStateListener.LISTEN_NONE);
630         return true;
631     }
632 
633     @Rpc(description = "Starts tracking voice mail state change " +
634                        "for default subscription ID.")
telephonyStartTrackingVoiceMailStateChange()635     public Boolean telephonyStartTrackingVoiceMailStateChange() {
636         return telephonyStartTrackingVoiceMailStateChangeForSubscription(
637                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
638     }
639 
640     @Rpc(description = "Starts tracking voice mail state change " +
641                        "for specified subscription ID.")
telephonyStartTrackingVoiceMailStateChangeForSubscription( @pcParametername = "subId") Integer subId)642     public Boolean telephonyStartTrackingVoiceMailStateChangeForSubscription(
643                    @RpcParameter(name = "subId") Integer subId) {
644         StateChangeListener listener = getStateChangeListenerForSubscription(subId, true);
645         if(listener == null) {
646             Log.e("Invalid subscription ID");
647             return false;
648         }
649         mTelephonyManager.createForSubscriptionId(subId).listen(
650             listener.mVoiceMailStateChangeListener,
651             VoiceMailStateChangeListener.sListeningStates);
652         return true;
653     }
654 
655     @Rpc(description = "Stops tracking voice mail state change " +
656                        "for default subscription ID.")
telephonyStopTrackingVoiceMailStateChange()657     public Boolean telephonyStopTrackingVoiceMailStateChange() {
658         return telephonyStopTrackingVoiceMailStateChangeForSubscription(
659                                  SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
660     }
661 
662     @Rpc(description = "Stops tracking voice mail state change " +
663                        "for specified subscription ID.")
telephonyStopTrackingVoiceMailStateChangeForSubscription( @pcParametername = "subId") Integer subId)664     public Boolean telephonyStopTrackingVoiceMailStateChangeForSubscription(
665                    @RpcParameter(name = "subId") Integer subId) {
666         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
667         if(listener == null) {
668             Log.e("Invalid subscription ID");
669             return false;
670         }
671         mTelephonyManager.createForSubscriptionId(subId).listen(
672             listener.mVoiceMailStateChangeListener,
673             PhoneStateListener.LISTEN_NONE);
674         return true;
675     }
676 
677     @Rpc(description = "Answers an incoming ringing call.")
telephonyAnswerCall()678     public void telephonyAnswerCall() throws RemoteException {
679         mTelephonyManager.silenceRinger();
680         mTelephonyManager.answerRingingCall();
681     }
682 
683     @Rpc(description = "Returns the radio on/off state.")
telephonyIsRadioOn()684     public Boolean telephonyIsRadioOn() {
685         return mTelephonyManager.isRadioOn();
686     }
687 
688     @Rpc(description = "Sets the radio to an on/off state.")
telephonySetRadioPower( @pcParametername = "turnOn") boolean turnOn)689     public Boolean telephonySetRadioPower(
690         @RpcParameter(name = "turnOn") boolean turnOn) {
691         return mTelephonyManager.setRadioPower(turnOn);
692     }
693 
694     @Rpc(description = "Returns the current cell location.")
telephonyGetCellLocation()695     public CellLocation telephonyGetCellLocation() {
696         return mTelephonyManager.getCellLocation();
697     }
698 
699     /**
700      *  Returns carrier id of the current subscription.
701      * @return Carrier id of the current subscription.
702      */
703     @Rpc(description = "Returns the numeric CarrierId for current subscription")
telephonyGetSimCarrierId()704     public int telephonyGetSimCarrierId() {
705         return mTelephonyManager.getSimCarrierId();
706     }
707 
708     /**
709      *  Returns carrier id name of the current subscription.
710      * @return Carrier id name of the current subscription
711      */
712     @Rpc(description = "Returns Carrier Name for current subscription")
telephonyGetSimCarrierIdName()713     public CharSequence telephonyGetSimCarrierIdName() {
714         return mTelephonyManager.getSimCarrierIdName();
715     }
716 
717     @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator." +
718                        "for default subscription ID")
telephonyGetNetworkOperator()719     public String telephonyGetNetworkOperator() {
720         return telephonyGetNetworkOperatorForSubscription(
721                         SubscriptionManager.getDefaultSubscriptionId());
722     }
723 
724     @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator" +
725                        "for specified subscription ID.")
telephonyGetNetworkOperatorForSubscription( @pcParametername = "subId") Integer subId)726     public String telephonyGetNetworkOperatorForSubscription(
727                   @RpcParameter(name = "subId") Integer subId) {
728         return mTelephonyManager.getNetworkOperator(subId);
729     }
730 
731     @Rpc(description = "Returns the alphabetic name of current registered operator" +
732                        "for specified subscription ID.")
telephonyGetNetworkOperatorName()733     public String telephonyGetNetworkOperatorName() {
734         return telephonyGetNetworkOperatorNameForSubscription(
735                         SubscriptionManager.getDefaultSubscriptionId());
736     }
737 
738     @Rpc(description = "Returns the alphabetic name of registered operator " +
739                        "for specified subscription ID.")
telephonyGetNetworkOperatorNameForSubscription( @pcParametername = "subId") Integer subId)740     public String telephonyGetNetworkOperatorNameForSubscription(
741                   @RpcParameter(name = "subId") Integer subId) {
742         return mTelephonyManager.getNetworkOperatorName(subId);
743     }
744 
745     @Rpc(description = "Returns the current RAT in use on the device.+" +
746                        "for default subscription ID")
telephonyGetNetworkType()747     public String telephonyGetNetworkType() {
748 
749         Log.d("sl4a:getNetworkType() is deprecated!" +
750                 "Please use getVoiceNetworkType()" +
751                 " or getDataNetworkTpe()");
752 
753         return telephonyGetNetworkTypeForSubscription(
754                        SubscriptionManager.getDefaultSubscriptionId());
755     }
756 
757     @Rpc(description = "Returns the current RAT in use on the device" +
758             " for a given Subscription.")
telephonyGetNetworkTypeForSubscription( @pcParametername = "subId") Integer subId)759     public String telephonyGetNetworkTypeForSubscription(
760                   @RpcParameter(name = "subId") Integer subId) {
761 
762         Log.d("sl4a:getNetworkTypeForSubscriber() is deprecated!" +
763                 "Please use getVoiceNetworkType()" +
764                 " or getDataNetworkTpe()");
765 
766         return TelephonyUtils.getNetworkTypeString(
767             mTelephonyManager.getNetworkType(subId));
768     }
769 
770     @Rpc(description = "Returns the current voice RAT for" +
771             " the default voice subscription.")
telephonyGetVoiceNetworkType()772     public String telephonyGetVoiceNetworkType() {
773         return telephonyGetVoiceNetworkTypeForSubscription(
774                          SubscriptionManager.getDefaultVoiceSubscriptionId());
775     }
776 
777     @Rpc(description = "Returns the current voice RAT for" +
778             " the specified voice subscription.")
telephonyGetVoiceNetworkTypeForSubscription( @pcParametername = "subId") Integer subId)779     public String telephonyGetVoiceNetworkTypeForSubscription(
780                   @RpcParameter(name = "subId") Integer subId) {
781         return TelephonyUtils.getNetworkTypeString(
782             mTelephonyManager.getVoiceNetworkType(subId));
783     }
784 
785     @Rpc(description = "Returns the current data RAT for" +
786             " the defaut data subscription")
telephonyGetDataNetworkType()787     public String telephonyGetDataNetworkType() {
788         return telephonyGetDataNetworkTypeForSubscription(
789                          SubscriptionManager.getDefaultDataSubscriptionId());
790     }
791 
792     @Rpc(description = "Returns the current data RAT for" +
793             " the specified data subscription")
telephonyGetDataNetworkTypeForSubscription( @pcParametername = "subId") Integer subId)794     public String telephonyGetDataNetworkTypeForSubscription(
795                   @RpcParameter(name = "subId") Integer subId) {
796         return TelephonyUtils.getNetworkTypeString(
797             mTelephonyManager.getDataNetworkType(subId));
798     }
799 
800     @Rpc(description = "Returns the device phone type.")
telephonyGetPhoneType()801     public String telephonyGetPhoneType() {
802         return TelephonyUtils.getPhoneTypeString(
803             mTelephonyManager.getPhoneType());
804     }
805 
806     @Rpc(description = "Return if setAlwaysAllowMMSData is set correctly")
telephonySetAlwaysAllowMmsData( @pcParametername = "subId") Integer subId, @RpcParameter(name = "alwaysAllow") Boolean alwaysAllow)807     public boolean telephonySetAlwaysAllowMmsData(
808             @RpcParameter(name = "subId") Integer subId,
809             @RpcParameter(name = "alwaysAllow") Boolean alwaysAllow) {
810         boolean wasAlwaysAllow = mTelephonyManager.isMobileDataPolicyEnabled(
811                 TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED);
812         mTelephonyManager.createForSubscriptionId(subId)
813                 .setMobileDataPolicyEnabled(
814                         TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, alwaysAllow);
815         return wasAlwaysAllow == alwaysAllow;
816     }
817 
818     /**
819     * Sets Data Roaming flag for a particular sub Id
820     * @param subId the subscriber id
821     * @param isEnabled can you set to true or false
822     */
823     @Rpc(description = "Sets data roaming for a sub Id")
telephonySetDataRoamingEnabled( @pcParametername = "subId") Integer subId, @RpcParameter(name = "isEnabled") Boolean isEnabled)824     public void telephonySetDataRoamingEnabled(
825             @RpcParameter(name = "subId") Integer subId,
826             @RpcParameter(name = "isEnabled") Boolean isEnabled) {
827         mTelephonyManager.createForSubscriptionId(subId).setDataRoamingEnabled(isEnabled);
828     }
829 
830     @Rpc(description = "Returns preferred opportunistic data subscription Id")
telephonyGetPreferredOpportunisticDataSubscription()831     public Integer telephonyGetPreferredOpportunisticDataSubscription() {
832         return mTelephonyManager.getPreferredOpportunisticDataSubscription();
833     }
834 
835     @Rpc(description = "Sets preferred opportunistic data subscription Id")
telephonySetPreferredOpportunisticDataSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "needValidation") Boolean needValidation)836     public void telephonySetPreferredOpportunisticDataSubscription(
837             @RpcParameter(name = "subId") Integer subId,
838             @RpcParameter(name = "needValidation") Boolean needValidation) {
839         mTelephonyManager.setPreferredOpportunisticDataSubscription(
840                    subId, needValidation, null, null);
841     }
842 
843     @Rpc(description = "Updates Available Networks")
telephonyUpdateAvailableNetworks( @pcParametername = "subId") Integer subId)844     public void telephonyUpdateAvailableNetworks(
845             @RpcParameter(name = "subId") Integer subId) {
846 
847         availableNetworkList = new ArrayList<>();
848         List<String> mccmmc = new ArrayList<String>();
849         List<Integer> bands = new ArrayList<Integer>();
850 
851         availableNetworkList.add(
852             new AvailableNetworkInfo(
853                 subId,
854                 AvailableNetworkInfo.PRIORITY_HIGH,
855                 mccmmc,
856                 bands));
857 
858         mTelephonyManager.updateAvailableNetworks(availableNetworkList, null, null);
859     }
860 
861     /**
862     * Get device phone type for a subscription.
863     * @param subId the subscriber id
864     * @return the phone type string for the subscriber.
865     */
866     @Rpc(description = "Returns the device phone type for a subscription.")
telephonyGetPhoneTypeForSubscription( @pcParametername = "subId") Integer subId)867     public String telephonyGetPhoneTypeForSubscription(
868                   @RpcParameter(name = "subId") Integer subId) {
869         return TelephonyUtils.getPhoneTypeString(
870             mTelephonyManager.getCurrentPhoneType(subId));
871     }
872 
873     @Rpc(description = "Returns the MCC for default subscription ID")
telephonyGetSimCountryIso()874     public String telephonyGetSimCountryIso() {
875          return telephonyGetSimCountryIsoForSubscription(
876                       SubscriptionManager.getDefaultSubscriptionId());
877     }
878 
879     @Rpc(description = "Returns the MCC for specified subscription ID")
telephonyGetSimCountryIsoForSubscription( @pcParametername = "subId") Integer subId)880     public String telephonyGetSimCountryIsoForSubscription(
881                   @RpcParameter(name = "subId") Integer subId) {
882         return mTelephonyManager.getSimCountryIso(subId);
883     }
884 
885     @Rpc(description = "Returns the MCC+MNC for default subscription ID")
telephonyGetSimOperator()886     public String telephonyGetSimOperator() {
887         return telephonyGetSimOperatorForSubscription(
888                   SubscriptionManager.getDefaultSubscriptionId());
889     }
890 
891     @Rpc(description = "Returns the MCC+MNC for specified subscription ID")
telephonyGetSimOperatorForSubscription( @pcParametername = "subId") Integer subId)892     public String telephonyGetSimOperatorForSubscription(
893                   @RpcParameter(name = "subId") Integer subId) {
894         return mTelephonyManager.getSimOperator(subId);
895     }
896 
897     @Rpc(description = "Returns the Service Provider Name (SPN)" +
898                        "for default subscription ID")
telephonyGetSimOperatorName()899     public String telephonyGetSimOperatorName() {
900         return telephonyGetSimOperatorNameForSubscription(
901                   SubscriptionManager.getDefaultSubscriptionId());
902     }
903 
904     @Rpc(description = "Returns the Service Provider Name (SPN)" +
905                        " for specified subscription ID.")
telephonyGetSimOperatorNameForSubscription( @pcParametername = "subId") Integer subId)906     public String telephonyGetSimOperatorNameForSubscription(
907                   @RpcParameter(name = "subId") Integer subId) {
908         return mTelephonyManager.getSimOperatorName(subId);
909     }
910 
911     @Rpc(description = "Returns the serial number of the SIM for " +
912                        "default subscription ID, or Null if unavailable")
telephonyGetSimSerialNumber()913     public String telephonyGetSimSerialNumber() {
914         return telephonyGetSimSerialNumberForSubscription(
915                   SubscriptionManager.getDefaultSubscriptionId());
916     }
917 
918     @Rpc(description = "Returns the serial number of the SIM for " +
919                        "specified subscription ID, or Null if unavailable")
telephonyGetSimSerialNumberForSubscription( @pcParametername = "subId") Integer subId)920     public String telephonyGetSimSerialNumberForSubscription(
921                   @RpcParameter(name = "subId") Integer subId) {
922         return mTelephonyManager.getSimSerialNumber(subId);
923     }
924 
925     /**
926      * Set SIM card power state.
927      *
928      * @param state  State of SIM (0: power down, 1: power up, 2: pass through)
929      **/
930     @Rpc(description = "Set the SIM power state of the SIM card for default slot ID.")
telephonySetSimPowerState( @pcParametername = "state") Integer state)931     public void telephonySetSimPowerState(
932                   @RpcParameter(name = "state") Integer state) {
933         mTelephonyManager.setSimPowerState(state);
934     }
935 
936     /**
937      * Set SIM card power state.
938      *
939      * @param slotId SIM slot id
940      * @param state  State of SIM (0: power down, 1: power up, 2: pass through)
941      **/
942     @Rpc(description = "Set the SIM power state for SIM slot slotId.")
telephonySetSimStateForSlotId( @pcParametername = "slotId") Integer slotId, @RpcParameter(name = "state") Integer state)943     public void telephonySetSimStateForSlotId(
944                   @RpcParameter(name = "slotId") Integer slotId,
945                   @RpcParameter(name = "state") Integer state) {
946         mTelephonyManager.setSimPowerStateForSlot(slotId, state);
947     }
948 
949     @Rpc(description = "Returns the state of the SIM card for default slot ID.")
telephonyGetSimState()950     public String telephonyGetSimState() {
951         return telephonyGetSimStateForSlotId(
952                   mTelephonyManager.getSlotIndex());
953     }
954 
955     @Rpc(description = "Returns the state of the SIM card for specified slot ID.")
telephonyGetSimStateForSlotId( @pcParametername = "slotId") Integer slotId)956     public String telephonyGetSimStateForSlotId(
957                   @RpcParameter(name = "slotId") Integer slotId) {
958         return TelephonyUtils.getSimStateString(
959             mTelephonyManager.getSimState(slotId));
960     }
961 
962     /**
963      * Switch device mode multisim
964      *
965      * @param numOfSims (1: single sim, 2: multi sim)
966      **/
967     @Rpc(description = "Switch configs to enable multi-sim or switch back to single-sim")
telephonySwitchMultiSimConfig( @pcParametername = "numOfSims") Integer numOfSims)968     public void telephonySwitchMultiSimConfig(
969             @RpcParameter(name = "numOfSims")
970             Integer numOfSims) {
971         mTelephonyManager.switchMultiSimConfig(numOfSims.intValue());
972     }
973 
974     /**
975      * Gets device mode multisim
976      *
977      * @return phoneCount (1-single sim, 2-dual sim, 3-tri sim)
978      **/
979     @Rpc(description = "Returns if device is in Single, Dual, Tri SIM Mode")
telephonyGetPhoneCount()980     public Integer telephonyGetPhoneCount() {
981         return mTelephonyManager.getPhoneCount();
982     }
983 
984     @Rpc(description = "Get Authentication Challenge Response from a " +
985             "given SIM Application")
telephonyGetIccSimChallengeResponse( @pcParametername = "appType") Integer appType, @RpcParameter(name = "authType") Integer authType, @RpcParameter(name = "hexChallenge") String hexChallenge)986     public String telephonyGetIccSimChallengeResponse(
987             @RpcParameter(name = "appType") Integer appType,
988             @RpcParameter(name = "authType") Integer authType,
989             @RpcParameter(name = "hexChallenge") String hexChallenge) {
990         return telephonyGetIccSimChallengeResponseForSubscription(
991                 SubscriptionManager.getDefaultSubscriptionId(), appType, authType, hexChallenge);
992     }
993 
994     @Rpc(description = "Get Authentication Challenge Response from a " +
995             "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)996     public String telephonyGetIccSimChallengeResponseForSubscription(
997             @RpcParameter(name = "subId") Integer subId,
998             @RpcParameter(name = "appType") Integer appType,
999             @RpcParameter(name = "authType") Integer authType,
1000             @RpcParameter(name = "hexChallenge") String hexChallenge) {
1001 
1002         try {
1003             String b64Data = BaseEncoding.base64().encode(BaseEncoding.base16().decode(hexChallenge));
1004             String b64Result = mTelephonyManager.getIccAuthentication(subId, appType, authType, b64Data);
1005             return (b64Result != null)
1006                     ? BaseEncoding.base16().encode(BaseEncoding.base64().decode(b64Result)) : null;
1007         } catch(Exception e) {
1008             Log.e("Exception in phoneGetIccSimChallengeResponseForSubscription" + e.toString());
1009             return null;
1010         }
1011     }
1012 
1013     /**
1014      * Check if the Subscription ID is valid.
1015      * @param subId the subscription ID
1016      * @return    {true} if subId is valid, {false}  otherwise.
1017      */
1018     @Rpc(description = "Check if the Subscription ID is valid.")
telephonyIsSubscriptionIdValid( @pcParametername = "subId") Integer subId)1019     public boolean telephonyIsSubscriptionIdValid(
1020         @RpcParameter(name = "subId") Integer subId){
1021         if (subId == null || !SubscriptionManager.isValidSubscriptionId(subId)) {
1022             Log.e("Invalid or null subscription ID");
1023             return false;
1024         }
1025         return true;
1026     }
1027 
1028     /**
1029     * Supply the puk code and pin for locked SIM.
1030     * @param puk the puk code string
1031     * @param pin the puk pin string
1032     * @return    true or false for supplying the puk code and pin successfully or unsuccessfully.
1033     */
1034     @Rpc(description = "Supply Puk and Pin for locked SIM.")
telephonySupplyPuk( @pcParametername = "puk") String puk, @RpcParameter(name = "pin") String pin)1035     public boolean telephonySupplyPuk(
1036             @RpcParameter(name = "puk") String puk,
1037             @RpcParameter(name = "pin") String pin) {
1038         return mTelephonyManager.supplyPuk(puk, pin);
1039     }
1040 
1041     /**
1042      * Supply the puk code and pin for locked SIM of specified subscription ID.
1043      * @param subId the subscription ID
1044      * @param puk the puk code string
1045      * @param pin the puk pin string
1046      * @return    true or false for supplying the puk code and pin successfully or unsuccessfully.
1047      */
1048     @Rpc(description = "Supply Puk and Pin for locked SIM " +
1049         "for specified subscription ID.")
telephonySupplyPukForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "puk") String puk, @RpcParameter(name = "pin") String pin)1050     public boolean telephonySupplyPukForSubscription(
1051         @RpcParameter(name = "subId") Integer subId,
1052         @RpcParameter(name = "puk") String puk,
1053         @RpcParameter(name = "pin") String pin) {
1054         if (!telephonyIsSubscriptionIdValid(subId)) {
1055             return false;
1056         }
1057         return mTelephonyManager.createForSubscriptionId(subId).supplyPuk(puk, pin);
1058     }
1059 
1060     /**
1061     * Supply pin for locked SIM.
1062     * @param pin the puk pin string
1063     * @return    true or false for supplying the pin successfully or unsuccessfully.
1064     */
1065     @Rpc(description = "Supply Pin for locked SIM.")
telephonySupplyPin( @pcParametername = "pin") String pin)1066     public boolean telephonySupplyPin(
1067             @RpcParameter(name = "pin") String pin) {
1068         return mTelephonyManager.supplyPin(pin);
1069     }
1070 
1071     /**
1072      * Supply pin for locked SIM of specified subscription ID.
1073      * @param subId the subscription ID
1074      * @param pin the puk pin string
1075      * @return    true or false for supplying the pin successfully or unsuccessfully.
1076      */
1077     @Rpc(description = "Supply Pin for locked SIM " +
1078         "for specified subscription ID.")
telephonySupplyPinForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "pin") String pin)1079     public boolean telephonySupplyPinForSubscription(
1080         @RpcParameter(name = "subId") Integer subId,
1081         @RpcParameter(name = "pin") String pin) {
1082         if (!telephonyIsSubscriptionIdValid(subId)) {
1083             return false;
1084         }
1085         return mTelephonyManager.createForSubscriptionId(subId).supplyPin(pin);
1086     }
1087 
1088     /**
1089      * Enable or disable the ICC PIN lock of specified subscription ID.
1090      * @param subId the subscription ID
1091      * @param enabled "true" for enable, "false" for disable.
1092      * @param pin needed to enable or disable the ICC PIN lock
1093      * @return    true or false for enable/disable the pin successfully or unsuccessfully.
1094      */
1095     @Rpc(description = "Enable or disable the ICC PIN lock " +
1096         "for specified subscription ID.")
telephonySetIccLockEnabledForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "enabled") Boolean enabled, @RpcParameter(name = "pin") String pin)1097     public boolean telephonySetIccLockEnabledForSubscription(
1098         @RpcParameter(name = "subId") Integer subId,
1099         @RpcParameter(name = "enabled") Boolean enabled,
1100         @RpcParameter(name = "pin") String pin) {
1101         if (!telephonyIsSubscriptionIdValid(subId)) {
1102             return false;
1103         }
1104         PinResult result= mTelephonyManager.createForSubscriptionId(subId).setIccLockEnabled(enabled,pin);
1105         if(result != null) {
1106             return (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS);
1107         }
1108         return false;
1109     }
1110 
1111     /**
1112      * Check whether ICC PIN lock is enabled.
1113      * @param subId the subscription ID
1114      * @return   true or false for changing the ICC lock PIN successfully or unsuccessfully.
1115      */
1116     @Rpc(description = "Check whether ICC PIN lock is enabled " +
1117         "for specified subscription ID.")
telephonyIsIccLockEnabled( @pcParametername = "subId") Integer subId)1118     public boolean telephonyIsIccLockEnabled(
1119         @RpcParameter(name = "subId") Integer subId) {
1120         if (!telephonyIsSubscriptionIdValid(subId)) {
1121             return false;
1122         }
1123         return mTelephonyManager.createForSubscriptionId(subId).isIccLockEnabled();
1124     }
1125 
1126     /**
1127      * Change the ICC lock PIN of specified subscription ID.
1128      * @param subId the subscription ID
1129      * @param oldPin is the old PIN.
1130      * @param newPin is the new PIN.
1131      * @return    true or false for changing the ICC lock PIN successfully or unsuccessfully.
1132      */
1133     @Rpc(description = "Change the ICC lock PIN " +
1134         "for specified subscription ID.")
telephonyChangeIccLockPinForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "oldPin") String oldPin, @RpcParameter(name = "newPin") String newPin)1135     public boolean telephonyChangeIccLockPinForSubscription(
1136         @RpcParameter(name = "subId") Integer subId,
1137         @RpcParameter(name = "oldPin")  String oldPin,
1138         @RpcParameter(name = "newPin")  String newPin) {
1139         if (!telephonyIsSubscriptionIdValid(subId)) {
1140             return false;
1141         }
1142         PinResult result= mTelephonyManager.createForSubscriptionId(subId).changeIccLockPin(oldPin,newPin);
1143         if(result != null) {
1144             return (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS);
1145         }
1146         return false;
1147     }
1148 
1149     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
1150             "for default subscription ID, or null if unavailable")
telephonyGetSubscriberId()1151     public String telephonyGetSubscriberId() {
1152         return telephonyGetSubscriberIdForSubscription(
1153                 SubscriptionManager.getDefaultSubscriptionId());
1154     }
1155 
1156     @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " +
1157                        "for specified subscription ID, or null if unavailable")
telephonyGetSubscriberIdForSubscription( @pcParametername = "subId") Integer subId)1158     public String telephonyGetSubscriberIdForSubscription(
1159                   @RpcParameter(name = "subId") Integer subId) {
1160         return mTelephonyManager.getSubscriberId(subId);
1161     }
1162 
1163     @Rpc(description = "Retrieves the alphabetic id associated with the" +
1164                        " voice mail number for default subscription ID.")
telephonyGetVoiceMailAlphaTag()1165     public String telephonyGetVoiceMailAlphaTag() {
1166         return telephonyGetVoiceMailAlphaTagForSubscription(
1167                    SubscriptionManager.getDefaultSubscriptionId());
1168     }
1169 
1170 
1171     @Rpc(description = "Retrieves the alphabetic id associated with the " +
1172                        "voice mail number for specified subscription ID.")
telephonyGetVoiceMailAlphaTagForSubscription( @pcParametername = "subId") Integer subId)1173     public String telephonyGetVoiceMailAlphaTagForSubscription(
1174                   @RpcParameter(name = "subId") Integer subId) {
1175         return mTelephonyManager.getVoiceMailAlphaTag(subId);
1176     }
1177 
1178     @Rpc(description = "Returns the voice mail number " +
1179                        "for default subscription ID; null if unavailable.")
telephonyGetVoiceMailNumber()1180     public String telephonyGetVoiceMailNumber() {
1181         return telephonyGetVoiceMailNumberForSubscription(
1182                    SubscriptionManager.getDefaultSubscriptionId());
1183     }
1184 
1185     @Rpc(description = "Returns the voice mail number " +
1186                         "for specified subscription ID; null if unavailable.")
telephonyGetVoiceMailNumberForSubscription( @pcParametername = "subId") Integer subId)1187     public String telephonyGetVoiceMailNumberForSubscription(
1188                   @RpcParameter(name = "subId") Integer subId) {
1189         return mTelephonyManager.getVoiceMailNumber(subId);
1190     }
1191 
1192     @Rpc(description = "Get voice message count for specified subscription ID.")
telephonyGetVoiceMailCountForSubscription( @pcParametername = "subId") Integer subId)1193     public Integer telephonyGetVoiceMailCountForSubscription(
1194                    @RpcParameter(name = "subId") Integer subId) {
1195         return mTelephonyManager.getVoiceMessageCount(subId);
1196     }
1197 
1198     @Rpc(description = "Get voice message count for default subscription ID.")
telephonyGetVoiceMailCount()1199     public Integer telephonyGetVoiceMailCount() {
1200         return mTelephonyManager.getVoiceMessageCount();
1201     }
1202 
1203     @Rpc(description = "Returns true if the device is in  roaming state" +
1204                        "for default subscription ID")
telephonyCheckNetworkRoaming()1205     public Boolean telephonyCheckNetworkRoaming() {
1206         return telephonyCheckNetworkRoamingForSubscription(
1207                              SubscriptionManager.getDefaultSubscriptionId());
1208     }
1209 
1210     @Rpc(description = "Returns true if the device is in roaming state " +
1211                        "for specified subscription ID")
telephonyCheckNetworkRoamingForSubscription( @pcParametername = "subId") Integer subId)1212     public Boolean telephonyCheckNetworkRoamingForSubscription(
1213                    @RpcParameter(name = "subId") Integer subId) {
1214         return mTelephonyManager.isNetworkRoaming(subId);
1215     }
1216 
1217     @Rpc(description = "Returns the unique device ID such as MEID or IMEI " +
1218                        "for deault sim slot ID, null if unavailable")
telephonyGetDeviceId()1219     public String telephonyGetDeviceId() {
1220         return telephonyGetDeviceIdForSlotId(mTelephonyManager.getSlotIndex());
1221     }
1222 
1223     @Rpc(description = "Returns the unique device ID such as MEID or IMEI for" +
1224                        " specified slot ID, null if unavailable")
telephonyGetDeviceIdForSlotId( @pcParametername = "slotId") Integer slotId)1225     public String telephonyGetDeviceIdForSlotId(
1226                   @RpcParameter(name = "slotId")
1227                   Integer slotId){
1228         return mTelephonyManager.getDeviceId(slotId);
1229     }
1230 
1231     @Rpc(description = "Returns the modem sw version, such as IMEI-SV;" +
1232                        " null if unavailable")
telephonyGetDeviceSoftwareVersion()1233     public String telephonyGetDeviceSoftwareVersion() {
1234         return mTelephonyManager.getDeviceSoftwareVersion();
1235     }
1236 
1237     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
1238                        "for default subscription ID; null if unavailable")
telephonyGetLine1Number()1239     public String telephonyGetLine1Number() {
1240         return mTelephonyManager.getLine1Number();
1241     }
1242 
1243     @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " +
1244                        "for specified subscription ID; null if unavailable")
telephonyGetLine1NumberForSubscription( @pcParametername = "subId") Integer subId)1245     public String telephonyGetLine1NumberForSubscription(
1246                   @RpcParameter(name = "subId") Integer subId) {
1247         return mTelephonyManager.getLine1Number(subId);
1248     }
1249 
1250     @Rpc(description = "Returns the Alpha Tag for the default subscription " +
1251                        "ID; null if unavailable")
telephonyGetLine1AlphaTag()1252     public String telephonyGetLine1AlphaTag() {
1253         return mTelephonyManager.getLine1AlphaTag();
1254     }
1255 
1256     @Rpc(description = "Returns the Alpha Tag for the specified subscription " +
1257                        "ID; null if unavailable")
telephonyGetLine1AlphaTagForSubscription( @pcParametername = "subId") Integer subId)1258     public String telephonyGetLine1AlphaTagForSubscription(
1259                   @RpcParameter(name = "subId") Integer subId) {
1260         return mTelephonyManager.getLine1AlphaTag(subId);
1261     }
1262 
1263     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
1264                        "for the default subscription")
telephonySetLine1Number( @pcParametername = "number") String number, @RpcOptional @RpcParameter(name = "alphaTag") String alphaTag)1265     public Boolean telephonySetLine1Number(
1266                 @RpcParameter(name = "number") String number,
1267                 @RpcOptional
1268                 @RpcParameter(name = "alphaTag") String alphaTag) {
1269         return mTelephonyManager.setLine1NumberForDisplay(alphaTag, number);
1270     }
1271 
1272     @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" +
1273                        "for the specified subscription")
telephonySetLine1NumberForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "number") String number, @RpcOptional @RpcParameter(name = "alphaTag") String alphaTag)1274     public Boolean telephonySetLine1NumberForSubscription(
1275                 @RpcParameter(name = "subId") Integer subId,
1276                 @RpcParameter(name = "number") String number,
1277                 @RpcOptional
1278                 @RpcParameter(name = "alphaTag") String alphaTag) {
1279         return mTelephonyManager.setLine1NumberForDisplay(subId, alphaTag, number);
1280     }
1281 
1282     @Rpc(description = "Returns the neighboring cell information of the device.")
telephonyGetNeighboringCellInfo()1283     public List<NeighboringCellInfo> telephonyGetNeighboringCellInfo() {
1284         return mTelephonyManager.getNeighboringCellInfo();
1285     }
1286 
1287     @Rpc(description =  "Sets the minimum reporting interval for CellInfo" +
1288                         "0-as quickly as possible, 0x7FFFFFF-off")
telephonySetCellInfoListRate( @pcParametername = "rate") Integer rate )1289     public void telephonySetCellInfoListRate(
1290                 @RpcParameter(name = "rate") Integer rate
1291             ) {
1292         mTelephonyManager.setCellInfoListRate(rate, SubscriptionManager.getDefaultSubscriptionId());
1293     }
1294 
1295     /**
1296      * Request a list of the current (latest) CellInfo.
1297      *
1298      * <p>When invoked on a device running Q or later, this will only return cached info.
1299      */
1300     @Rpc(description = "Returns all observed cell information from all radios"
1301                        + "on the device including the primary and neighboring cells.")
telephonyGetAllCellInfo()1302     public List<CellInfo> telephonyGetAllCellInfo() {
1303         return mTelephonyManager.getAllCellInfo();
1304     }
1305 
1306     private abstract class FacadeCellInfoCallback extends TelephonyManager.CellInfoCallback {
1307         public List<CellInfo> cellInfo;
1308     }
1309 
1310     /** Request an asynchronous update for the latest CellInfo */
1311     @Rpc(description = "Request updated CellInfo scan information for"
1312                        + " primary and neighboring cells.")
telephonyRequestCellInfoUpdate()1313     public List<CellInfo> telephonyRequestCellInfoUpdate() {
1314         FacadeCellInfoCallback tmCiCb = new FacadeCellInfoCallback() {
1315             @Override
1316             public void onCellInfo(List<CellInfo> ci) {
1317                 synchronized (this) {
1318                     this.cellInfo = ci;
1319                     notifyAll();
1320                 }
1321             }
1322 
1323             @Override
1324             public void onError(int errorCode, Throwable detail) {
1325                 Log.d("Error in telephonyRequestCellInfoUpdate(): errorCode=" + errorCode
1326                         + "detail=" + detail);
1327             }
1328         };
1329 
1330         synchronized (tmCiCb) {
1331             mTelephonyManager.requestCellInfoUpdate(
1332                     new Executor() {
1333                         public void execute(Runnable r) {
1334                             Log.d("Running cellInfo Executor");
1335                             r.run();
1336                         }
1337                     }, tmCiCb);
1338             try {
1339                 tmCiCb.wait(3000 /* millis */);
1340             } catch (InterruptedException e) {
1341                 Log.d("Timed out waiting for cellInfo Executor");
1342                 return null;
1343             }
1344         }
1345         return tmCiCb.cellInfo;
1346     }
1347 
1348     @Rpc(description = "Returns True if cellular data is enabled for" +
1349                        "default data subscription ID.")
telephonyIsDataEnabled()1350     public Boolean telephonyIsDataEnabled() {
1351         return telephonyIsDataEnabledForSubscription(
1352                    SubscriptionManager.getDefaultDataSubscriptionId());
1353     }
1354 
1355     @Rpc(description = "Returns True if data connection is enabled.")
telephonyIsDataEnabledForSubscription( @pcParametername = "subId") Integer subId)1356     public Boolean telephonyIsDataEnabledForSubscription(
1357                    @RpcParameter(name = "subId") Integer subId) {
1358         return mTelephonyManager.getDataEnabled(subId);
1359     }
1360 
1361     @Rpc(description = "Toggles data connection on /off for" +
1362                        " default data subscription ID.")
telephonyToggleDataConnection( @pcParametername = "enabled") @pcOptional Boolean enabled)1363     public void telephonyToggleDataConnection(
1364                 @RpcParameter(name = "enabled")
1365                 @RpcOptional Boolean enabled) {
1366         telephonyToggleDataConnectionForSubscription(
1367                          SubscriptionManager.getDefaultDataSubscriptionId(), enabled);
1368     }
1369 
1370     @Rpc(description = "Toggles data connection on/off for" +
1371                        " specified subscription ID")
telephonyToggleDataConnectionForSubscription( @pcParametername = "subId") Integer subId, @RpcParameter(name = "enabled") @RpcOptional Boolean enabled)1372     public void telephonyToggleDataConnectionForSubscription(
1373                 @RpcParameter(name = "subId") Integer subId,
1374                 @RpcParameter(name = "enabled")
1375                 @RpcOptional Boolean enabled) {
1376         if (enabled == null) {
1377             enabled = !telephonyIsDataEnabledForSubscription(subId);
1378         }
1379         mTelephonyManager.setDataEnabled(subId, enabled);
1380     }
1381 
1382     @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)1383     public void telephonySetAPN(@RpcParameter(name = "name") final String name,
1384                        @RpcParameter(name = "apn") final String apn,
1385                        @RpcParameter(name = "type") @RpcOptional @RpcDefault("")
1386                        final String type,
1387                        @RpcParameter(name = "subId") @RpcOptional Integer subId) {
1388         //TODO: b/26273471 Need to find out how to set APN for specific subId
1389         Uri uri;
1390         Cursor cursor;
1391 
1392         String mcc = "";
1393         String mnc = "";
1394 
1395         List<String> numerics = TelephonyProperties.icc_operator_numeric();
1396         String numeric = numerics.isEmpty() ? null : numerics.get(0);
1397         // MCC is first 3 chars and then in 2 - 3 chars of MNC
1398         if (numeric != null && numeric.length() > 4) {
1399             // Country code
1400             mcc = numeric.substring(0, 3);
1401             // Network code
1402             mnc = numeric.substring(3);
1403         }
1404 
1405         uri = mService.getContentResolver().insert(
1406                 Telephony.Carriers.CONTENT_URI, new ContentValues());
1407         if (uri == null) {
1408             Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI);
1409             return;
1410         }
1411 
1412         cursor = mService.getContentResolver().query(uri, sProjection, null, null, null);
1413         cursor.moveToFirst();
1414 
1415         ContentValues values = new ContentValues();
1416 
1417         values.put(Telephony.Carriers.NAME, name);
1418         values.put(Telephony.Carriers.APN, apn);
1419         values.put(Telephony.Carriers.PROXY, "");
1420         values.put(Telephony.Carriers.PORT, "");
1421         values.put(Telephony.Carriers.MMSPROXY, "");
1422         values.put(Telephony.Carriers.MMSPORT, "");
1423         values.put(Telephony.Carriers.USER, "");
1424         values.put(Telephony.Carriers.SERVER, "");
1425         values.put(Telephony.Carriers.PASSWORD, "");
1426         values.put(Telephony.Carriers.MMSC, "");
1427         values.put(Telephony.Carriers.TYPE, type);
1428         values.put(Telephony.Carriers.MCC, mcc);
1429         values.put(Telephony.Carriers.MNC, mnc);
1430         values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
1431 
1432         int ret = mService.getContentResolver().update(uri, values, null, null);
1433         Log.d("after update " + ret);
1434         cursor.close();
1435 
1436         // Make this APN as the preferred
1437         String where = "name=\"" + name + "\"";
1438 
1439         Cursor c = mService.getContentResolver().query(
1440                 Telephony.Carriers.CONTENT_URI,
1441                 new String[] {
1442                         "_id", "name", "apn", "type"
1443                 }, where, null,
1444                 Telephony.Carriers.DEFAULT_SORT_ORDER);
1445         if (c != null) {
1446             c.moveToFirst();
1447             String key = c.getString(0);
1448             final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
1449             ContentResolver resolver = mService.getContentResolver();
1450             ContentValues prefAPN = new ContentValues();
1451             prefAPN.put("apn_id", key);
1452             resolver.update(Uri.parse(PREFERRED_APN_URI), prefAPN, null, null);
1453         }
1454         c.close();
1455     }
1456 
1457     @Rpc(description = "Returns the number of APNs defined")
telephonyGetNumberOfAPNs( @pcParametername = "subId") @pcOptional Integer subId)1458     public int telephonyGetNumberOfAPNs(
1459                @RpcParameter(name = "subId")
1460                @RpcOptional Integer subId) {
1461         //TODO: b/26273471 Need to find out how to get Number of APNs for specific subId
1462         int result = 0;
1463 
1464         Cursor cursor = mService.getContentResolver().query(
1465                 Telephony.Carriers.SIM_APN_URI,
1466                 new String[] {"_id", "name", "apn", "type"}, null, null,
1467                 Telephony.Carriers.DEFAULT_SORT_ORDER);
1468 
1469         if (cursor != null) {
1470             result = cursor.getCount();
1471         }
1472         cursor.close();
1473         return result;
1474     }
1475 
1476     @Rpc(description = "Returns the currently selected APN name")
telephonyGetSelectedAPN( @pcParametername = "subId") @pcOptional Integer subId)1477     public String telephonyGetSelectedAPN(
1478                   @RpcParameter(name = "subId")
1479                   @RpcOptional Integer subId) {
1480         //TODO: b/26273471 Need to find out how to get selected APN for specific subId
1481         String key = null;
1482         int ID_INDEX = 0;
1483         final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
1484 
1485         Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI),
1486                 new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
1487 
1488         if (cursor.getCount() > 0) {
1489             cursor.moveToFirst();
1490             key = cursor.getString(ID_INDEX);
1491         }
1492         cursor.close();
1493         return key;
1494     }
1495 
1496     @Rpc(description = "Returns the current data connection state")
telephonyGetDataConnectionState()1497     public String telephonyGetDataConnectionState() {
1498         return TelephonyUtils.getDataConnectionStateString(
1499             mTelephonyManager.getDataState());
1500     }
1501 
1502     @Rpc(description = "Returns Total Rx Bytes.")
getTotalRxBytes()1503     public long getTotalRxBytes() {
1504         return TrafficStats.getTotalRxBytes();
1505     }
1506 
1507     @Rpc(description = "Returns Total Tx Bytes.")
getTotalTxBytes()1508     public long getTotalTxBytes() {
1509         return TrafficStats.getTotalTxBytes();
1510     }
1511 
1512     @Rpc(description = "Returns Total Rx Packets.")
getTotalRxPackets()1513     public long getTotalRxPackets() {
1514         return TrafficStats.getTotalRxPackets();
1515     }
1516 
1517     @Rpc(description = "Returns Total Tx Packets.")
getTotalTxPackets()1518     public long getTotalTxPackets() {
1519         return TrafficStats.getTotalTxPackets();
1520     }
1521 
1522     @Rpc(description = "Returns Mobile Network Rx Bytes.")
getMobileRxBytes()1523     public long getMobileRxBytes() {
1524         return TrafficStats.getMobileRxBytes();
1525     }
1526 
1527     @Rpc(description = "Returns Mobile Network Tx Bytes.")
getMobileTxBytes()1528     public long getMobileTxBytes() {
1529         return TrafficStats.getMobileTxBytes();
1530     }
1531 
1532     @Rpc(description = "Returns Mobile Network Packets.")
getMobileRxPackets()1533     public long getMobileRxPackets() {
1534         return TrafficStats.getMobileRxPackets();
1535     }
1536 
1537     @Rpc(description = "Returns Mobile Network Packets.")
getMobileTxPackets()1538     public long getMobileTxPackets() {
1539         return TrafficStats.getMobileTxPackets();
1540     }
1541 
1542     @Rpc(description = "Returns a given UID Rx Bytes.")
getUidRxBytes( @pcParametername = "uid") Integer uid)1543     public long getUidRxBytes(
1544             @RpcParameter(name = "uid") Integer uid) {
1545         return TrafficStats.getUidRxBytes(uid);
1546     }
1547 
1548     @Rpc(description = "Returns a given UID Rx Packets.")
getUidRxPackets( @pcParametername = "uid") Integer uid)1549     public long getUidRxPackets(
1550             @RpcParameter(name = "uid") Integer uid) {
1551         return TrafficStats.getUidRxPackets(uid);
1552     }
1553 
1554     @Rpc(description = "Enables or Disables Video Calling()")
telephonyEnableVideoCalling( @pcParametername = "enable") boolean enable)1555     public void telephonyEnableVideoCalling(
1556             @RpcParameter(name = "enable") boolean enable) {
1557         mTelephonyManager.enableVideoCalling(enable);
1558     }
1559 
1560     @Rpc(description = "Returns a boolean of whether or not " +
1561             "video calling setting is enabled by the user")
telephonyIsVideoCallingEnabled()1562     public Boolean telephonyIsVideoCallingEnabled() {
1563         return mTelephonyManager.isVideoCallingEnabled();
1564     }
1565 
1566     @Rpc(description = "Returns a boolean of whether video calling is available for use")
telephonyIsVideoCallingAvailable()1567     public Boolean telephonyIsVideoCallingAvailable() {
1568         return mTelephonyManager.isVideoTelephonyAvailable();
1569     }
1570 
1571     @Rpc(description = "Returns a boolean of whether or not the device is ims registered")
telephonyIsImsRegistered()1572     public Boolean telephonyIsImsRegistered() {
1573         return mTelephonyManager.isImsRegistered();
1574     }
1575 
1576     @Rpc(description = "Returns a boolean of whether or not volte calling is available for use")
telephonyIsVolteAvailable()1577     public Boolean telephonyIsVolteAvailable() {
1578         return mTelephonyManager.isVolteAvailable();
1579     }
1580 
1581     @Rpc(description = "Returns a boolean of whether or not wifi calling is available for use")
telephonyIsWifiCallingAvailable()1582     public Boolean telephonyIsWifiCallingAvailable() {
1583         return mTelephonyManager.isWifiCallingAvailable();
1584     }
1585 
1586     @Rpc(description = "Returns the service state string for default subscription ID")
telephonyGetServiceState()1587     public ServiceState telephonyGetServiceState() {
1588         return telephonyGetServiceStateForSubscription(
1589                                  SubscriptionManager.getDefaultSubscriptionId());
1590     }
1591 
1592     @Rpc(description = "Returns the service state string for specified subscription ID")
telephonyGetServiceStateForSubscription( @pcParametername = "subId") Integer subId)1593     public ServiceState telephonyGetServiceStateForSubscription(
1594                   @RpcParameter(name = "subId") Integer subId) {
1595         return mTelephonyManager.getServiceStateForSubscriber(subId);
1596     }
1597 
1598     @Rpc(description = "Returns the call state for default subscription ID")
telephonyGetCallState()1599     public String telephonyGetCallState() {
1600         return telephonyGetCallStateForSubscription(
1601                                SubscriptionManager.getDefaultSubscriptionId());
1602     }
1603 
1604     @Rpc(description = "Returns the call state for specified subscription ID")
telephonyGetCallStateForSubscription( @pcParametername = "subId") Integer subId)1605     public String telephonyGetCallStateForSubscription(
1606                   @RpcParameter(name = "subId") Integer subId) {
1607         return TelephonyUtils.getTelephonyCallStateString(
1608             mTelephonyManager.getCallState(subId));
1609     }
1610 
1611     @Rpc(description = "Returns current signal strength for default subscription ID.")
telephonyGetSignalStrength()1612     public SignalStrength telephonyGetSignalStrength() {
1613         return mTelephonyManager.getSignalStrength();
1614     }
1615 
1616     @Rpc(description = "Returns current signal strength for specified subscription ID.")
telephonyGetSignalStrengthForSubscription( @pcParametername = "subId") Integer subId)1617     public SignalStrength telephonyGetSignalStrengthForSubscription(
1618                     @RpcParameter(name = "subId") Integer subId) {
1619         StateChangeListener listener = getStateChangeListenerForSubscription(subId, false);
1620         if(listener == null) {
1621             Log.e("Invalid subscription ID");
1622             return null;
1623         }
1624         return listener.mSignalStrengthChangeListener.mSignalStrengths;
1625     }
1626 
1627     @Rpc(description = "Returns the sim count.")
telephonyGetSimCount()1628     public int telephonyGetSimCount() {
1629         return mTelephonyManager.getSimCount();
1630     }
1631 
1632     /**
1633      * Plays an audio file specified by {@code audioFileName} during a phone call.
1634      *
1635      * @return {@code true} if the audio file is successfully played.
1636      */
1637     @Rpc(description = "Plays the specified audio file during a phone call")
telephonyPlayAudioFile( @pcParametername = "audioFileName", description = "the audio file in the app's files folder") String audioFileName)1638     public boolean telephonyPlayAudioFile(
1639         @RpcParameter(name = "audioFileName", description = "the audio file in the app's files folder")
1640             String audioFileName) {
1641         Log.d(String.format("Playing audio file \"%s\"...", audioFileName));
1642         InCallServiceImpl.setEventFacade(mEventFacade);
1643         return InCallServiceImpl.playAudioFile(audioFileName);
1644     }
1645 
1646     /** Stops playing an audio file during a call. */
1647     @Rpc(description = "Stops playing audio file during a phone call")
telephonyStopPlayingAudioFile()1648     public void telephonyStopPlayingAudioFile() {
1649         InCallServiceImpl.stopPlayAudioFile();
1650     }
1651 
1652     /**
1653      * Records voice and writes to a wav file specified by {@code recordFileName}
1654      * during a phone call.
1655      *
1656      * @return {@code true} if voice is successfully recorded
1657      */
1658     @Rpc(description = "Records voice and writes to a wav file during a phone call")
telephonyRecordVoice( @pcParametername = "recordFileName", description = "The recorded voice file name") String recordFileName, @RpcParameter(name = "sampleRate", description = "sampling rate of voice data") @RpcDefault("16000") Integer sampleRate, @RpcParameter(name = "channelCount", description = "channel number of voice to record") @RpcDefault("1") Integer channelCount, @RpcParameter(name = "cancelNoiseEcho", description = "enable echo canceler and noise suppressor") @RpcDefault("false") Boolean cancelNoiseEcho)1659     public boolean telephonyRecordVoice(
1660         @RpcParameter(name = "recordFileName", description = "The recorded voice file name")
1661             String recordFileName,
1662         @RpcParameter(name = "sampleRate", description = "sampling rate of voice data")
1663         @RpcDefault("16000") Integer sampleRate,
1664         @RpcParameter(name = "channelCount", description = "channel number of voice to record")
1665         @RpcDefault("1") Integer channelCount,
1666         @RpcParameter(name = "cancelNoiseEcho", description = "enable echo canceler and noise suppressor")
1667         @RpcDefault("false") Boolean cancelNoiseEcho) {
1668         Log.d(String.format("Recording voice to  the \"%s\" file...", recordFileName));
1669         InCallServiceImpl.setEventFacade(mEventFacade);
1670         return InCallServiceImpl.recordVoice(recordFileName, sampleRate, channelCount, cancelNoiseEcho);
1671     }
1672 
1673     /** Stops recording voice during a phone call.*/
1674     @Rpc(description = "Stops recording voice during a call.")
telephonyStopRecordVoice()1675     public void telephonyStopRecordVoice() {
1676         InCallServiceImpl.stopRecordVoice();
1677     }
1678 
1679     /**
1680      * Get the list of Forbidden PLMNs stored on the USIM
1681      * profile of the SIM for the default subscription.
1682      */
1683     @Rpc(description = "Returns a list of forbidden PLMNs")
telephonyGetForbiddenPlmns()1684     public @Nullable List<String> telephonyGetForbiddenPlmns() {
1685         String[] fplmns = mTelephonyManager.getForbiddenPlmns(
1686                 SubscriptionManager.getDefaultSubscriptionId(),
1687                 TelephonyManager.APPTYPE_USIM);
1688 
1689         if (fplmns != null) {
1690             return Arrays.asList(fplmns);
1691         }
1692         return null;
1693     }
1694 
getStateChangeListenerForSubscription( int subId, boolean createIfNeeded)1695     private StateChangeListener getStateChangeListenerForSubscription(
1696             int subId,
1697             boolean createIfNeeded) {
1698 
1699        if(mStateChangeListeners.get(subId) == null) {
1700             if(createIfNeeded == false) {
1701                 return null;
1702             }
1703 
1704             if(mSubscriptionManager.isValidSubscriptionId(subId) == false) {
1705                 Log.e("Cannot get listener for invalid/inactive subId");
1706                 return null;
1707             }
1708 
1709             mStateChangeListeners.put(subId, new StateChangeListener(subId));
1710         }
1711 
1712         return mStateChangeListeners.get(subId);
1713     }
1714 
1715     //FIXME: This whole class needs reworking. Why do we have separate listeners for everything?
1716     //We need one listener that overrides multiple methods.
1717     private final class StateChangeListener {
1718         public ServiceStateChangeListener mServiceStateChangeListener;
1719         public SignalStrengthChangeListener mSignalStrengthChangeListener;
1720         public CallStateChangeListener mCallStateChangeListener;
1721         public CellInfoChangeListener mCellInfoChangeListener;
1722         public DataConnectionStateChangeListener mDataConnectionStateChangeListener;
1723         public ActiveDataSubIdChangeListener mActiveDataSubIdChangeListener;
1724         public DisplayInfoStateChangeListener mDisplayInfoStateChangeListener;
1725         public DataConnectionRealTimeInfoChangeListener mDataConnectionRTInfoChangeListener;
1726         public VoiceMailStateChangeListener mVoiceMailStateChangeListener;
1727 
StateChangeListener(int subId)1728         public StateChangeListener(int subId) {
1729             mServiceStateChangeListener =
1730                 new ServiceStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1731             mSignalStrengthChangeListener =
1732                 new SignalStrengthChangeListener(mEventFacade, subId, mService.getMainLooper());
1733             mDataConnectionStateChangeListener =
1734                 new DataConnectionStateChangeListener(
1735                         mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
1736             mActiveDataSubIdChangeListener =
1737                 new ActiveDataSubIdChangeListener(
1738                         mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
1739             mDisplayInfoStateChangeListener =
1740                 new DisplayInfoStateChangeListener(
1741                         mEventFacade, mTelephonyManager, subId, mService.getMainLooper());
1742             mCallStateChangeListener =
1743                 new CallStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1744             mCellInfoChangeListener =
1745                 new CellInfoChangeListener(mEventFacade, subId, mService.getMainLooper());
1746             mDataConnectionRTInfoChangeListener =
1747                 new DataConnectionRealTimeInfoChangeListener(
1748                         mEventFacade, subId, mService.getMainLooper());
1749             mVoiceMailStateChangeListener =
1750                 new VoiceMailStateChangeListener(mEventFacade, subId, mService.getMainLooper());
1751         }
1752 
shutdown()1753         public void shutdown() {
1754             mTelephonyManager.listen(
1755                     mServiceStateChangeListener,
1756                     PhoneStateListener.LISTEN_NONE);
1757             mTelephonyManager.listen(
1758                     mSignalStrengthChangeListener,
1759                     PhoneStateListener.LISTEN_NONE);
1760             mTelephonyManager.listen(
1761                     mCallStateChangeListener,
1762                     PhoneStateListener.LISTEN_NONE);
1763             mTelephonyManager.listen(
1764                     mActiveDataSubIdChangeListener,
1765                     PhoneStateListener.LISTEN_NONE);
1766             mTelephonyManager.listen(
1767                     mDisplayInfoStateChangeListener,
1768                     PhoneStateListener.LISTEN_NONE);
1769             mTelephonyManager.listen(
1770                     mCellInfoChangeListener,
1771                     PhoneStateListener.LISTEN_NONE);
1772             mTelephonyManager.listen(
1773                     mDataConnectionStateChangeListener,
1774                     PhoneStateListener.LISTEN_NONE);
1775             mTelephonyManager.listen(
1776                     mDataConnectionRTInfoChangeListener,
1777                     PhoneStateListener.LISTEN_NONE);
1778             mTelephonyManager.listen(
1779                     mVoiceMailStateChangeListener,
1780                     PhoneStateListener.LISTEN_NONE);
1781         }
1782 
finalize()1783         protected void finalize() {
1784             try {
1785                 shutdown();
1786             } catch(Exception e) {}
1787         }
1788     }
1789 
1790     @Override
shutdown()1791     public void shutdown() {
1792         for(StateChangeListener listener : mStateChangeListeners.values()) {
1793             listener.shutdown();
1794         }
1795     }
1796 }
1797