DefaultPhoneNotifier.java revision d2c79d28884203ad4f13ebdf443b3899d56b93d6
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.notifyCallStateUsingSubId(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 long subId = sender.getSubId(); 120 Rlog.d(LOG_TAG, "nofityServiceState: mRegistry=" + mRegistry + " ss=" + ss 121 + " sender=" + sender); 122 if (ss == null) { 123 ss = new ServiceState(); 124 ss.setStateOutOfService(); 125 } 126 try { 127 if (mRegistry != null) { 128 mRegistry.notifyServiceStateUsingSubId(subId, ss); 129 } 130 } catch (RemoteException ex) { 131 // system process is dead 132 } 133 } 134 135 @Override 136 public void notifySignalStrength(Phone sender) { 137 long subId = sender.getSubId(); 138 Rlog.d(LOG_TAG, "notifySignalStrength: mRegistry=" + mRegistry 139 + " ss=" + sender.getSignalStrength() + " sender=" + sender); 140 try { 141 if (mRegistry != null) { 142 mRegistry.notifySignalStrengthUsingSubId(subId, sender.getSignalStrength()); 143 } 144 } catch (RemoteException ex) { 145 // system process is dead 146 } 147 } 148 149 @Override 150 public void notifyMessageWaitingChanged(Phone sender) { 151 long subId = sender.getSubId(); 152 try { 153 if (mRegistry != null) { 154 mRegistry.notifyMessageWaitingChangedUsingSubId(subId, 155 sender.getMessageWaitingIndicator()); 156 } 157 } catch (RemoteException ex) { 158 // system process is dead 159 } 160 } 161 162 @Override 163 public void notifyCallForwardingChanged(Phone sender) { 164 long subId = sender.getSubId(); 165 try { 166 if (mRegistry != null) { 167 mRegistry.notifyCallForwardingChangedUsingSubId(subId, 168 sender.getCallForwardingIndicator()); 169 } 170 } catch (RemoteException ex) { 171 // system process is dead 172 } 173 } 174 175 @Override 176 public void notifyDataActivity(Phone sender) { 177 long subId = sender.getSubId(); 178 try { 179 if (mRegistry != null) { 180 mRegistry.notifyDataActivityUsingSubId(subId, 181 convertDataActivityState(sender.getDataActivityState())); 182 } 183 } catch (RemoteException ex) { 184 // system process is dead 185 } 186 } 187 188 @Override 189 public void notifyDataConnection(Phone sender, String reason, String apnType, 190 PhoneConstants.DataState state) { 191 doNotifyDataConnection(sender, reason, apnType, state); 192 } 193 194 private void doNotifyDataConnection(Phone sender, String reason, String apnType, 195 PhoneConstants.DataState state) { 196 long subId = sender.getSubId(); 197 long dds = SubscriptionManager.getDefaultDataSubId(); 198 if (DBG) log("subId = " + subId + ", DDS = " + dds); 199 200 // TODO 201 // use apnType as the key to which connection we're talking about. 202 // pass apnType back up to fetch particular for this one. 203 TelephonyManager telephony = TelephonyManager.getDefault(); 204 LinkProperties linkProperties = null; 205 NetworkCapabilities networkCapabilities = null; 206 boolean roaming = false; 207 208 if (state == PhoneConstants.DataState.CONNECTED) { 209 linkProperties = sender.getLinkProperties(apnType); 210 networkCapabilities = sender.getNetworkCapabilities(apnType); 211 } 212 ServiceState ss = sender.getServiceState(); 213 if (ss != null) roaming = ss.getRoaming(); 214 215 try { 216 if (mRegistry != null) { 217 mRegistry.notifyDataConnectionUsingSubId(subId, 218 convertDataState(state), 219 sender.isDataConnectivityPossible(apnType), reason, 220 sender.getActiveApnHost(apnType), 221 apnType, 222 linkProperties, 223 networkCapabilities, 224 ((telephony!=null) ? telephony.getNetworkType() : 225 TelephonyManager.NETWORK_TYPE_UNKNOWN), 226 roaming); 227 } 228 } catch (RemoteException ex) { 229 // system process is dead 230 } 231 } 232 233 @Override 234 public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { 235 long subId = sender.getSubId(); 236 try { 237 if (mRegistry != null) { 238 mRegistry.notifyDataConnectionFailedUsingSubId(subId, reason, apnType); 239 } 240 } catch (RemoteException ex) { 241 // system process is dead 242 } 243 } 244 245 @Override 246 public void notifyCellLocation(Phone sender) { 247 long subId = sender.getSubId(); 248 Bundle data = new Bundle(); 249 sender.getCellLocation().fillInNotifierBundle(data); 250 try { 251 if (mRegistry != null) { 252 mRegistry.notifyCellLocationUsingSubId(subId, data); 253 } 254 } catch (RemoteException ex) { 255 // system process is dead 256 } 257 } 258 259 @Override 260 public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) { 261 long subId = sender.getSubId(); 262 try { 263 if (mRegistry != null) { 264 mRegistry.notifyCellInfoUsingSubId(subId, cellInfo); 265 } 266 } catch (RemoteException ex) { 267 268 } 269 } 270 271 @Override 272 public void notifyDataConnectionRealTimeInfo(Phone sender, 273 DataConnectionRealTimeInfo dcRtInfo) { 274 try { 275 mRegistry.notifyDataConnectionRealTimeInfo(dcRtInfo); 276 } catch (RemoteException ex) { 277 278 } 279 } 280 281 @Override 282 public void notifyOtaspChanged(Phone sender, int otaspMode) { 283 // FIXME: subId? 284 try { 285 if (mRegistry != null) { 286 mRegistry.notifyOtaspChanged(otaspMode); 287 } 288 } catch (RemoteException ex) { 289 // system process is dead 290 } 291 } 292 293 public void notifyPreciseCallState(Phone sender) { 294 // FIXME: subId? 295 Call ringingCall = sender.getRingingCall(); 296 Call foregroundCall = sender.getForegroundCall(); 297 Call backgroundCall = sender.getBackgroundCall(); 298 if (ringingCall != null && foregroundCall != null && backgroundCall != null) { 299 try { 300 mRegistry.notifyPreciseCallState( 301 convertPreciseCallState(ringingCall.getState()), 302 convertPreciseCallState(foregroundCall.getState()), 303 convertPreciseCallState(backgroundCall.getState())); 304 } catch (RemoteException ex) { 305 // system process is dead 306 } 307 } 308 } 309 310 public void notifyDisconnectCause(int cause, int preciseCause) { 311 // FIXME: subId? 312 try { 313 mRegistry.notifyDisconnectCause(cause, preciseCause); 314 } catch (RemoteException ex) { 315 // system process is dead 316 } 317 } 318 319 public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType, 320 String apn, String failCause) { 321 // FIXME: subId? 322 try { 323 mRegistry.notifyPreciseDataConnectionFailed(reason, apnType, apn, failCause); 324 } catch (RemoteException ex) { 325 // system process is dead 326 } 327 } 328 329 @Override 330 public void notifyVoLteServiceStateChanged(Phone sender, VoLteServiceState lteState) { 331 // FIXME: subID 332 try { 333 mRegistry.notifyVoLteServiceStateChanged(lteState); 334 } catch (RemoteException ex) { 335 // system process is dead 336 } 337 } 338 339 /** 340 * Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_* 341 * constants for the public API. 342 */ 343 public static int convertCallState(PhoneConstants.State state) { 344 switch (state) { 345 case RINGING: 346 return TelephonyManager.CALL_STATE_RINGING; 347 case OFFHOOK: 348 return TelephonyManager.CALL_STATE_OFFHOOK; 349 default: 350 return TelephonyManager.CALL_STATE_IDLE; 351 } 352 } 353 354 /** 355 * Convert the TelephonyManager.CALL_STATE_* constants into the 356 * {@link PhoneConstants.State} enum for the public API. 357 */ 358 public static PhoneConstants.State convertCallState(int state) { 359 switch (state) { 360 case TelephonyManager.CALL_STATE_RINGING: 361 return PhoneConstants.State.RINGING; 362 case TelephonyManager.CALL_STATE_OFFHOOK: 363 return PhoneConstants.State.OFFHOOK; 364 default: 365 return PhoneConstants.State.IDLE; 366 } 367 } 368 369 /** 370 * Convert the {@link PhoneConstants.DataState} enum into the TelephonyManager.DATA_* constants 371 * for the public API. 372 */ 373 public static int convertDataState(PhoneConstants.DataState state) { 374 switch (state) { 375 case CONNECTING: 376 return TelephonyManager.DATA_CONNECTING; 377 case CONNECTED: 378 return TelephonyManager.DATA_CONNECTED; 379 case SUSPENDED: 380 return TelephonyManager.DATA_SUSPENDED; 381 default: 382 return TelephonyManager.DATA_DISCONNECTED; 383 } 384 } 385 386 /** 387 * Convert the TelephonyManager.DATA_* constants into {@link PhoneConstants.DataState} enum 388 * for the public API. 389 */ 390 public static PhoneConstants.DataState convertDataState(int state) { 391 switch (state) { 392 case TelephonyManager.DATA_CONNECTING: 393 return PhoneConstants.DataState.CONNECTING; 394 case TelephonyManager.DATA_CONNECTED: 395 return PhoneConstants.DataState.CONNECTED; 396 case TelephonyManager.DATA_SUSPENDED: 397 return PhoneConstants.DataState.SUSPENDED; 398 default: 399 return PhoneConstants.DataState.DISCONNECTED; 400 } 401 } 402 403 /** 404 * Convert the {@link Phone.DataActivityState} enum into the TelephonyManager.DATA_* constants 405 * for the public API. 406 */ 407 public static int convertDataActivityState(Phone.DataActivityState state) { 408 switch (state) { 409 case DATAIN: 410 return TelephonyManager.DATA_ACTIVITY_IN; 411 case DATAOUT: 412 return TelephonyManager.DATA_ACTIVITY_OUT; 413 case DATAINANDOUT: 414 return TelephonyManager.DATA_ACTIVITY_INOUT; 415 case DORMANT: 416 return TelephonyManager.DATA_ACTIVITY_DORMANT; 417 default: 418 return TelephonyManager.DATA_ACTIVITY_NONE; 419 } 420 } 421 422 /** 423 * Convert the TelephonyManager.DATA_* constants into the {@link Phone.DataActivityState} enum 424 * for the public API. 425 */ 426 public static Phone.DataActivityState convertDataActivityState(int state) { 427 switch (state) { 428 case TelephonyManager.DATA_ACTIVITY_IN: 429 return Phone.DataActivityState.DATAIN; 430 case TelephonyManager.DATA_ACTIVITY_OUT: 431 return Phone.DataActivityState.DATAOUT; 432 case TelephonyManager.DATA_ACTIVITY_INOUT: 433 return Phone.DataActivityState.DATAINANDOUT; 434 case TelephonyManager.DATA_ACTIVITY_DORMANT: 435 return Phone.DataActivityState.DORMANT; 436 default: 437 return Phone.DataActivityState.NONE; 438 } 439 } 440 441 /** 442 * Convert the {@link State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants 443 * for the public API. 444 */ 445 public static int convertPreciseCallState(Call.State state) { 446 switch (state) { 447 case ACTIVE: 448 return PreciseCallState.PRECISE_CALL_STATE_ACTIVE; 449 case HOLDING: 450 return PreciseCallState.PRECISE_CALL_STATE_HOLDING; 451 case DIALING: 452 return PreciseCallState.PRECISE_CALL_STATE_DIALING; 453 case ALERTING: 454 return PreciseCallState.PRECISE_CALL_STATE_ALERTING; 455 case INCOMING: 456 return PreciseCallState.PRECISE_CALL_STATE_INCOMING; 457 case WAITING: 458 return PreciseCallState.PRECISE_CALL_STATE_WAITING; 459 case DISCONNECTED: 460 return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED; 461 case DISCONNECTING: 462 return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING; 463 default: 464 return PreciseCallState.PRECISE_CALL_STATE_IDLE; 465 } 466 } 467 468 /** 469 * Convert the Call.State.* constants into the {@link State} enum 470 * for the public API. 471 */ 472 public static Call.State convertPreciseCallState(int state) { 473 switch (state) { 474 case PreciseCallState.PRECISE_CALL_STATE_ACTIVE: 475 return Call.State.ACTIVE; 476 case PreciseCallState.PRECISE_CALL_STATE_HOLDING: 477 return Call.State.HOLDING; 478 case PreciseCallState.PRECISE_CALL_STATE_DIALING: 479 return Call.State.DIALING; 480 case PreciseCallState.PRECISE_CALL_STATE_ALERTING: 481 return Call.State.ALERTING; 482 case PreciseCallState.PRECISE_CALL_STATE_INCOMING: 483 return Call.State.INCOMING; 484 case PreciseCallState.PRECISE_CALL_STATE_WAITING: 485 return Call.State.WAITING; 486 case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED: 487 return Call.State.DISCONNECTED; 488 case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING: 489 return Call.State.DISCONNECTING; 490 default: 491 return Call.State.IDLE; 492 } 493 } 494 495 public interface IDataStateChangedCallback { 496 void onDataStateChanged(long subId, String state, String reason, String apnName, 497 String apnType, boolean unavailable); 498 } 499 500 private void log(String s) { 501 Rlog.d(LOG_TAG, s); 502 } 503} 504