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