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