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