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