1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony; 18 19 import android.os.Bundle; 20 import android.os.Handler; 21 import android.os.Looper; 22 import android.os.Message; 23 import android.telephony.CellLocation; 24 import android.telephony.CellInfo; 25 import android.telephony.VoLteServiceState; 26 import android.telephony.Rlog; 27 import android.telephony.ServiceState; 28 import android.telephony.SignalStrength; 29 import android.telephony.SubscriptionManager; 30 import android.telephony.PreciseCallState; 31 import android.telephony.PreciseDataConnectionState; 32 33 import com.android.internal.telephony.IPhoneStateListener; 34 35 import java.util.List; 36 37 /** 38 * A listener class for monitoring changes in specific telephony states 39 * on the device, including service state, signal strength, message 40 * waiting indicator (voicemail), and others. 41 * <p> 42 * Override the methods for the state that you wish to receive updates for, and 43 * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ 44 * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. 45 * <p> 46 * Note that access to some telephony information is 47 * permission-protected. Your application won't receive updates for protected 48 * information unless it has the appropriate permissions declared in 49 * its manifest file. Where permissions apply, they are noted in the 50 * appropriate LISTEN_ flags. 51 */ 52 public class PhoneStateListener { 53 private static final String LOG_TAG = "PhoneStateListener"; 54 private static final boolean DBG = false; // STOPSHIP if true 55 56 /** 57 * Stop listening for updates. 58 */ 59 public static final int LISTEN_NONE = 0; 60 61 /** 62 * Listen for changes to the network service state (cellular). 63 * 64 * @see #onServiceStateChanged 65 * @see ServiceState 66 */ 67 public static final int LISTEN_SERVICE_STATE = 0x00000001; 68 69 /** 70 * Listen for changes to the network signal strength (cellular). 71 * {@more} 72 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE 73 * READ_PHONE_STATE} 74 * <p> 75 * 76 * @see #onSignalStrengthChanged 77 * 78 * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS} 79 */ 80 @Deprecated 81 public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; 82 83 /** 84 * Listen for changes to the message-waiting indicator. 85 * {@more} 86 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE 87 * READ_PHONE_STATE} 88 * <p> 89 * Example: The status bar uses this to determine when to display the 90 * voicemail icon. 91 * 92 * @see #onMessageWaitingIndicatorChanged 93 */ 94 public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; 95 96 /** 97 * Listen for changes to the call-forwarding indicator. 98 * {@more} 99 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE 100 * READ_PHONE_STATE} 101 * @see #onCallForwardingIndicatorChanged 102 */ 103 public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; 104 105 /** 106 * Listen for changes to the device's cell location. Note that 107 * this will result in frequent callbacks to the listener. 108 * {@more} 109 * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION 110 * ACCESS_COARSE_LOCATION} 111 * <p> 112 * If you need regular location updates but want more control over 113 * the update interval or location precision, you can set up a listener 114 * through the {@link android.location.LocationManager location manager} 115 * instead. 116 * 117 * @see #onCellLocationChanged 118 */ 119 public static final int LISTEN_CELL_LOCATION = 0x00000010; 120 121 /** 122 * Listen for changes to the device call state. 123 * {@more} 124 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE 125 * READ_PHONE_STATE} 126 * @see #onCallStateChanged 127 */ 128 public static final int LISTEN_CALL_STATE = 0x00000020; 129 130 /** 131 * Listen for changes to the data connection state (cellular). 132 * 133 * @see #onDataConnectionStateChanged 134 */ 135 public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; 136 137 /** 138 * Listen for changes to the direction of data traffic on the data 139 * connection (cellular). 140 * {@more} 141 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE 142 * READ_PHONE_STATE} 143 * Example: The status bar uses this to display the appropriate 144 * data-traffic icon. 145 * 146 * @see #onDataActivity 147 */ 148 public static final int LISTEN_DATA_ACTIVITY = 0x00000080; 149 150 /** 151 * Listen for changes to the network signal strengths (cellular). 152 * <p> 153 * Example: The status bar uses this to control the signal-strength 154 * icon. 155 * 156 * @see #onSignalStrengthsChanged 157 */ 158 public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; 159 160 /** 161 * Listen for changes to OTASP mode. 162 * 163 * @see #onOtaspChanged 164 * @hide 165 */ 166 public static final int LISTEN_OTASP_CHANGED = 0x00000200; 167 168 /** 169 * Listen for changes to observed cell info. 170 * 171 * @see #onCellInfoChanged 172 */ 173 public static final int LISTEN_CELL_INFO = 0x00000400; 174 175 /** 176 * Listen for precise changes and fails to the device calls (cellular). 177 * {@more} 178 * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE 179 * READ_PRECISE_PHONE_STATE} 180 * 181 * @hide 182 */ 183 public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800; 184 185 /** 186 * Listen for precise changes and fails on the data connection (cellular). 187 * {@more} 188 * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE 189 * READ_PRECISE_PHONE_STATE} 190 * 191 * @see #onPreciseDataConnectionStateChanged 192 * @hide 193 */ 194 public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; 195 196 /** 197 * Listen for real time info for all data connections (cellular)). 198 * {@more} 199 * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE 200 * READ_PRECISE_PHONE_STATE} 201 * 202 * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) 203 * @hide 204 */ 205 public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; 206 207 /** 208 * Listen for changes to LTE network state 209 * 210 * @see #onLteNetworkStateChanged 211 * @hide 212 */ 213 public static final int LISTEN_VOLTE_STATE = 0x00004000; 214 215 /** 216 * Listen for OEM hook raw event 217 * 218 * @see #onOemHookRawEvent 219 * @hide 220 */ 221 public static final int LISTEN_OEM_HOOK_RAW_EVENT = 0x00008000; 222 223 /* 224 * Subscription used to listen to the phone state changes 225 * @hide 226 */ 227 /** @hide */ 228 protected long mSubId = 0; 229 230 private final Handler mHandler; 231 232 /** 233 * Create a PhoneStateListener for the Phone with the default subscription. 234 * This class requires Looper.myLooper() not return null. To supply your 235 * own non-null looper use PhoneStateListener(Looper looper) below. 236 */ 237 public PhoneStateListener() { 238 this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper()); 239 } 240 241 /** 242 * Create a PhoneStateListener for the Phone with the default subscription 243 * using a particular non-null Looper. 244 * @hide 245 */ 246 public PhoneStateListener(Looper looper) { 247 this(SubscriptionManager.DEFAULT_SUB_ID, looper); 248 } 249 250 /** 251 * Create a PhoneStateListener for the Phone using the specified subscription. 252 * This class requires Looper.myLooper() not return null. To supply your 253 * own non-null Looper use PhoneStateListener(long subId, Looper looper) below. 254 * @hide 255 */ 256 public PhoneStateListener(long subId) { 257 this(subId, Looper.myLooper()); 258 } 259 260 /** 261 * Create a PhoneStateListener for the Phone using the specified subscription 262 * and non-null Looper. 263 * @hide 264 */ 265 public PhoneStateListener(long subId, Looper looper) { 266 if (DBG) log("ctor: subId=" + subId + " looper=" + looper); 267 mSubId = subId; 268 mHandler = new Handler(looper) { 269 public void handleMessage(Message msg) { 270 if (DBG) { 271 log("mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what) 272 + " msg=" + msg); 273 } 274 switch (msg.what) { 275 case LISTEN_SERVICE_STATE: 276 PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj); 277 break; 278 case LISTEN_SIGNAL_STRENGTH: 279 PhoneStateListener.this.onSignalStrengthChanged(msg.arg1); 280 break; 281 case LISTEN_MESSAGE_WAITING_INDICATOR: 282 PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0); 283 break; 284 case LISTEN_CALL_FORWARDING_INDICATOR: 285 PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0); 286 break; 287 case LISTEN_CELL_LOCATION: 288 PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj); 289 break; 290 case LISTEN_CALL_STATE: 291 PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj); 292 break; 293 case LISTEN_DATA_CONNECTION_STATE: 294 PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2); 295 PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1); 296 break; 297 case LISTEN_DATA_ACTIVITY: 298 PhoneStateListener.this.onDataActivity(msg.arg1); 299 break; 300 case LISTEN_SIGNAL_STRENGTHS: 301 PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj); 302 break; 303 case LISTEN_OTASP_CHANGED: 304 PhoneStateListener.this.onOtaspChanged(msg.arg1); 305 break; 306 case LISTEN_CELL_INFO: 307 PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj); 308 break; 309 case LISTEN_PRECISE_CALL_STATE: 310 PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj); 311 break; 312 case LISTEN_PRECISE_DATA_CONNECTION_STATE: 313 PhoneStateListener.this.onPreciseDataConnectionStateChanged( 314 (PreciseDataConnectionState)msg.obj); 315 break; 316 case LISTEN_DATA_CONNECTION_REAL_TIME_INFO: 317 PhoneStateListener.this.onDataConnectionRealTimeInfoChanged( 318 (DataConnectionRealTimeInfo)msg.obj); 319 break; 320 case LISTEN_VOLTE_STATE: 321 PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj); 322 break; 323 case LISTEN_OEM_HOOK_RAW_EVENT: 324 PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj); 325 break; 326 327 } 328 } 329 }; 330 } 331 332 /** 333 * Callback invoked when device service state changes. 334 * 335 * @see ServiceState#STATE_EMERGENCY_ONLY 336 * @see ServiceState#STATE_IN_SERVICE 337 * @see ServiceState#STATE_OUT_OF_SERVICE 338 * @see ServiceState#STATE_POWER_OFF 339 */ 340 public void onServiceStateChanged(ServiceState serviceState) { 341 // default implementation empty 342 } 343 344 /** 345 * Callback invoked when network signal strength changes. 346 * 347 * @see ServiceState#STATE_EMERGENCY_ONLY 348 * @see ServiceState#STATE_IN_SERVICE 349 * @see ServiceState#STATE_OUT_OF_SERVICE 350 * @see ServiceState#STATE_POWER_OFF 351 * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)} 352 */ 353 @Deprecated 354 public void onSignalStrengthChanged(int asu) { 355 // default implementation empty 356 } 357 358 /** 359 * Callback invoked when the message-waiting indicator changes. 360 */ 361 public void onMessageWaitingIndicatorChanged(boolean mwi) { 362 // default implementation empty 363 } 364 365 /** 366 * Callback invoked when the call-forwarding indicator changes. 367 */ 368 public void onCallForwardingIndicatorChanged(boolean cfi) { 369 // default implementation empty 370 } 371 372 /** 373 * Callback invoked when device cell location changes. 374 */ 375 public void onCellLocationChanged(CellLocation location) { 376 // default implementation empty 377 } 378 379 /** 380 * Callback invoked when device call state changes. 381 * 382 * @see TelephonyManager#CALL_STATE_IDLE 383 * @see TelephonyManager#CALL_STATE_RINGING 384 * @see TelephonyManager#CALL_STATE_OFFHOOK 385 */ 386 public void onCallStateChanged(int state, String incomingNumber) { 387 // default implementation empty 388 } 389 390 /** 391 * Callback invoked when connection state changes. 392 * 393 * @see TelephonyManager#DATA_DISCONNECTED 394 * @see TelephonyManager#DATA_CONNECTING 395 * @see TelephonyManager#DATA_CONNECTED 396 * @see TelephonyManager#DATA_SUSPENDED 397 */ 398 public void onDataConnectionStateChanged(int state) { 399 // default implementation empty 400 } 401 402 /** 403 * same as above, but with the network type. Both called. 404 */ 405 public void onDataConnectionStateChanged(int state, int networkType) { 406 } 407 408 /** 409 * Callback invoked when data activity state changes. 410 * 411 * @see TelephonyManager#DATA_ACTIVITY_NONE 412 * @see TelephonyManager#DATA_ACTIVITY_IN 413 * @see TelephonyManager#DATA_ACTIVITY_OUT 414 * @see TelephonyManager#DATA_ACTIVITY_INOUT 415 * @see TelephonyManager#DATA_ACTIVITY_DORMANT 416 */ 417 public void onDataActivity(int direction) { 418 // default implementation empty 419 } 420 421 /** 422 * Callback invoked when network signal strengths changes. 423 * 424 * @see ServiceState#STATE_EMERGENCY_ONLY 425 * @see ServiceState#STATE_IN_SERVICE 426 * @see ServiceState#STATE_OUT_OF_SERVICE 427 * @see ServiceState#STATE_POWER_OFF 428 */ 429 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 430 // default implementation empty 431 } 432 433 434 /** 435 * The Over The Air Service Provisioning (OTASP) has changed. Requires 436 * the READ_PHONE_STATE permission. 437 * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code> 438 * means the value is currently unknown and the system should wait until 439 * <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before 440 * making the decision to perform OTASP or not. 441 * 442 * @hide 443 */ 444 public void onOtaspChanged(int otaspMode) { 445 // default implementation empty 446 } 447 448 /** 449 * Callback invoked when a observed cell info has changed, 450 * or new cells have been added or removed. 451 * @param cellInfo is the list of currently visible cells. 452 */ 453 public void onCellInfoChanged(List<CellInfo> cellInfo) { 454 } 455 456 /** 457 * Callback invoked when precise device call state changes. 458 * 459 * @hide 460 */ 461 public void onPreciseCallStateChanged(PreciseCallState callState) { 462 // default implementation empty 463 } 464 465 /** 466 * Callback invoked when data connection state changes with precise information. 467 * 468 * @hide 469 */ 470 public void onPreciseDataConnectionStateChanged( 471 PreciseDataConnectionState dataConnectionState) { 472 // default implementation empty 473 } 474 475 /** 476 * Callback invoked when data connection state changes with precise information. 477 * 478 * @hide 479 */ 480 public void onDataConnectionRealTimeInfoChanged( 481 DataConnectionRealTimeInfo dcRtInfo) { 482 // default implementation empty 483 } 484 485 /** 486 * Callback invoked when the service state of LTE network 487 * related to the VoLTE service has changed. 488 * @param stateInfo is the current LTE network information 489 * @hide 490 */ 491 public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) { 492 } 493 494 /** 495 * Callback invoked when OEM hook raw event is received. Requires 496 * the READ_PRIVILEGED_PHONE_STATE permission. 497 * @param rawData is the byte array of the OEM hook raw data. 498 * @hide 499 */ 500 public void onOemHookRawEvent(byte[] rawData) { 501 // default implementation empty 502 } 503 504 /** 505 * The callback methods need to be called on the handler thread where 506 * this object was created. If the binder did that for us it'd be nice. 507 */ 508 IPhoneStateListener callback = new IPhoneStateListener.Stub() { 509 public void onServiceStateChanged(ServiceState serviceState) { 510 Message.obtain(mHandler, LISTEN_SERVICE_STATE, 0, 0, serviceState).sendToTarget(); 511 } 512 513 public void onSignalStrengthChanged(int asu) { 514 Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTH, asu, 0, null).sendToTarget(); 515 } 516 517 public void onMessageWaitingIndicatorChanged(boolean mwi) { 518 Message.obtain(mHandler, LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null) 519 .sendToTarget(); 520 } 521 522 public void onCallForwardingIndicatorChanged(boolean cfi) { 523 Message.obtain(mHandler, LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null) 524 .sendToTarget(); 525 } 526 527 public void onCellLocationChanged(Bundle bundle) { 528 CellLocation location = CellLocation.newFromBundle(bundle); 529 Message.obtain(mHandler, LISTEN_CELL_LOCATION, 0, 0, location).sendToTarget(); 530 } 531 532 public void onCallStateChanged(int state, String incomingNumber) { 533 Message.obtain(mHandler, LISTEN_CALL_STATE, state, 0, incomingNumber).sendToTarget(); 534 } 535 536 public void onDataConnectionStateChanged(int state, int networkType) { 537 Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType). 538 sendToTarget(); 539 } 540 541 public void onDataActivity(int direction) { 542 Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget(); 543 } 544 545 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 546 Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength).sendToTarget(); 547 } 548 549 public void onOtaspChanged(int otaspMode) { 550 Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget(); 551 } 552 553 public void onCellInfoChanged(List<CellInfo> cellInfo) { 554 Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0, cellInfo).sendToTarget(); 555 } 556 557 public void onPreciseCallStateChanged(PreciseCallState callState) { 558 Message.obtain(mHandler, LISTEN_PRECISE_CALL_STATE, 0, 0, callState).sendToTarget(); 559 } 560 561 public void onPreciseDataConnectionStateChanged( 562 PreciseDataConnectionState dataConnectionState) { 563 Message.obtain(mHandler, LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, 564 dataConnectionState).sendToTarget(); 565 } 566 567 public void onDataConnectionRealTimeInfoChanged( 568 DataConnectionRealTimeInfo dcRtInfo) { 569 Message.obtain(mHandler, LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, 570 dcRtInfo).sendToTarget(); 571 } 572 573 public void onVoLteServiceStateChanged(VoLteServiceState lteState) { 574 Message.obtain(mHandler, LISTEN_VOLTE_STATE, 0, 0, lteState).sendToTarget(); 575 } 576 577 public void onOemHookRawEvent(byte[] rawData) { 578 Message.obtain(mHandler, LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData).sendToTarget(); 579 } 580 }; 581 582 private void log(String s) { 583 Rlog.d(LOG_TAG, s); 584 } 585 } 586