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