SipPhoneBase.java revision ffe6e68213ae3220497188fed814e271b472292a
1/* 2 * Copyright (C) 2010 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.sip; 18 19import android.content.Context; 20import android.net.LinkProperties; 21import android.os.AsyncResult; 22import android.os.Handler; 23import android.os.Message; 24import android.os.Registrant; 25import android.os.RegistrantList; 26import android.os.SystemProperties; 27import android.telephony.CellInfo; 28import android.telephony.CellLocation; 29import android.telephony.ServiceState; 30import android.telephony.SignalStrength; 31import android.telephony.Rlog; 32 33import com.android.internal.telephony.Call; 34import com.android.internal.telephony.CallStateException; 35import com.android.internal.telephony.Connection; 36import com.android.internal.telephony.dataconnection.DataConnection; 37import com.android.internal.telephony.IccCard; 38import com.android.internal.telephony.IccPhoneBookInterfaceManager; 39import com.android.internal.telephony.IccSmsInterfaceManager; 40import com.android.internal.telephony.MmiCode; 41import com.android.internal.telephony.OperatorInfo; 42import com.android.internal.telephony.PhoneBase; 43import com.android.internal.telephony.PhoneConstants; 44import com.android.internal.telephony.PhoneNotifier; 45import com.android.internal.telephony.PhoneSubInfo; 46import com.android.internal.telephony.TelephonyProperties; 47import com.android.internal.telephony.UUSInfo; 48import com.android.internal.telephony.uicc.IccFileHandler; 49 50import java.util.ArrayList; 51import java.util.List; 52 53abstract class SipPhoneBase extends PhoneBase { 54 private static final String LOG_TAG = "SipPhoneBase"; 55 56 private RegistrantList mRingbackRegistrants = new RegistrantList(); 57 private PhoneConstants.State mState = PhoneConstants.State.IDLE; 58 59 public SipPhoneBase(String name, Context context, PhoneNotifier notifier) { 60 super(name, notifier, context, new SipCommandInterface(context), false); 61 } 62 63 @Override 64 public abstract Call getForegroundCall(); 65 66 @Override 67 public abstract Call getBackgroundCall(); 68 69 @Override 70 public abstract Call getRingingCall(); 71 72 @Override 73 public Connection dial(String dialString, UUSInfo uusInfo) 74 throws CallStateException { 75 // ignore UUSInfo 76 return dial(dialString); 77 } 78 79 void migrateFrom(SipPhoneBase from) { 80 migrate(mRingbackRegistrants, from.mRingbackRegistrants); 81 migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants); 82 migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants); 83 migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants); 84 migrate(mDisconnectRegistrants, from.mDisconnectRegistrants); 85 migrate(mServiceStateRegistrants, from.mServiceStateRegistrants); 86 migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants); 87 migrate(mMmiRegistrants, from.mMmiRegistrants); 88 migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants); 89 migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants); 90 } 91 92 static void migrate(RegistrantList to, RegistrantList from) { 93 from.removeCleared(); 94 for (int i = 0, n = from.size(); i < n; i++) { 95 to.add((Registrant) from.get(i)); 96 } 97 } 98 99 @Override 100 public void registerForRingbackTone(Handler h, int what, Object obj) { 101 mRingbackRegistrants.addUnique(h, what, obj); 102 } 103 104 @Override 105 public void unregisterForRingbackTone(Handler h) { 106 mRingbackRegistrants.remove(h); 107 } 108 109 protected void startRingbackTone() { 110 AsyncResult result = new AsyncResult(null, Boolean.TRUE, null); 111 mRingbackRegistrants.notifyRegistrants(result); 112 } 113 114 protected void stopRingbackTone() { 115 AsyncResult result = new AsyncResult(null, Boolean.FALSE, null); 116 mRingbackRegistrants.notifyRegistrants(result); 117 } 118 119 @Override 120 public ServiceState getServiceState() { 121 // FIXME: we may need to provide this when data connectivity is lost 122 // or when server is down 123 ServiceState s = new ServiceState(); 124 s.setState(ServiceState.STATE_IN_SERVICE); 125 return s; 126 } 127 128 @Override 129 public CellLocation getCellLocation() { 130 return null; 131 } 132 133 @Override 134 public PhoneConstants.State getState() { 135 return mState; 136 } 137 138 @Override 139 public int getPhoneType() { 140 return PhoneConstants.PHONE_TYPE_SIP; 141 } 142 143 @Override 144 public SignalStrength getSignalStrength() { 145 return new SignalStrength(); 146 } 147 148 @Override 149 public boolean getMessageWaitingIndicator() { 150 return false; 151 } 152 153 @Override 154 public boolean getCallForwardingIndicator() { 155 return false; 156 } 157 158 @Override 159 public List<? extends MmiCode> getPendingMmiCodes() { 160 return new ArrayList<MmiCode>(0); 161 } 162 163 @Override 164 public PhoneConstants.DataState getDataConnectionState() { 165 return PhoneConstants.DataState.DISCONNECTED; 166 } 167 168 @Override 169 public PhoneConstants.DataState getDataConnectionState(String apnType) { 170 return PhoneConstants.DataState.DISCONNECTED; 171 } 172 173 @Override 174 public DataActivityState getDataActivityState() { 175 return DataActivityState.NONE; 176 } 177 178 /** 179 * Notify any interested party of a Phone state change 180 * {@link com.android.internal.telephony.PhoneConstants.State} 181 */ 182 /* package */ void notifyPhoneStateChanged() { 183 mNotifier.notifyPhoneState(this); 184 } 185 186 /** 187 * Notify registrants of a change in the call state. This notifies changes in 188 * {@link com.android.internal.telephony.Call.State}. Use this when changes 189 * in the precise call state are needed, else use notifyPhoneStateChanged. 190 */ 191 /* package */ void notifyPreciseCallStateChanged() { 192 /* we'd love it if this was package-scoped*/ 193 super.notifyPreciseCallStateChangedP(); 194 } 195 196 void notifyNewRingingConnection(Connection c) { 197 super.notifyNewRingingConnectionP(c); 198 } 199 200 void notifyDisconnect(Connection cn) { 201 mDisconnectRegistrants.notifyResult(cn); 202 } 203 204 void notifyUnknownConnection() { 205 mUnknownConnectionRegistrants.notifyResult(this); 206 } 207 208 void notifySuppServiceFailed(SuppService code) { 209 mSuppServiceFailedRegistrants.notifyResult(code); 210 } 211 212 void notifyServiceStateChanged(ServiceState ss) { 213 super.notifyServiceStateChangedP(ss); 214 } 215 216 @Override 217 public void notifyCallForwardingIndicator() { 218 mNotifier.notifyCallForwardingChanged(this); 219 } 220 221 public boolean canDial() { 222 int serviceState = getServiceState().getState(); 223 Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState); 224 if (serviceState == ServiceState.STATE_POWER_OFF) return false; 225 226 String disableCall = SystemProperties.get( 227 TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); 228 Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall); 229 if (disableCall.equals("true")) return false; 230 231 Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState()); 232 Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState()); 233 Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState()); 234 return !getRingingCall().isRinging() 235 && (!getForegroundCall().getState().isAlive() 236 || !getBackgroundCall().getState().isAlive()); 237 } 238 239 @Override 240 public boolean handleInCallMmiCommands(String dialString) { 241 return false; 242 } 243 244 boolean isInCall() { 245 Call.State foregroundCallState = getForegroundCall().getState(); 246 Call.State backgroundCallState = getBackgroundCall().getState(); 247 Call.State ringingCallState = getRingingCall().getState(); 248 249 return (foregroundCallState.isAlive() || backgroundCallState.isAlive() 250 || ringingCallState.isAlive()); 251 } 252 253 @Override 254 public boolean handlePinMmi(String dialString) { 255 return false; 256 } 257 258 @Override 259 public void sendUssdResponse(String ussdMessge) { 260 } 261 262 @Override 263 public void registerForSuppServiceNotification( 264 Handler h, int what, Object obj) { 265 } 266 267 @Override 268 public void unregisterForSuppServiceNotification(Handler h) { 269 } 270 271 @Override 272 public void setRadioPower(boolean power) { 273 } 274 275 @Override 276 public String getVoiceMailNumber() { 277 return null; 278 } 279 280 @Override 281 public String getVoiceMailAlphaTag() { 282 return null; 283 } 284 285 @Override 286 public String getDeviceId() { 287 return null; 288 } 289 290 @Override 291 public String getDeviceSvn() { 292 return null; 293 } 294 295 @Override 296 public String getImei() { 297 return null; 298 } 299 300 @Override 301 public String getEsn() { 302 Rlog.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method"); 303 return "0"; 304 } 305 306 @Override 307 public String getMeid() { 308 Rlog.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method"); 309 return "0"; 310 } 311 312 @Override 313 public String getSubscriberId() { 314 return null; 315 } 316 317 @Override 318 public String getGroupIdLevel1() { 319 return null; 320 } 321 322 @Override 323 public String getIccSerialNumber() { 324 return null; 325 } 326 327 @Override 328 public String getLine1Number() { 329 return null; 330 } 331 332 @Override 333 public String getLine1AlphaTag() { 334 return null; 335 } 336 337 @Override 338 public void setLine1Number(String alphaTag, String number, Message onComplete) { 339 // FIXME: what to reply for SIP? 340 AsyncResult.forMessage(onComplete, null, null); 341 onComplete.sendToTarget(); 342 } 343 344 @Override 345 public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, 346 Message onComplete) { 347 // FIXME: what to reply for SIP? 348 AsyncResult.forMessage(onComplete, null, null); 349 onComplete.sendToTarget(); 350 } 351 352 @Override 353 public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { 354 } 355 356 @Override 357 public void setCallForwardingOption(int commandInterfaceCFAction, 358 int commandInterfaceCFReason, String dialingNumber, 359 int timerSeconds, Message onComplete) { 360 } 361 362 @Override 363 public void getOutgoingCallerIdDisplay(Message onComplete) { 364 // FIXME: what to reply? 365 AsyncResult.forMessage(onComplete, null, null); 366 onComplete.sendToTarget(); 367 } 368 369 @Override 370 public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, 371 Message onComplete) { 372 // FIXME: what's this for SIP? 373 AsyncResult.forMessage(onComplete, null, null); 374 onComplete.sendToTarget(); 375 } 376 377 @Override 378 public void getCallWaiting(Message onComplete) { 379 AsyncResult.forMessage(onComplete, null, null); 380 onComplete.sendToTarget(); 381 } 382 383 @Override 384 public void setCallWaiting(boolean enable, Message onComplete) { 385 Rlog.e(LOG_TAG, "call waiting not supported"); 386 } 387 388 @Override 389 public boolean getIccRecordsLoaded() { 390 return false; 391 } 392 393 @Override 394 public IccCard getIccCard() { 395 return null; 396 } 397 398 @Override 399 public void getAvailableNetworks(Message response) { 400 } 401 402 @Override 403 public void setNetworkSelectionModeAutomatic(Message response) { 404 } 405 406 @Override 407 public void selectNetworkManually( 408 OperatorInfo network, 409 Message response) { 410 } 411 412 @Override 413 public void getNeighboringCids(Message response) { 414 } 415 416 @Override 417 public void setOnPostDialCharacter(Handler h, int what, Object obj) { 418 } 419 420 @Override 421 public void getDataCallList(Message response) { 422 } 423 424 public List<DataConnection> getCurrentDataConnectionList () { 425 return null; 426 } 427 428 @Override 429 public void updateServiceLocation() { 430 } 431 432 @Override 433 public void enableLocationUpdates() { 434 } 435 436 @Override 437 public void disableLocationUpdates() { 438 } 439 440 @Override 441 public boolean getDataRoamingEnabled() { 442 return false; 443 } 444 445 @Override 446 public void setDataRoamingEnabled(boolean enable) { 447 } 448 449 public boolean enableDataConnectivity() { 450 return false; 451 } 452 453 public boolean disableDataConnectivity() { 454 return false; 455 } 456 457 @Override 458 public boolean isDataConnectivityPossible() { 459 return false; 460 } 461 462 boolean updateCurrentCarrierInProvider() { 463 return false; 464 } 465 466 public void saveClirSetting(int commandInterfaceCLIRMode) { 467 } 468 469 @Override 470 public PhoneSubInfo getPhoneSubInfo(){ 471 return null; 472 } 473 474 @Override 475 public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ 476 return null; 477 } 478 479 @Override 480 public IccFileHandler getIccFileHandler(){ 481 return null; 482 } 483 484 @Override 485 public void activateCellBroadcastSms(int activate, Message response) { 486 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 487 } 488 489 @Override 490 public void getCellBroadcastSmsConfig(Message response) { 491 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 492 } 493 494 @Override 495 public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){ 496 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 497 } 498 499 //@Override 500 @Override 501 public boolean needsOtaServiceProvisioning() { 502 // FIXME: what's this for SIP? 503 return false; 504 } 505 506 //@Override 507 @Override 508 public LinkProperties getLinkProperties(String apnType) { 509 // FIXME: what's this for SIP? 510 return null; 511 } 512 513 void updatePhoneState() { 514 PhoneConstants.State oldState = mState; 515 516 if (getRingingCall().isRinging()) { 517 mState = PhoneConstants.State.RINGING; 518 } else if (getForegroundCall().isIdle() 519 && getBackgroundCall().isIdle()) { 520 mState = PhoneConstants.State.IDLE; 521 } else { 522 mState = PhoneConstants.State.OFFHOOK; 523 } 524 525 if (mState != oldState) { 526 Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState); 527 notifyPhoneStateChanged(); 528 } 529 } 530 531 @Override 532 protected void onUpdateIccAvailability() { 533 } 534} 535