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