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( 259 @RpcParameter(name = "type") String type, 260 @RpcParameter(name = "listen") Boolean listen) { 261 return telephonyAdjustPreciseCallStateListenLevelForSubscription(type, listen, 262 SubscriptionManager.getDefaultVoiceSubscriptionId()); 263 } 264 265 @Rpc(description = "Turn on/off precise listening on fore/background or" + 266 " ringing calls for specified subscription ID.") 267 public Boolean telephonyAdjustPreciseCallStateListenLevelForSubscription( 268 @RpcParameter(name = "type") String type, 269 @RpcParameter(name = "listen") Boolean listen, 270 @RpcParameter(name = "subId") Integer subId) { 271 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 272 if(listener == null) { 273 Log.e("Invalid subscription ID"); 274 return false; 275 } 276 277 if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND)) { 278 listener.mCallStateChangeListener.listenForeground = listen; 279 } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING)) { 280 listener.mCallStateChangeListener.listenRinging = listen; 281 } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND)) { 282 listener.mCallStateChangeListener.listenBackground = listen; 283 } else { 284 throw new IllegalArgumentException("Invalid listen level type " + type); 285 } 286 287 return true; 288 } 289 290 @Rpc(description = "Stops tracking cell info change " + 291 "for default voice subscription ID.") 292 public Boolean telephonyStopTrackingCellInfoChange() { 293 return telephonyStopTrackingCellInfoChangeForSubscription( 294 SubscriptionManager.getDefaultVoiceSubscriptionId()); 295 } 296 297 @Rpc(description = "Stops tracking cell info change " + 298 "for specified subscription ID.") 299 public Boolean telephonyStopTrackingCellInfoChangeForSubscription( 300 @RpcParameter(name = "subId") Integer subId) { 301 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 302 if(listener == null) { 303 Log.e("Invalid subscription ID"); 304 return false; 305 } 306 mTelephonyManager.listen( 307 listener.mCellInfoChangeListener, 308 PhoneStateListener.LISTEN_NONE); 309 return true; 310 } 311 @Rpc(description = "Stops tracking call state change " + 312 "for default voice subscription ID.") 313 public Boolean telephonyStopTrackingCallStateChange() { 314 return telephonyStopTrackingCallStateChangeForSubscription( 315 SubscriptionManager.getDefaultVoiceSubscriptionId()); 316 } 317 318 @Rpc(description = "Stops tracking call state change " + 319 "for specified subscription ID.") 320 public Boolean telephonyStopTrackingCallStateChangeForSubscription( 321 @RpcParameter(name = "subId") Integer subId) { 322 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 323 if(listener == null) { 324 Log.e("Invalid subscription ID"); 325 return false; 326 } 327 mTelephonyManager.listen( 328 listener.mCallStateChangeListener, 329 PhoneStateListener.LISTEN_NONE); 330 return true; 331 } 332 333 @Rpc(description = "Starts tracking data connection real time info change" + 334 "for default subscription ID.") 335 public Boolean telephonyStartTrackingDataConnectionRTInfoChange() { 336 return telephonyStartTrackingDataConnectionRTInfoChangeForSubscription( 337 SubscriptionManager.getDefaultDataSubscriptionId()); 338 } 339 340 @Rpc(description = "Starts tracking data connection real time info change" + 341 "for specified subscription ID.") 342 public Boolean telephonyStartTrackingDataConnectionRTInfoChangeForSubscription( 343 @RpcParameter(name = "subId") Integer subId) { 344 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 345 if(listener == null) { 346 Log.e("Invalid subscription ID"); 347 return false; 348 } 349 mTelephonyManager.listen( 350 listener.mDataConnectionRTInfoChangeListener, 351 DataConnectionRealTimeInfoChangeListener.sListeningStates); 352 return true; 353 } 354 355 @Rpc(description = "Stops tracking data connection real time info change" + 356 "for default subscription ID.") 357 public Boolean telephonyStopTrackingDataConnectionRTInfoChange() { 358 return telephonyStopTrackingDataConnectionRTInfoChangeForSubscription( 359 SubscriptionManager.getDefaultDataSubscriptionId()); 360 } 361 362 @Rpc(description = "Stops tracking data connection real time info change" + 363 "for specified subscription ID.") 364 public Boolean telephonyStopTrackingDataConnectionRTInfoChangeForSubscription( 365 @RpcParameter(name = "subId") Integer subId) { 366 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 367 if(listener == null) { 368 Log.e("Invalid subscription ID"); 369 return false; 370 } 371 mTelephonyManager.listen( 372 listener.mDataConnectionRTInfoChangeListener, 373 PhoneStateListener.LISTEN_NONE); 374 return true; 375 } 376 377 @Rpc(description = "Starts tracking data connection state change" + 378 "for default subscription ID..") 379 public Boolean telephonyStartTrackingDataConnectionStateChange() { 380 return telephonyStartTrackingDataConnectionStateChangeForSubscription( 381 SubscriptionManager.getDefaultDataSubscriptionId()); 382 } 383 384 @Rpc(description = "Starts tracking data connection state change" + 385 "for specified subscription ID.") 386 public Boolean telephonyStartTrackingDataConnectionStateChangeForSubscription( 387 @RpcParameter(name = "subId") Integer subId) { 388 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 389 if(listener == null) { 390 Log.e("Invalid subscription ID"); 391 return false; 392 } 393 mTelephonyManager.listen( 394 listener.mDataConnectionStateChangeListener, 395 DataConnectionStateChangeListener.sListeningStates); 396 return true; 397 } 398 399 @Rpc(description = "Stops tracking data connection state change " + 400 "for default subscription ID..") 401 public Boolean telephonyStopTrackingDataConnectionStateChange() { 402 return telephonyStopTrackingDataConnectionStateChangeForSubscription( 403 SubscriptionManager.getDefaultDataSubscriptionId()); 404 } 405 406 @Rpc(description = "Stops tracking data connection state change " + 407 "for specified subscription ID..") 408 public Boolean telephonyStopTrackingDataConnectionStateChangeForSubscription( 409 @RpcParameter(name = "subId") Integer subId) { 410 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 411 if(listener == null) { 412 Log.e("Invalid subscription ID"); 413 return false; 414 } 415 mTelephonyManager.listen( 416 listener.mDataConnectionStateChangeListener, 417 PhoneStateListener.LISTEN_NONE); 418 return true; 419 } 420 421 @Rpc(description = "Starts tracking service state change " + 422 "for default subscription ID.") 423 public Boolean telephonyStartTrackingServiceStateChange() { 424 return telephonyStartTrackingServiceStateChangeForSubscription( 425 SubscriptionManager.getDefaultSubscriptionId()); 426 } 427 428 @Rpc(description = "Starts tracking service state change " + 429 "for specified subscription ID.") 430 public Boolean telephonyStartTrackingServiceStateChangeForSubscription( 431 @RpcParameter(name = "subId") Integer subId) { 432 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 433 if(listener == null) { 434 Log.e("Invalid subscription ID"); 435 return false; 436 } 437 mTelephonyManager.listen( 438 listener.mServiceStateChangeListener, 439 ServiceStateChangeListener.sListeningStates); 440 return true; 441 } 442 443 @Rpc(description = "Stops tracking service state change " + 444 "for default subscription ID.") 445 public Boolean telephonyStopTrackingServiceStateChange() { 446 return telephonyStopTrackingServiceStateChangeForSubscription( 447 SubscriptionManager.getDefaultSubscriptionId()); 448 } 449 450 @Rpc(description = "Stops tracking service state change " + 451 "for specified subscription ID.") 452 public Boolean telephonyStopTrackingServiceStateChangeForSubscription( 453 @RpcParameter(name = "subId") Integer subId) { 454 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 455 if(listener == null) { 456 Log.e("Invalid subscription ID"); 457 return false; 458 } 459 mTelephonyManager.listen( 460 listener.mServiceStateChangeListener, 461 PhoneStateListener.LISTEN_NONE); 462 return true; 463 } 464 465 @Rpc(description = "Starts tracking signal strength change " + 466 "for default subscription ID.") 467 public Boolean telephonyStartTrackingSignalStrengthChange() { 468 return telephonyStartTrackingSignalStrengthChangeForSubscription( 469 SubscriptionManager.getDefaultSubscriptionId()); 470 } 471 472 @Rpc(description = "Starts tracking signal strength change " + 473 "for specified subscription ID.") 474 public Boolean telephonyStartTrackingSignalStrengthChangeForSubscription( 475 @RpcParameter(name = "subId") Integer subId) { 476 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 477 if(listener == null) { 478 Log.e("Invalid subscription ID"); 479 return false; 480 } 481 mTelephonyManager.listen( 482 listener.mSignalStrengthChangeListener, 483 SignalStrengthChangeListener.sListeningStates); 484 return true; 485 } 486 487 @Rpc(description = "Stops tracking signal strength change " + 488 "for default subscription ID.") 489 public Boolean telephonyStopTrackingSignalStrengthChange() { 490 return telephonyStopTrackingSignalStrengthChangeForSubscription( 491 SubscriptionManager.getDefaultSubscriptionId()); 492 } 493 494 @Rpc(description = "Stops tracking signal strength change " + 495 "for specified subscription ID.") 496 public Boolean telephonyStopTrackingSignalStrengthChangeForSubscription( 497 @RpcParameter(name = "subId") Integer subId) { 498 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 499 if(listener == null) { 500 Log.e("Invalid subscription ID"); 501 return false; 502 } 503 mTelephonyManager.listen( 504 listener.mSignalStrengthChangeListener, 505 PhoneStateListener.LISTEN_NONE); 506 return true; 507 } 508 509 @Rpc(description = "Starts tracking voice mail state change " + 510 "for default subscription ID.") 511 public Boolean telephonyStartTrackingVoiceMailStateChange() { 512 return telephonyStartTrackingVoiceMailStateChangeForSubscription( 513 SubscriptionManager.getDefaultSubscriptionId()); 514 } 515 516 @Rpc(description = "Starts tracking voice mail state change " + 517 "for specified subscription ID.") 518 public Boolean telephonyStartTrackingVoiceMailStateChangeForSubscription( 519 @RpcParameter(name = "subId") Integer subId) { 520 StateChangeListener listener = getStateChangeListenerForSubscription(subId, true); 521 if(listener == null) { 522 Log.e("Invalid subscription ID"); 523 return false; 524 } 525 mTelephonyManager.listen( 526 listener.mVoiceMailStateChangeListener, 527 VoiceMailStateChangeListener.sListeningStates); 528 return true; 529 } 530 531 @Rpc(description = "Stops tracking voice mail state change " + 532 "for default subscription ID.") 533 public Boolean telephonyStopTrackingVoiceMailStateChange() { 534 return telephonyStopTrackingVoiceMailStateChangeForSubscription( 535 SubscriptionManager.getDefaultSubscriptionId()); 536 } 537 538 @Rpc(description = "Stops tracking voice mail state change " + 539 "for specified subscription ID.") 540 public Boolean telephonyStopTrackingVoiceMailStateChangeForSubscription( 541 @RpcParameter(name = "subId") Integer subId) { 542 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 543 if(listener == null) { 544 Log.e("Invalid subscription ID"); 545 return false; 546 } 547 mTelephonyManager.listen( 548 listener.mVoiceMailStateChangeListener, 549 PhoneStateListener.LISTEN_NONE); 550 return true; 551 } 552 553 @Rpc(description = "Answers an incoming ringing call.") 554 public void telephonyAnswerCall() throws RemoteException { 555 mTelephonyManager.silenceRinger(); 556 mTelephonyManager.answerRingingCall(); 557 } 558 559 @Rpc(description = "Returns the current cell location.") 560 public CellLocation telephonyGetCellLocation() { 561 return mTelephonyManager.getCellLocation(); 562 } 563 564 @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator." + 565 "for default subscription ID") 566 public String telephonyGetNetworkOperator() { 567 return telephonyGetNetworkOperatorForSubscription( 568 SubscriptionManager.getDefaultSubscriptionId()); 569 } 570 571 @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator" + 572 "for specified subscription ID.") 573 public String telephonyGetNetworkOperatorForSubscription( 574 @RpcParameter(name = "subId") Integer subId) { 575 return mTelephonyManager.getNetworkOperator(subId); 576 } 577 578 @Rpc(description = "Returns the alphabetic name of current registered operator" + 579 "for specified subscription ID.") 580 public String telephonyGetNetworkOperatorName() { 581 return telephonyGetNetworkOperatorNameForSubscription( 582 SubscriptionManager.getDefaultSubscriptionId()); 583 } 584 585 @Rpc(description = "Returns the alphabetic name of registered operator " + 586 "for specified subscription ID.") 587 public String telephonyGetNetworkOperatorNameForSubscription( 588 @RpcParameter(name = "subId") Integer subId) { 589 return mTelephonyManager.getNetworkOperatorName(subId); 590 } 591 592 @Rpc(description = "Returns the current RAT in use on the device.+" + 593 "for default subscription ID") 594 public String telephonyGetNetworkType() { 595 596 Log.d("sl4a:getNetworkType() is deprecated!" + 597 "Please use getVoiceNetworkType()" + 598 " or getDataNetworkTpe()"); 599 600 return telephonyGetNetworkTypeForSubscription( 601 SubscriptionManager.getDefaultSubscriptionId()); 602 } 603 604 @Rpc(description = "Returns the current RAT in use on the device" + 605 " for a given Subscription.") 606 public String telephonyGetNetworkTypeForSubscription( 607 @RpcParameter(name = "subId") Integer subId) { 608 609 Log.d("sl4a:getNetworkTypeForSubscriber() is deprecated!" + 610 "Please use getVoiceNetworkType()" + 611 " or getDataNetworkTpe()"); 612 613 return TelephonyUtils.getNetworkTypeString( 614 mTelephonyManager.getNetworkType(subId)); 615 } 616 617 @Rpc(description = "Returns the current voice RAT for" + 618 " the default voice subscription.") 619 public String telephonyGetVoiceNetworkType() { 620 return telephonyGetVoiceNetworkTypeForSubscription( 621 SubscriptionManager.getDefaultVoiceSubscriptionId()); 622 } 623 624 @Rpc(description = "Returns the current voice RAT for" + 625 " the specified voice subscription.") 626 public String telephonyGetVoiceNetworkTypeForSubscription( 627 @RpcParameter(name = "subId") Integer subId) { 628 return TelephonyUtils.getNetworkTypeString( 629 mTelephonyManager.getVoiceNetworkType(subId)); 630 } 631 632 @Rpc(description = "Returns the current data RAT for" + 633 " the defaut data subscription") 634 public String telephonyGetDataNetworkType() { 635 return telephonyGetDataNetworkTypeForSubscription( 636 SubscriptionManager.getDefaultDataSubscriptionId()); 637 } 638 639 @Rpc(description = "Returns the current data RAT for" + 640 " the specified data subscription") 641 public String telephonyGetDataNetworkTypeForSubscription( 642 @RpcParameter(name = "subId") Integer subId) { 643 return TelephonyUtils.getNetworkTypeString( 644 mTelephonyManager.getDataNetworkType(subId)); 645 } 646 647 @Rpc(description = "Returns the device phone type.") 648 public String telephonyGetPhoneType() { 649 return TelephonyUtils.getPhoneTypeString( 650 mTelephonyManager.getPhoneType()); 651 } 652 653 @Rpc(description = "Returns the MCC for default subscription ID") 654 public String telephonyGetSimCountryIso() { 655 return telephonyGetSimCountryIsoForSubscription( 656 SubscriptionManager.getDefaultSubscriptionId()); 657 } 658 659 @Rpc(description = "Returns the MCC for specified subscription ID") 660 public String telephonyGetSimCountryIsoForSubscription( 661 @RpcParameter(name = "subId") Integer subId) { 662 return mTelephonyManager.getSimCountryIso(subId); 663 } 664 665 @Rpc(description = "Returns the MCC+MNC for default subscription ID") 666 public String telephonyGetSimOperator() { 667 return telephonyGetSimOperatorForSubscription( 668 SubscriptionManager.getDefaultSubscriptionId()); 669 } 670 671 @Rpc(description = "Returns the MCC+MNC for specified subscription ID") 672 public String telephonyGetSimOperatorForSubscription( 673 @RpcParameter(name = "subId") Integer subId) { 674 return mTelephonyManager.getSimOperator(subId); 675 } 676 677 @Rpc(description = "Returns the Service Provider Name (SPN)" + 678 "for default subscription ID") 679 public String telephonyGetSimOperatorName() { 680 return telephonyGetSimOperatorNameForSubscription( 681 SubscriptionManager.getDefaultSubscriptionId()); 682 } 683 684 @Rpc(description = "Returns the Service Provider Name (SPN)" + 685 " for specified subscription ID.") 686 public String telephonyGetSimOperatorNameForSubscription( 687 @RpcParameter(name = "subId") Integer subId) { 688 return mTelephonyManager.getSimOperatorName(subId); 689 } 690 691 @Rpc(description = "Returns the serial number of the SIM for " + 692 "default subscription ID, or Null if unavailable") 693 public String telephonyGetSimSerialNumber() { 694 return telephonyGetSimSerialNumberForSubscription( 695 SubscriptionManager.getDefaultSubscriptionId()); 696 } 697 698 @Rpc(description = "Returns the serial number of the SIM for " + 699 "specified subscription ID, or Null if unavailable") 700 public String telephonyGetSimSerialNumberForSubscription( 701 @RpcParameter(name = "subId") Integer subId) { 702 return mTelephonyManager.getSimSerialNumber(subId); 703 } 704 705 @Rpc(description = "Returns the state of the SIM card for default slot ID.") 706 public String telephonyGetSimState() { 707 return telephonyGetSimStateForSlotId( 708 mTelephonyManager.getDefaultSim()); 709 } 710 711 @Rpc(description = "Returns the state of the SIM card for specified slot ID.") 712 public String telephonyGetSimStateForSlotId( 713 @RpcParameter(name = "slotId") Integer slotId) { 714 return TelephonyUtils.getSimStateString( 715 mTelephonyManager.getSimState(slotId)); 716 } 717 718 @Rpc(description = "Get Authentication Challenge Response from a " + 719 "given SIM Application") 720 public String telephonyGetIccSimChallengeResponse( 721 @RpcParameter(name = "appType") Integer appType, 722 @RpcParameter(name = "authType") Integer authType, 723 @RpcParameter(name = "hexChallenge") String hexChallenge) { 724 return telephonyGetIccSimChallengeResponseForSubscription( 725 SubscriptionManager.getDefaultSubscriptionId(), appType, authType, hexChallenge); 726 } 727 728 @Rpc(description = "Get Authentication Challenge Response from a " + 729 "given SIM Application for a specified Subscription") 730 public String telephonyGetIccSimChallengeResponseForSubscription( 731 @RpcParameter(name = "subId") Integer subId, 732 @RpcParameter(name = "appType") Integer appType, 733 @RpcParameter(name = "authType") Integer authType, 734 @RpcParameter(name = "hexChallenge") String hexChallenge) { 735 736 try { 737 String b64Data = BaseEncoding.base64().encode(BaseEncoding.base16().decode(hexChallenge)); 738 String b64Result = mTelephonyManager.getIccAuthentication(subId, appType, authType, b64Data); 739 return (b64Result != null) 740 ? BaseEncoding.base16().encode(BaseEncoding.base64().decode(b64Result)) : null; 741 } catch(Exception e) { 742 Log.e("Exception in phoneGetIccSimChallengeResponseForSubscription" + e.toString()); 743 return null; 744 } 745 } 746 747 @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " + 748 "for default subscription ID, or null if unavailable") 749 public String telephonyGetSubscriberId() { 750 return telephonyGetSubscriberIdForSubscription( 751 SubscriptionManager.getDefaultSubscriptionId()); 752 } 753 754 @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " + 755 "for specified subscription ID, or null if unavailable") 756 public String telephonyGetSubscriberIdForSubscription( 757 @RpcParameter(name = "subId") Integer subId) { 758 return mTelephonyManager.getSubscriberId(subId); 759 } 760 761 @Rpc(description = "Retrieves the alphabetic id associated with the" + 762 " voice mail number for default subscription ID.") 763 public String telephonyGetVoiceMailAlphaTag() { 764 return telephonyGetVoiceMailAlphaTagForSubscription( 765 SubscriptionManager.getDefaultSubscriptionId()); 766 } 767 768 769 @Rpc(description = "Retrieves the alphabetic id associated with the " + 770 "voice mail number for specified subscription ID.") 771 public String telephonyGetVoiceMailAlphaTagForSubscription( 772 @RpcParameter(name = "subId") Integer subId) { 773 return mTelephonyManager.getVoiceMailAlphaTag(subId); 774 } 775 776 @Rpc(description = "Returns the voice mail number " + 777 "for default subscription ID; null if unavailable.") 778 public String telephonyGetVoiceMailNumber() { 779 return telephonyGetVoiceMailNumberForSubscription( 780 SubscriptionManager.getDefaultSubscriptionId()); 781 } 782 783 @Rpc(description = "Returns the voice mail number " + 784 "for specified subscription ID; null if unavailable.") 785 public String telephonyGetVoiceMailNumberForSubscription( 786 @RpcParameter(name = "subId") Integer subId) { 787 return mTelephonyManager.getVoiceMailNumber(subId); 788 } 789 790 @Rpc(description = "Get voice message count for specified subscription ID.") 791 public Integer telephonyGetVoiceMailCountForSubscription( 792 @RpcParameter(name = "subId") Integer subId) { 793 return mTelephonyManager.getVoiceMessageCount(subId); 794 } 795 796 @Rpc(description = "Get voice message count for default subscription ID.") 797 public Integer telephonyGetVoiceMailCount() { 798 return mTelephonyManager.getVoiceMessageCount(); 799 } 800 801 @Rpc(description = "Returns true if the device is in roaming state" + 802 "for default subscription ID") 803 public Boolean telephonyCheckNetworkRoaming() { 804 return telephonyCheckNetworkRoamingForSubscription( 805 SubscriptionManager.getDefaultSubscriptionId()); 806 } 807 808 @Rpc(description = "Returns true if the device is in roaming state " + 809 "for specified subscription ID") 810 public Boolean telephonyCheckNetworkRoamingForSubscription( 811 @RpcParameter(name = "subId") Integer subId) { 812 return mTelephonyManager.isNetworkRoaming(subId); 813 } 814 815 @Rpc(description = "Returns the unique device ID such as MEID or IMEI " + 816 "for deault sim slot ID, null if unavailable") 817 public String telephonyGetDeviceId() { 818 return telephonyGetDeviceIdForSlotId(mTelephonyManager.getDefaultSim()); 819 } 820 821 @Rpc(description = "Returns the unique device ID such as MEID or IMEI for" + 822 " specified slot ID, null if unavailable") 823 public String telephonyGetDeviceIdForSlotId( 824 @RpcParameter(name = "slotId") 825 Integer slotId){ 826 return mTelephonyManager.getDeviceId(slotId); 827 } 828 829 @Rpc(description = "Returns the modem sw version, such as IMEI-SV;" + 830 " null if unavailable") 831 public String telephonyGetDeviceSoftwareVersion() { 832 return mTelephonyManager.getDeviceSoftwareVersion(); 833 } 834 835 @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " + 836 "for default subscription ID; null if unavailable") 837 public String telephonyGetLine1Number() { 838 return mTelephonyManager.getLine1Number(); 839 } 840 841 @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " + 842 "for specified subscription ID; null if unavailable") 843 public String telephonyGetLine1NumberForSubscription( 844 @RpcParameter(name = "subId") Integer subId) { 845 return mTelephonyManager.getLine1Number(subId); 846 } 847 848 @Rpc(description = "Returns the Alpha Tag for the default subscription " + 849 "ID; null if unavailable") 850 public String telephonyGetLine1AlphaTag() { 851 return mTelephonyManager.getLine1AlphaTag(); 852 } 853 854 @Rpc(description = "Returns the Alpha Tag for the specified subscription " + 855 "ID; null if unavailable") 856 public String telephonyGetLine1AlphaTagForSubscription( 857 @RpcParameter(name = "subId") Integer subId) { 858 return mTelephonyManager.getLine1AlphaTag(subId); 859 } 860 861 @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" + 862 "for the default subscription") 863 public Boolean telephonySetLine1Number( 864 @RpcParameter(name = "number") String number, 865 @RpcOptional 866 @RpcParameter(name = "alphaTag") String alphaTag) { 867 return mTelephonyManager.setLine1NumberForDisplay(alphaTag, number); 868 } 869 870 @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" + 871 "for the specified subscription") 872 public Boolean telephonySetLine1NumberForSubscription( 873 @RpcParameter(name = "subId") Integer subId, 874 @RpcParameter(name = "number") String number, 875 @RpcOptional 876 @RpcParameter(name = "alphaTag") String alphaTag) { 877 return mTelephonyManager.setLine1NumberForDisplay(subId, alphaTag, number); 878 } 879 880 @Rpc(description = "Returns the neighboring cell information of the device.") 881 public List<NeighboringCellInfo> telephonyGetNeighboringCellInfo() { 882 return mTelephonyManager.getNeighboringCellInfo(); 883 } 884 885 @Rpc(description = "Sets the minimum reporting interval for CellInfo" + 886 "0-as quickly as possible, 0x7FFFFFF-off") 887 public void telephonySetCellInfoListRate( 888 @RpcParameter(name = "rate") Integer rate 889 ) { 890 mTelephonyManager.setCellInfoListRate(rate); 891 } 892 893 @Rpc(description = "Returns all observed cell information from all radios"+ 894 "on the device including the primary and neighboring cells") 895 public List<CellInfo> telephonyGetAllCellInfo() { 896 return mTelephonyManager.getAllCellInfo(); 897 } 898 899 @Rpc(description = "Returns True if cellular data is enabled for" + 900 "default data subscription ID.") 901 public Boolean telephonyIsDataEnabled() { 902 return telephonyIsDataEnabledForSubscription( 903 SubscriptionManager.getDefaultDataSubscriptionId()); 904 } 905 906 @Rpc(description = "Returns True if data connection is enabled.") 907 public Boolean telephonyIsDataEnabledForSubscription( 908 @RpcParameter(name = "subId") Integer subId) { 909 return mTelephonyManager.getDataEnabled(subId); 910 } 911 912 @Rpc(description = "Toggles data connection on /off for" + 913 " default data subscription ID.") 914 public void telephonyToggleDataConnection( 915 @RpcParameter(name = "enabled") 916 @RpcOptional Boolean enabled) { 917 telephonyToggleDataConnectionForSubscription( 918 SubscriptionManager.getDefaultDataSubscriptionId(), enabled); 919 } 920 921 @Rpc(description = "Toggles data connection on/off for" + 922 " specified subscription ID") 923 public void telephonyToggleDataConnectionForSubscription( 924 @RpcParameter(name = "subId") Integer subId, 925 @RpcParameter(name = "enabled") 926 @RpcOptional Boolean enabled) { 927 if (enabled == null) { 928 enabled = !telephonyIsDataEnabledForSubscription(subId); 929 } 930 mTelephonyManager.setDataEnabled(subId, enabled); 931 } 932 933 @Rpc(description = "Sets an APN and make that as preferred APN.") 934 public void telephonySetAPN(@RpcParameter(name = "name") final String name, 935 @RpcParameter(name = "apn") final String apn, 936 @RpcParameter(name = "type") @RpcOptional @RpcDefault("") 937 final String type, 938 @RpcParameter(name = "subId") @RpcOptional Integer subId) { 939 //TODO: b/26273471 Need to find out how to set APN for specific subId 940 Uri uri; 941 Cursor cursor; 942 943 String mcc = ""; 944 String mnc = ""; 945 946 String numeric = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC); 947 // MCC is first 3 chars and then in 2 - 3 chars of MNC 948 if (numeric != null && numeric.length() > 4) { 949 // Country code 950 mcc = numeric.substring(0, 3); 951 // Network code 952 mnc = numeric.substring(3); 953 } 954 955 uri = mService.getContentResolver().insert( 956 Telephony.Carriers.CONTENT_URI, new ContentValues()); 957 if (uri == null) { 958 Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI); 959 return; 960 } 961 962 cursor = mService.getContentResolver().query(uri, sProjection, null, null, null); 963 cursor.moveToFirst(); 964 965 ContentValues values = new ContentValues(); 966 967 values.put(Telephony.Carriers.NAME, name); 968 values.put(Telephony.Carriers.APN, apn); 969 values.put(Telephony.Carriers.PROXY, ""); 970 values.put(Telephony.Carriers.PORT, ""); 971 values.put(Telephony.Carriers.MMSPROXY, ""); 972 values.put(Telephony.Carriers.MMSPORT, ""); 973 values.put(Telephony.Carriers.USER, ""); 974 values.put(Telephony.Carriers.SERVER, ""); 975 values.put(Telephony.Carriers.PASSWORD, ""); 976 values.put(Telephony.Carriers.MMSC, ""); 977 values.put(Telephony.Carriers.TYPE, type); 978 values.put(Telephony.Carriers.MCC, mcc); 979 values.put(Telephony.Carriers.MNC, mnc); 980 values.put(Telephony.Carriers.NUMERIC, mcc + mnc); 981 982 int ret = mService.getContentResolver().update(uri, values, null, null); 983 Log.d("after update " + ret); 984 cursor.close(); 985 986 // Make this APN as the preferred 987 String where = "name=\"" + name + "\""; 988 989 Cursor c = mService.getContentResolver().query( 990 Telephony.Carriers.CONTENT_URI, 991 new String[] { 992 "_id", "name", "apn", "type" 993 }, where, null, 994 Telephony.Carriers.DEFAULT_SORT_ORDER); 995 if (c != null) { 996 c.moveToFirst(); 997 String key = c.getString(0); 998 final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn"; 999 ContentResolver resolver = mService.getContentResolver(); 1000 ContentValues prefAPN = new ContentValues(); 1001 prefAPN.put("apn_id", key); 1002 resolver.update(Uri.parse(PREFERRED_APN_URI), prefAPN, null, null); 1003 } 1004 c.close(); 1005 } 1006 1007 @Rpc(description = "Returns the number of APNs defined") 1008 public int telephonyGetNumberOfAPNs( 1009 @RpcParameter(name = "subId") 1010 @RpcOptional Integer subId) { 1011 //TODO: b/26273471 Need to find out how to get Number of APNs for specific subId 1012 int result = 0; 1013 String where = "numeric=\"" + android.os.SystemProperties.get( 1014 TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\""; 1015 1016 Cursor cursor = mService.getContentResolver().query( 1017 Telephony.Carriers.CONTENT_URI, 1018 new String[] {"_id", "name", "apn", "type"}, where, null, 1019 Telephony.Carriers.DEFAULT_SORT_ORDER); 1020 1021 if (cursor != null) { 1022 result = cursor.getCount(); 1023 } 1024 cursor.close(); 1025 return result; 1026 } 1027 1028 @Rpc(description = "Returns the currently selected APN name") 1029 public String telephonyGetSelectedAPN( 1030 @RpcParameter(name = "subId") 1031 @RpcOptional Integer subId) { 1032 //TODO: b/26273471 Need to find out how to get selected APN for specific subId 1033 String key = null; 1034 int ID_INDEX = 0; 1035 final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn"; 1036 1037 Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI), 1038 new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER); 1039 1040 if (cursor.getCount() > 0) { 1041 cursor.moveToFirst(); 1042 key = cursor.getString(ID_INDEX); 1043 } 1044 cursor.close(); 1045 return key; 1046 } 1047 1048 @Rpc(description = "Returns the current data connection state") 1049 public String telephonyGetDataConnectionState() { 1050 return TelephonyUtils.getDataConnectionStateString( 1051 mTelephonyManager.getDataState()); 1052 } 1053 1054 @Rpc(description = "Enables or Disables Video Calling()") 1055 public void telephonyEnableVideoCalling( 1056 @RpcParameter(name = "enable") boolean enable) { 1057 mTelephonyManager.enableVideoCalling(enable); 1058 } 1059 1060 @Rpc(description = "Returns a boolean of whether or not " + 1061 "video calling setting is enabled by the user") 1062 public Boolean telephonyIsVideoCallingEnabled() { 1063 return mTelephonyManager.isVideoCallingEnabled(); 1064 } 1065 1066 @Rpc(description = "Returns a boolean of whether video calling is available for use") 1067 public Boolean telephonyIsVideoCallingAvailable() { 1068 return mTelephonyManager.isVideoTelephonyAvailable(); 1069 } 1070 1071 @Rpc(description = "Returns a boolean of whether or not the device is ims registered") 1072 public Boolean telephonyIsImsRegistered() { 1073 return mTelephonyManager.isImsRegistered(); 1074 } 1075 1076 @Rpc(description = "Returns a boolean of whether or not volte calling is available for use") 1077 public Boolean telephonyIsVolteAvailable() { 1078 return mTelephonyManager.isVolteAvailable(); 1079 } 1080 1081 @Rpc(description = "Returns a boolean of whether or not wifi calling is available for use") 1082 public Boolean telephonyIsWifiCallingAvailable() { 1083 return mTelephonyManager.isWifiCallingAvailable(); 1084 } 1085 1086 @Rpc(description = "Returns the service state for default subscription ID") 1087 public String telephonyGetServiceState() { 1088 //TODO: b/26273807 need to have framework API to get service state. 1089 return telephonyGetServiceStateForSubscription( 1090 SubscriptionManager.getDefaultSubscriptionId()); 1091 } 1092 1093 @Rpc(description = "Returns the service state for specified subscription ID") 1094 public String telephonyGetServiceStateForSubscription( 1095 @RpcParameter(name = "subId") Integer subId) { 1096 //TODO: b/26273807 need to have framework API to get service state. 1097 return null; 1098 } 1099 1100 @Rpc(description = "Returns the call state for default subscription ID") 1101 public String telephonyGetCallState() { 1102 return telephonyGetCallStateForSubscription( 1103 SubscriptionManager.getDefaultSubscriptionId()); 1104 } 1105 1106 @Rpc(description = "Returns the call state for specified subscription ID") 1107 public String telephonyGetCallStateForSubscription( 1108 @RpcParameter(name = "subId") Integer subId) { 1109 return TelephonyUtils.getTelephonyCallStateString( 1110 mTelephonyManager.getCallState(subId)); 1111 } 1112 1113 @Rpc(description = "Returns current signal strength for default subscription ID.") 1114 public SignalStrength telephonyGetSignalStrength() { 1115 return telephonyGetSignalStrengthForSubscription( 1116 SubscriptionManager.getDefaultSubscriptionId()); 1117 } 1118 1119 @Rpc(description = "Returns current signal strength for specified subscription ID.") 1120 public SignalStrength telephonyGetSignalStrengthForSubscription( 1121 @RpcParameter(name = "subId") Integer subId) { 1122 StateChangeListener listener = getStateChangeListenerForSubscription(subId, false); 1123 if(listener == null) { 1124 Log.e("Invalid subscription ID"); 1125 return null; 1126 } 1127 return listener.mSignalStrengthChangeListener.mSignalStrengths; 1128 } 1129 1130 @Rpc(description = "Returns the sim count.") 1131 public int telephonyGetSimCount() { 1132 return mTelephonyManager.getSimCount(); 1133 } 1134 1135 private StateChangeListener getStateChangeListenerForSubscription( 1136 int subId, 1137 boolean createIfNeeded) { 1138 1139 if(mStateChangeListeners.get(subId) == null) { 1140 if(createIfNeeded == false) { 1141 return null; 1142 } 1143 1144 if(mSubscriptionManager.getActiveSubscriptionInfo(subId) == null) { 1145 Log.e("Cannot get listener for invalid/inactive subId"); 1146 return null; 1147 } 1148 1149 mStateChangeListeners.put(subId, new StateChangeListener(subId)); 1150 } 1151 1152 return mStateChangeListeners.get(subId); 1153 } 1154 1155 //FIXME: This whole class needs reworking. Why do we have separate listeners for everything? 1156 //We need one listener that overrides multiple methods. 1157 private final class StateChangeListener { 1158 public ServiceStateChangeListener mServiceStateChangeListener; 1159 public SignalStrengthChangeListener mSignalStrengthChangeListener; 1160 public CallStateChangeListener mCallStateChangeListener; 1161 public CellInfoChangeListener mCellInfoChangeListener; 1162 public DataConnectionStateChangeListener mDataConnectionStateChangeListener; 1163 public DataConnectionRealTimeInfoChangeListener mDataConnectionRTInfoChangeListener; 1164 public VoiceMailStateChangeListener mVoiceMailStateChangeListener; 1165 1166 public StateChangeListener(int subId) { 1167 mServiceStateChangeListener = 1168 new ServiceStateChangeListener(mEventFacade, subId, mService.getMainLooper()); 1169 mSignalStrengthChangeListener = 1170 new SignalStrengthChangeListener(mEventFacade, subId, mService.getMainLooper()); 1171 mDataConnectionStateChangeListener = 1172 new DataConnectionStateChangeListener( 1173 mEventFacade, mTelephonyManager, subId, mService.getMainLooper()); 1174 mCallStateChangeListener = 1175 new CallStateChangeListener(mEventFacade, subId, mService.getMainLooper()); 1176 mCellInfoChangeListener = 1177 new CellInfoChangeListener(mEventFacade, subId, mService.getMainLooper()); 1178 mDataConnectionRTInfoChangeListener = 1179 new DataConnectionRealTimeInfoChangeListener( 1180 mEventFacade, subId, mService.getMainLooper()); 1181 mVoiceMailStateChangeListener = 1182 new VoiceMailStateChangeListener(mEventFacade, subId, mService.getMainLooper()); 1183 } 1184 1185 public void shutdown() { 1186 mTelephonyManager.listen( 1187 mServiceStateChangeListener, 1188 PhoneStateListener.LISTEN_NONE); 1189 mTelephonyManager.listen( 1190 mSignalStrengthChangeListener, 1191 PhoneStateListener.LISTEN_NONE); 1192 mTelephonyManager.listen( 1193 mCallStateChangeListener, 1194 PhoneStateListener.LISTEN_NONE); 1195 mTelephonyManager.listen( 1196 mCellInfoChangeListener, 1197 PhoneStateListener.LISTEN_NONE); 1198 mTelephonyManager.listen( 1199 mDataConnectionStateChangeListener, 1200 PhoneStateListener.LISTEN_NONE); 1201 mTelephonyManager.listen( 1202 mDataConnectionRTInfoChangeListener, 1203 PhoneStateListener.LISTEN_NONE); 1204 mTelephonyManager.listen( 1205 mVoiceMailStateChangeListener, 1206 PhoneStateListener.LISTEN_NONE); 1207 } 1208 1209 protected void finalize() { 1210 try { 1211 shutdown(); 1212 } catch(Exception e) {} 1213 } 1214 } 1215 1216 @Override 1217 public void shutdown() { 1218 for(StateChangeListener listener : mStateChangeListeners.values()) { 1219 listener.shutdown(); 1220 } 1221 } 1222 } 1223