SipPhoneBase.java revision ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6a
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 /** 129 * @return all available cell information or null if none. 130 */ 131 @Override 132 public List<CellInfo> getAllCellInfo() { 133 return getServiceStateTracker().getAllCellInfo(); 134 } 135 136 @Override 137 public CellLocation getCellLocation() { 138 return null; 139 } 140 141 @Override 142 public PhoneConstants.State getState() { 143 return mState; 144 } 145 146 @Override 147 public int getPhoneType() { 148 return PhoneConstants.PHONE_TYPE_SIP; 149 } 150 151 @Override 152 public SignalStrength getSignalStrength() { 153 return new SignalStrength(); 154 } 155 156 @Override 157 public boolean getMessageWaitingIndicator() { 158 return false; 159 } 160 161 @Override 162 public boolean getCallForwardingIndicator() { 163 return false; 164 } 165 166 @Override 167 public List<? extends MmiCode> getPendingMmiCodes() { 168 return new ArrayList<MmiCode>(0); 169 } 170 171 @Override 172 public PhoneConstants.DataState getDataConnectionState() { 173 return PhoneConstants.DataState.DISCONNECTED; 174 } 175 176 @Override 177 public PhoneConstants.DataState getDataConnectionState(String apnType) { 178 return PhoneConstants.DataState.DISCONNECTED; 179 } 180 181 @Override 182 public DataActivityState getDataActivityState() { 183 return DataActivityState.NONE; 184 } 185 186 /** 187 * Notify any interested party of a Phone state change 188 * {@link com.android.internal.telephony.PhoneConstants.State} 189 */ 190 /* package */ void notifyPhoneStateChanged() { 191 mNotifier.notifyPhoneState(this); 192 } 193 194 /** 195 * Notify registrants of a change in the call state. This notifies changes in 196 * {@link com.android.internal.telephony.Call.State}. Use this when changes 197 * in the precise call state are needed, else use notifyPhoneStateChanged. 198 */ 199 /* package */ void notifyPreciseCallStateChanged() { 200 /* we'd love it if this was package-scoped*/ 201 super.notifyPreciseCallStateChangedP(); 202 } 203 204 void notifyNewRingingConnection(Connection c) { 205 super.notifyNewRingingConnectionP(c); 206 } 207 208 void notifyDisconnect(Connection cn) { 209 mDisconnectRegistrants.notifyResult(cn); 210 } 211 212 void notifyUnknownConnection() { 213 mUnknownConnectionRegistrants.notifyResult(this); 214 } 215 216 void notifySuppServiceFailed(SuppService code) { 217 mSuppServiceFailedRegistrants.notifyResult(code); 218 } 219 220 void notifyServiceStateChanged(ServiceState ss) { 221 super.notifyServiceStateChangedP(ss); 222 } 223 224 @Override 225 public void notifyCallForwardingIndicator() { 226 mNotifier.notifyCallForwardingChanged(this); 227 } 228 229 public boolean canDial() { 230 int serviceState = getServiceState().getState(); 231 Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState); 232 if (serviceState == ServiceState.STATE_POWER_OFF) return false; 233 234 String disableCall = SystemProperties.get( 235 TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); 236 Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall); 237 if (disableCall.equals("true")) return false; 238 239 Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState()); 240 Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState()); 241 Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState()); 242 return !getRingingCall().isRinging() 243 && (!getForegroundCall().getState().isAlive() 244 || !getBackgroundCall().getState().isAlive()); 245 } 246 247 @Override 248 public boolean handleInCallMmiCommands(String dialString) { 249 return false; 250 } 251 252 boolean isInCall() { 253 Call.State foregroundCallState = getForegroundCall().getState(); 254 Call.State backgroundCallState = getBackgroundCall().getState(); 255 Call.State ringingCallState = getRingingCall().getState(); 256 257 return (foregroundCallState.isAlive() || backgroundCallState.isAlive() 258 || ringingCallState.isAlive()); 259 } 260 261 @Override 262 public boolean handlePinMmi(String dialString) { 263 return false; 264 } 265 266 @Override 267 public void sendUssdResponse(String ussdMessge) { 268 } 269 270 @Override 271 public void registerForSuppServiceNotification( 272 Handler h, int what, Object obj) { 273 } 274 275 @Override 276 public void unregisterForSuppServiceNotification(Handler h) { 277 } 278 279 @Override 280 public void setRadioPower(boolean power) { 281 } 282 283 @Override 284 public String getVoiceMailNumber() { 285 return null; 286 } 287 288 @Override 289 public String getVoiceMailAlphaTag() { 290 return null; 291 } 292 293 @Override 294 public String getDeviceId() { 295 return null; 296 } 297 298 @Override 299 public String getDeviceSvn() { 300 return null; 301 } 302 303 @Override 304 public String getImei() { 305 return null; 306 } 307 308 @Override 309 public String getEsn() { 310 Rlog.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method"); 311 return "0"; 312 } 313 314 @Override 315 public String getMeid() { 316 Rlog.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method"); 317 return "0"; 318 } 319 320 @Override 321 public String getSubscriberId() { 322 return null; 323 } 324 325 @Override 326 public String getIccSerialNumber() { 327 return null; 328 } 329 330 @Override 331 public String getLine1Number() { 332 return null; 333 } 334 335 @Override 336 public String getLine1AlphaTag() { 337 return null; 338 } 339 340 @Override 341 public void setLine1Number(String alphaTag, String number, Message onComplete) { 342 // FIXME: what to reply for SIP? 343 AsyncResult.forMessage(onComplete, null, null); 344 onComplete.sendToTarget(); 345 } 346 347 @Override 348 public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, 349 Message onComplete) { 350 // FIXME: what to reply for SIP? 351 AsyncResult.forMessage(onComplete, null, null); 352 onComplete.sendToTarget(); 353 } 354 355 @Override 356 public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { 357 } 358 359 @Override 360 public void setCallForwardingOption(int commandInterfaceCFAction, 361 int commandInterfaceCFReason, String dialingNumber, 362 int timerSeconds, Message onComplete) { 363 } 364 365 @Override 366 public void getOutgoingCallerIdDisplay(Message onComplete) { 367 // FIXME: what to reply? 368 AsyncResult.forMessage(onComplete, null, null); 369 onComplete.sendToTarget(); 370 } 371 372 @Override 373 public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, 374 Message onComplete) { 375 // FIXME: what's this for SIP? 376 AsyncResult.forMessage(onComplete, null, null); 377 onComplete.sendToTarget(); 378 } 379 380 @Override 381 public void getCallWaiting(Message onComplete) { 382 AsyncResult.forMessage(onComplete, null, null); 383 onComplete.sendToTarget(); 384 } 385 386 @Override 387 public void setCallWaiting(boolean enable, Message onComplete) { 388 Rlog.e(LOG_TAG, "call waiting not supported"); 389 } 390 391 @Override 392 public boolean getIccRecordsLoaded() { 393 return false; 394 } 395 396 @Override 397 public IccCard getIccCard() { 398 return null; 399 } 400 401 @Override 402 public void getAvailableNetworks(Message response) { 403 } 404 405 @Override 406 public void setNetworkSelectionModeAutomatic(Message response) { 407 } 408 409 @Override 410 public void selectNetworkManually( 411 OperatorInfo network, 412 Message response) { 413 } 414 415 @Override 416 public void getNeighboringCids(Message response) { 417 } 418 419 @Override 420 public void setOnPostDialCharacter(Handler h, int what, Object obj) { 421 } 422 423 @Override 424 public void getDataCallList(Message response) { 425 } 426 427 public List<DataConnection> getCurrentDataConnectionList () { 428 return null; 429 } 430 431 @Override 432 public void updateServiceLocation() { 433 } 434 435 @Override 436 public void enableLocationUpdates() { 437 } 438 439 @Override 440 public void disableLocationUpdates() { 441 } 442 443 @Override 444 public boolean getDataRoamingEnabled() { 445 return false; 446 } 447 448 @Override 449 public void setDataRoamingEnabled(boolean enable) { 450 } 451 452 public boolean enableDataConnectivity() { 453 return false; 454 } 455 456 public boolean disableDataConnectivity() { 457 return false; 458 } 459 460 @Override 461 public boolean isDataConnectivityPossible() { 462 return false; 463 } 464 465 boolean updateCurrentCarrierInProvider() { 466 return false; 467 } 468 469 public void saveClirSetting(int commandInterfaceCLIRMode) { 470 } 471 472 @Override 473 public PhoneSubInfo getPhoneSubInfo(){ 474 return null; 475 } 476 477 @Override 478 public IccSmsInterfaceManager getIccSmsInterfaceManager(){ 479 return null; 480 } 481 482 @Override 483 public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ 484 return null; 485 } 486 487 @Override 488 public IccFileHandler getIccFileHandler(){ 489 return null; 490 } 491 492 @Override 493 public void activateCellBroadcastSms(int activate, Message response) { 494 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 495 } 496 497 @Override 498 public void getCellBroadcastSmsConfig(Message response) { 499 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 500 } 501 502 @Override 503 public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){ 504 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 505 } 506 507 //@Override 508 @Override 509 public boolean needsOtaServiceProvisioning() { 510 // FIXME: what's this for SIP? 511 return false; 512 } 513 514 //@Override 515 @Override 516 public LinkProperties getLinkProperties(String apnType) { 517 // FIXME: what's this for SIP? 518 return null; 519 } 520 521 void updatePhoneState() { 522 PhoneConstants.State oldState = mState; 523 524 if (getRingingCall().isRinging()) { 525 mState = PhoneConstants.State.RINGING; 526 } else if (getForegroundCall().isIdle() 527 && getBackgroundCall().isIdle()) { 528 mState = PhoneConstants.State.IDLE; 529 } else { 530 mState = PhoneConstants.State.OFFHOOK; 531 } 532 533 if (mState != oldState) { 534 Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState); 535 notifyPhoneStateChanged(); 536 } 537 } 538 539 @Override 540 protected void onUpdateIccAvailability() { 541 } 542} 543