DefaultPhoneNotifier.java revision d1a60dfe521f376e3500946d5371f126dbd36767
1/* 2 * Copyright (C) 2006 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 17package com.android.internal.telephony; 18 19import android.net.LinkProperties; 20import android.net.NetworkCapabilities; 21import android.os.Bundle; 22import android.os.RemoteException; 23import android.os.ServiceManager; 24import android.telephony.CellInfo; 25import android.telephony.DataConnectionRealTimeInfo; 26import android.telephony.Rlog; 27import android.telephony.VoLteServiceState; 28import android.telephony.ServiceState; 29import android.telephony.SubscriptionManager; 30import android.telephony.TelephonyManager; 31import android.telephony.PreciseCallState; 32import android.telephony.DisconnectCause; 33 34import com.android.internal.telephony.Call; 35import com.android.internal.telephony.CallManager; 36import com.android.internal.telephony.Phone; 37import com.android.internal.telephony.ITelephonyRegistry; 38import com.android.internal.telephony.PhoneConstants; 39 40import java.util.List; 41 42/** 43 * broadcast intents 44 */ 45public class DefaultPhoneNotifier implements PhoneNotifier { 46 private static final String LOG_TAG = "DefaultPhoneNotifier"; 47 private static final boolean DBG = false; // STOPSHIP if true 48 49 protected ITelephonyRegistry mRegistry; 50 51 /*package*/ 52 protected DefaultPhoneNotifier() { 53 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( 54 "telephony.registry")); 55 } 56 57 @Override 58 public void notifyPhoneState(Phone sender) { 59 Call ringingCall = sender.getRingingCall(); 60 long subId = sender.getSubId(); 61 String incomingNumber = ""; 62 if (ringingCall != null && ringingCall.getEarliestConnection() != null){ 63 incomingNumber = ringingCall.getEarliestConnection().getAddress(); 64 } 65 try { 66 if (mRegistry != null) { 67 mRegistry.notifyCallStateForSubscriber(subId, 68 convertCallState(sender.getState()), incomingNumber); 69 } 70 } catch (RemoteException ex) { 71 // system process is dead 72 } 73 notifyCallStateToTelephonyRegistry(sender); 74 } 75 76 /* 77 * Suppose, some third party app e.g. FM app registers for a call state changed indication 78 * through TelephonyManager/PhoneStateListener and an incoming call is received on sub1 or 79 * sub2. Then ir-respective of sub1/sub2 FM app should be informed of call state 80 * changed(onCallStateChanged()) indication so that FM app can be paused. 81 * Hence send consolidated call state information to apps. (i.e. sub1 or sub2 active 82 * call state, in priority order RINGING > OFFHOOK > IDLE) 83 */ 84 public void notifyCallStateToTelephonyRegistry(Phone sender) { 85 Call ringingCall = null; 86 CallManager cm = CallManager.getInstance(); 87 PhoneConstants.State state = sender.getState(); 88 String incomingNumber = ""; 89 for (Phone phone : cm.getAllPhones()) { 90 if (phone.getState() == PhoneConstants.State.RINGING) { 91 ringingCall = phone.getRingingCall(); 92 if (ringingCall != null && ringingCall.getEarliestConnection() != null) { 93 incomingNumber = ringingCall.getEarliestConnection().getAddress(); 94 } 95 sender = phone; 96 state = PhoneConstants.State.RINGING; 97 break; 98 } else if (phone.getState() == PhoneConstants.State.OFFHOOK) { 99 if (state == PhoneConstants.State.IDLE) { 100 state = PhoneConstants.State.OFFHOOK; 101 sender = phone; 102 } 103 } 104 } 105 if (DBG) log("notifyCallStateToTelephonyRegistry, subId = " + sender.getSubId() 106 + " state = " + state); 107 try { 108 if (mRegistry != null) { 109 mRegistry.notifyCallState(convertCallState(state), incomingNumber); 110 } 111 } catch (RemoteException ex) { 112 // system process is dead 113 } 114 } 115 116 @Override 117 public void notifyServiceState(Phone sender) { 118 ServiceState ss = sender.getServiceState(); 119 int phoneId = sender.getPhoneId(); 120 long subId = sender.getSubId(); 121 122 Rlog.d(LOG_TAG, "nofityServiceState: mRegistry=" + mRegistry + " ss=" + ss 123 + " sender=" + sender + " phondId=" + phoneId + " subId=" + subId); 124 if (ss == null) { 125 ss = new ServiceState(); 126 ss.setStateOutOfService(); 127 } 128 try { 129 if (mRegistry != null) { 130 mRegistry.notifyServiceStateForPhoneId(phoneId, subId, ss); 131 } 132 } catch (RemoteException ex) { 133 // system process is dead 134 } 135 } 136 137 @Override 138 public void notifySignalStrength(Phone sender) { 139 long subId = sender.getSubId(); 140 Rlog.d(LOG_TAG, "notifySignalStrength: mRegistry=" + mRegistry 141 + " ss=" + sender.getSignalStrength() + " sender=" + sender); 142 try { 143 if (mRegistry != null) { 144 mRegistry.notifySignalStrengthForSubscriber(subId, sender.getSignalStrength()); 145 } 146 } catch (RemoteException ex) { 147 // system process is dead 148 } 149 } 150 151 @Override 152 public void notifyMessageWaitingChanged(Phone sender) { 153 int phoneId = sender.getPhoneId(); 154 long subId = sender.getSubId(); 155 156 try { 157 if (mRegistry != null) { 158 mRegistry.notifyMessageWaitingChangedForPhoneId(phoneId, subId, 159 sender.getMessageWaitingIndicator()); 160 } 161 } catch (RemoteException ex) { 162 // system process is dead 163 } 164 } 165 166 @Override 167 public void notifyCallForwardingChanged(Phone sender) { 168 long subId = sender.getSubId(); 169 try { 170 if (mRegistry != null) { 171 mRegistry.notifyCallForwardingChangedForSubscriber(subId, 172 sender.getCallForwardingIndicator()); 173 } 174 } catch (RemoteException ex) { 175 // system process is dead 176 } 177 } 178 179 @Override 180 public void notifyDataActivity(Phone sender) { 181 long subId = sender.getSubId(); 182 try { 183 if (mRegistry != null) { 184 mRegistry.notifyDataActivityForSubscriber(subId, 185 convertDataActivityState(sender.getDataActivityState())); 186 } 187 } catch (RemoteException ex) { 188 // system process is dead 189 } 190 } 191 192 @Override 193 public void notifyDataConnection(Phone sender, String reason, String apnType, 194 PhoneConstants.DataState state) { 195 doNotifyDataConnection(sender, reason, apnType, state); 196 } 197 198 private void doNotifyDataConnection(Phone sender, String reason, String apnType, 199 PhoneConstants.DataState state) { 200 long subId = sender.getSubId(); 201 long dds = SubscriptionManager.getDefaultDataSubId(); 202 if (DBG) log("subId = " + subId + ", DDS = " + dds); 203 204 // TODO 205 // use apnType as the key to which connection we're talking about. 206 // pass apnType back up to fetch particular for this one. 207 TelephonyManager telephony = TelephonyManager.getDefault(); 208 LinkProperties linkProperties = null; 209 NetworkCapabilities networkCapabilities = null; 210 boolean roaming = false; 211 212 if (state == PhoneConstants.DataState.CONNECTED) { 213 linkProperties = sender.getLinkProperties(apnType); 214 networkCapabilities = sender.getNetworkCapabilities(apnType); 215 } 216 ServiceState ss = sender.getServiceState(); 217 if (ss != null) roaming = ss.getRoaming(); 218 219 try { 220 if (mRegistry != null) { 221 mRegistry.notifyDataConnectionForSubscriber(subId, 222 convertDataState(state), 223 sender.isDataConnectivityPossible(apnType), reason, 224 sender.getActiveApnHost(apnType), 225 apnType, 226 linkProperties, 227 networkCapabilities, 228 ((telephony!=null) ? telephony.getNetworkType() : 229 TelephonyManager.NETWORK_TYPE_UNKNOWN), 230 roaming); 231 } 232 } catch (RemoteException ex) { 233 // system process is dead 234 } 235 } 236 237 @Override 238 public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { 239 long subId = sender.getSubId(); 240 try { 241 if (mRegistry != null) { 242 mRegistry.notifyDataConnectionFailedForSubscriber(subId, reason, apnType); 243 } 244 } catch (RemoteException ex) { 245 // system process is dead 246 } 247 } 248 249 @Override 250 public void notifyCellLocation(Phone sender) { 251 long subId = sender.getSubId(); 252 Bundle data = new Bundle(); 253 sender.getCellLocation().fillInNotifierBundle(data); 254 try { 255 if (mRegistry != null) { 256 mRegistry.notifyCellLocationForSubscriber(subId, data); 257 } 258 } catch (RemoteException ex) { 259 // system process is dead 260 } 261 } 262 263 @Override 264 public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) { 265 long subId = sender.getSubId(); 266 try { 267 if (mRegistry != null) { 268 mRegistry.notifyCellInfoForSubscriber(subId, cellInfo); 269 } 270 } catch (RemoteException ex) { 271 272 } 273 } 274 275 @Override 276 public void notifyDataConnectionRealTimeInfo(Phone sender, 277 DataConnectionRealTimeInfo dcRtInfo) { 278 try { 279 mRegistry.notifyDataConnectionRealTimeInfo(dcRtInfo); 280 } catch (RemoteException ex) { 281 282 } 283 } 284 285 @Override 286 public void notifyOtaspChanged(Phone sender, int otaspMode) { 287 // FIXME: subId? 288 try { 289 if (mRegistry != null) { 290 mRegistry.notifyOtaspChanged(otaspMode); 291 } 292 } catch (RemoteException ex) { 293 // system process is dead 294 } 295 } 296 297 public void notifyPreciseCallState(Phone sender) { 298 // FIXME: subId? 299 Call ringingCall = sender.getRingingCall(); 300 Call foregroundCall = sender.getForegroundCall(); 301 Call backgroundCall = sender.getBackgroundCall(); 302 if (ringingCall != null && foregroundCall != null && backgroundCall != null) { 303 try { 304 mRegistry.notifyPreciseCallState( 305 convertPreciseCallState(ringingCall.getState()), 306 convertPreciseCallState(foregroundCall.getState()), 307 convertPreciseCallState(backgroundCall.getState())); 308 } catch (RemoteException ex) { 309 // system process is dead 310 } 311 } 312 } 313 314 public void notifyDisconnectCause(int cause, int preciseCause) { 315 // FIXME: subId? 316 try { 317 mRegistry.notifyDisconnectCause(cause, preciseCause); 318 } catch (RemoteException ex) { 319 // system process is dead 320 } 321 } 322 323 public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType, 324 String apn, String failCause) { 325 // FIXME: subId? 326 try { 327 mRegistry.notifyPreciseDataConnectionFailed(reason, apnType, apn, failCause); 328 } catch (RemoteException ex) { 329 // system process is dead 330 } 331 } 332 333 @Override 334 public void notifyVoLteServiceStateChanged(Phone sender, VoLteServiceState lteState) { 335 // FIXME: subID 336 try { 337 mRegistry.notifyVoLteServiceStateChanged(lteState); 338 } catch (RemoteException ex) { 339 // system process is dead 340 } 341 } 342 343 /** 344 * Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_* 345 * constants for the public API. 346 */ 347 public static int convertCallState(PhoneConstants.State state) { 348 switch (state) { 349 case RINGING: 350 return TelephonyManager.CALL_STATE_RINGING; 351 case OFFHOOK: 352 return TelephonyManager.CALL_STATE_OFFHOOK; 353 default: 354 return TelephonyManager.CALL_STATE_IDLE; 355 } 356 } 357 358 /** 359 * Convert the TelephonyManager.CALL_STATE_* constants into the 360 * {@link PhoneConstants.State} enum for the public API. 361 */ 362 public static PhoneConstants.State convertCallState(int state) { 363 switch (state) { 364 case TelephonyManager.CALL_STATE_RINGING: 365 return PhoneConstants.State.RINGING; 366 case TelephonyManager.CALL_STATE_OFFHOOK: 367 return PhoneConstants.State.OFFHOOK; 368 default: 369 return PhoneConstants.State.IDLE; 370 } 371 } 372 373 /** 374 * Convert the {@link PhoneConstants.DataState} enum into the TelephonyManager.DATA_* constants 375 * for the public API. 376 */ 377 public static int convertDataState(PhoneConstants.DataState state) { 378 switch (state) { 379 case CONNECTING: 380 return TelephonyManager.DATA_CONNECTING; 381 case CONNECTED: 382 return TelephonyManager.DATA_CONNECTED; 383 case SUSPENDED: 384 return TelephonyManager.DATA_SUSPENDED; 385 default: 386 return TelephonyManager.DATA_DISCONNECTED; 387 } 388 } 389 390 /** 391 * Convert the TelephonyManager.DATA_* constants into {@link PhoneConstants.DataState} enum 392 * for the public API. 393 */ 394 public static PhoneConstants.DataState convertDataState(int state) { 395 switch (state) { 396 case TelephonyManager.DATA_CONNECTING: 397 return PhoneConstants.DataState.CONNECTING; 398 case TelephonyManager.DATA_CONNECTED: 399 return PhoneConstants.DataState.CONNECTED; 400 case TelephonyManager.DATA_SUSPENDED: 401 return PhoneConstants.DataState.SUSPENDED; 402 default: 403 return PhoneConstants.DataState.DISCONNECTED; 404 } 405 } 406 407 /** 408 * Convert the {@link Phone.DataActivityState} enum into the TelephonyManager.DATA_* constants 409 * for the public API. 410 */ 411 public static int convertDataActivityState(Phone.DataActivityState state) { 412 switch (state) { 413 case DATAIN: 414 return TelephonyManager.DATA_ACTIVITY_IN; 415 case DATAOUT: 416 return TelephonyManager.DATA_ACTIVITY_OUT; 417 case DATAINANDOUT: 418 return TelephonyManager.DATA_ACTIVITY_INOUT; 419 case DORMANT: 420 return TelephonyManager.DATA_ACTIVITY_DORMANT; 421 default: 422 return TelephonyManager.DATA_ACTIVITY_NONE; 423 } 424 } 425 426 /** 427 * Convert the TelephonyManager.DATA_* constants into the {@link Phone.DataActivityState} enum 428 * for the public API. 429 */ 430 public static Phone.DataActivityState convertDataActivityState(int state) { 431 switch (state) { 432 case TelephonyManager.DATA_ACTIVITY_IN: 433 return Phone.DataActivityState.DATAIN; 434 case TelephonyManager.DATA_ACTIVITY_OUT: 435 return Phone.DataActivityState.DATAOUT; 436 case TelephonyManager.DATA_ACTIVITY_INOUT: 437 return Phone.DataActivityState.DATAINANDOUT; 438 case TelephonyManager.DATA_ACTIVITY_DORMANT: 439 return Phone.DataActivityState.DORMANT; 440 default: 441 return Phone.DataActivityState.NONE; 442 } 443 } 444 445 /** 446 * Convert the {@link State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants 447 * for the public API. 448 */ 449 public static int convertPreciseCallState(Call.State state) { 450 switch (state) { 451 case ACTIVE: 452 return PreciseCallState.PRECISE_CALL_STATE_ACTIVE; 453 case HOLDING: 454 return PreciseCallState.PRECISE_CALL_STATE_HOLDING; 455 case DIALING: 456 return PreciseCallState.PRECISE_CALL_STATE_DIALING; 457 case ALERTING: 458 return PreciseCallState.PRECISE_CALL_STATE_ALERTING; 459 case INCOMING: 460 return PreciseCallState.PRECISE_CALL_STATE_INCOMING; 461 case WAITING: 462 return PreciseCallState.PRECISE_CALL_STATE_WAITING; 463 case DISCONNECTED: 464 return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED; 465 case DISCONNECTING: 466 return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING; 467 default: 468 return PreciseCallState.PRECISE_CALL_STATE_IDLE; 469 } 470 } 471 472 /** 473 * Convert the Call.State.* constants into the {@link State} enum 474 * for the public API. 475 */ 476 public static Call.State convertPreciseCallState(int state) { 477 switch (state) { 478 case PreciseCallState.PRECISE_CALL_STATE_ACTIVE: 479 return Call.State.ACTIVE; 480 case PreciseCallState.PRECISE_CALL_STATE_HOLDING: 481 return Call.State.HOLDING; 482 case PreciseCallState.PRECISE_CALL_STATE_DIALING: 483 return Call.State.DIALING; 484 case PreciseCallState.PRECISE_CALL_STATE_ALERTING: 485 return Call.State.ALERTING; 486 case PreciseCallState.PRECISE_CALL_STATE_INCOMING: 487 return Call.State.INCOMING; 488 case PreciseCallState.PRECISE_CALL_STATE_WAITING: 489 return Call.State.WAITING; 490 case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED: 491 return Call.State.DISCONNECTED; 492 case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING: 493 return Call.State.DISCONNECTING; 494 default: 495 return Call.State.IDLE; 496 } 497 } 498 499 public interface IDataStateChangedCallback { 500 void onDataStateChanged(long subId, String state, String reason, String apnName, 501 String apnType, boolean unavailable); 502 } 503 504 private void log(String s) { 505 Rlog.d(LOG_TAG, s); 506 } 507} 508