OSDN Git Service

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