SipPhoneBase.java revision 850665a367489cce0b83431fa0e6e543b24062e0
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 getGroupIdLevel1() {
327        return null;
328    }
329
330    @Override
331    public String getIccSerialNumber() {
332        return null;
333    }
334
335    @Override
336    public String getLine1Number() {
337        return null;
338    }
339
340    @Override
341    public String getLine1AlphaTag() {
342        return null;
343    }
344
345    @Override
346    public void setLine1Number(String alphaTag, String number, Message onComplete) {
347        // FIXME: what to reply for SIP?
348        AsyncResult.forMessage(onComplete, null, null);
349        onComplete.sendToTarget();
350    }
351
352    @Override
353    public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
354            Message onComplete) {
355        // FIXME: what to reply for SIP?
356        AsyncResult.forMessage(onComplete, null, null);
357        onComplete.sendToTarget();
358    }
359
360    @Override
361    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
362    }
363
364    @Override
365    public void setCallForwardingOption(int commandInterfaceCFAction,
366            int commandInterfaceCFReason, String dialingNumber,
367            int timerSeconds, Message onComplete) {
368    }
369
370    @Override
371    public void getOutgoingCallerIdDisplay(Message onComplete) {
372        // FIXME: what to reply?
373        AsyncResult.forMessage(onComplete, null, null);
374        onComplete.sendToTarget();
375    }
376
377    @Override
378    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
379                                           Message onComplete) {
380        // FIXME: what's this for SIP?
381        AsyncResult.forMessage(onComplete, null, null);
382        onComplete.sendToTarget();
383    }
384
385    @Override
386    public void getCallWaiting(Message onComplete) {
387        AsyncResult.forMessage(onComplete, null, null);
388        onComplete.sendToTarget();
389    }
390
391    @Override
392    public void setCallWaiting(boolean enable, Message onComplete) {
393        Rlog.e(LOG_TAG, "call waiting not supported");
394    }
395
396    @Override
397    public boolean getIccRecordsLoaded() {
398        return false;
399    }
400
401    @Override
402    public IccCard getIccCard() {
403        return null;
404    }
405
406    @Override
407    public void getAvailableNetworks(Message response) {
408    }
409
410    @Override
411    public void setNetworkSelectionModeAutomatic(Message response) {
412    }
413
414    @Override
415    public void selectNetworkManually(
416            OperatorInfo network,
417            Message response) {
418    }
419
420    @Override
421    public void getNeighboringCids(Message response) {
422    }
423
424    @Override
425    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
426    }
427
428    @Override
429    public void getDataCallList(Message response) {
430    }
431
432    public List<DataConnection> getCurrentDataConnectionList () {
433        return null;
434    }
435
436    @Override
437    public void updateServiceLocation() {
438    }
439
440    @Override
441    public void enableLocationUpdates() {
442    }
443
444    @Override
445    public void disableLocationUpdates() {
446    }
447
448    @Override
449    public boolean getDataRoamingEnabled() {
450        return false;
451    }
452
453    @Override
454    public void setDataRoamingEnabled(boolean enable) {
455    }
456
457    public boolean enableDataConnectivity() {
458        return false;
459    }
460
461    public boolean disableDataConnectivity() {
462        return false;
463    }
464
465    @Override
466    public boolean isDataConnectivityPossible() {
467        return false;
468    }
469
470    boolean updateCurrentCarrierInProvider() {
471        return false;
472    }
473
474    public void saveClirSetting(int commandInterfaceCLIRMode) {
475    }
476
477    @Override
478    public PhoneSubInfo getPhoneSubInfo(){
479        return null;
480    }
481
482    public IccSmsInterfaceManager getIccSmsInterfaceManager(){
483        return null;
484    }
485
486    @Override
487    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
488        return null;
489    }
490
491    @Override
492    public IccFileHandler getIccFileHandler(){
493        return null;
494    }
495
496    @Override
497    public void activateCellBroadcastSms(int activate, Message response) {
498        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
499    }
500
501    @Override
502    public void getCellBroadcastSmsConfig(Message response) {
503        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
504    }
505
506    @Override
507    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
508        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
509    }
510
511    //@Override
512    @Override
513    public boolean needsOtaServiceProvisioning() {
514        // FIXME: what's this for SIP?
515        return false;
516    }
517
518    //@Override
519    @Override
520    public LinkProperties getLinkProperties(String apnType) {
521        // FIXME: what's this for SIP?
522        return null;
523    }
524
525    void updatePhoneState() {
526        PhoneConstants.State oldState = mState;
527
528        if (getRingingCall().isRinging()) {
529            mState = PhoneConstants.State.RINGING;
530        } else if (getForegroundCall().isIdle()
531                && getBackgroundCall().isIdle()) {
532            mState = PhoneConstants.State.IDLE;
533        } else {
534            mState = PhoneConstants.State.OFFHOOK;
535        }
536
537        if (mState != oldState) {
538            Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState);
539            notifyPhoneStateChanged();
540        }
541    }
542
543    @Override
544    protected void onUpdateIccAvailability() {
545    }
546}
547