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