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