ImsPhoneBase.java revision 410298cb95b110609193941807aff6c9676d2304
1/*
2 * Copyright (C) 2013 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.imsphone;
18
19import android.content.Context;
20import android.net.LinkProperties;
21import android.os.AsyncResult;
22import android.os.Handler;
23import android.os.Message;
24import android.os.RegistrantList;
25import android.os.SystemProperties;
26import android.telephony.CellInfo;
27import android.telephony.CellLocation;
28import android.telephony.ServiceState;
29import android.telephony.SignalStrength;
30import android.telephony.Rlog;
31
32import com.android.internal.telephony.Call;
33import com.android.internal.telephony.Connection;
34import com.android.internal.telephony.dataconnection.DataConnection;
35import com.android.internal.telephony.IccCard;
36import com.android.internal.telephony.IccPhoneBookInterfaceManager;
37import com.android.internal.telephony.MmiCode;
38import com.android.internal.telephony.OperatorInfo;
39import com.android.internal.telephony.Phone;
40import com.android.internal.telephony.PhoneConstants;
41import com.android.internal.telephony.PhoneNotifier;
42import com.android.internal.telephony.TelephonyProperties;
43import com.android.internal.telephony.uicc.IccFileHandler;
44
45import java.util.ArrayList;
46import java.util.List;
47
48abstract class ImsPhoneBase extends Phone {
49    private static final String LOG_TAG = "ImsPhoneBase";
50
51    private RegistrantList mRingbackRegistrants = new RegistrantList();
52    private RegistrantList mOnHoldRegistrants = new RegistrantList();
53    private RegistrantList mTtyModeReceivedRegistrants = new RegistrantList();
54    private PhoneConstants.State mState = PhoneConstants.State.IDLE;
55
56    public ImsPhoneBase(String name, Context context, PhoneNotifier notifier) {
57        super(name, notifier, context, new ImsPhoneCommandInterface(context), false);
58    }
59
60    @Override
61    public void migrateFrom(Phone from) {
62        super.migrateFrom(from);
63        migrate(mRingbackRegistrants, ((ImsPhoneBase)from).mRingbackRegistrants);
64    }
65
66    @Override
67    public void registerForRingbackTone(Handler h, int what, Object obj) {
68        mRingbackRegistrants.addUnique(h, what, obj);
69    }
70
71    @Override
72    public void unregisterForRingbackTone(Handler h) {
73        mRingbackRegistrants.remove(h);
74    }
75
76    @Override
77    public void startRingbackTone() {
78        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
79        mRingbackRegistrants.notifyRegistrants(result);
80    }
81
82    @Override
83    public void stopRingbackTone() {
84        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
85        mRingbackRegistrants.notifyRegistrants(result);
86    }
87
88    @Override
89    public void registerForOnHoldTone(Handler h, int what, Object obj) {
90        mOnHoldRegistrants.addUnique(h, what, obj);
91    }
92
93    @Override
94    public void unregisterForOnHoldTone(Handler h) {
95        mOnHoldRegistrants.remove(h);
96    }
97
98    protected void startOnHoldTone() {
99        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
100        mOnHoldRegistrants.notifyRegistrants(result);
101    }
102
103    protected void stopOnHoldTone() {
104        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
105        mOnHoldRegistrants.notifyRegistrants(result);
106    }
107
108    @Override
109    public void registerForTtyModeReceived(Handler h, int what, Object obj){
110        mTtyModeReceivedRegistrants.addUnique(h, what, obj);
111    }
112
113    @Override
114    public void unregisterForTtyModeReceived(Handler h) {
115        mTtyModeReceivedRegistrants.remove(h);
116    }
117
118    public void onTtyModeReceived(int mode) {
119        AsyncResult result = new AsyncResult(null, Integer.valueOf(mode), null);
120        mTtyModeReceivedRegistrants.notifyRegistrants(result);
121    }
122
123    @Override
124    public ServiceState getServiceState() {
125        // FIXME: we may need to provide this when data connectivity is lost
126        // or when server is down
127        ServiceState s = new ServiceState();
128        s.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
129        return s;
130    }
131
132    /**
133     * @return all available cell information or null if none.
134     */
135    @Override
136    public List<CellInfo> getAllCellInfo() {
137        return getServiceStateTracker().getAllCellInfo();
138    }
139
140    @Override
141    public CellLocation getCellLocation() {
142        return null;
143    }
144
145    @Override
146    public PhoneConstants.State getState() {
147        return mState;
148    }
149
150    @Override
151    public int getPhoneType() {
152        return PhoneConstants.PHONE_TYPE_IMS;
153    }
154
155    @Override
156    public SignalStrength getSignalStrength() {
157        return new SignalStrength();
158    }
159
160    @Override
161    public boolean getMessageWaitingIndicator() {
162        return false;
163    }
164
165    @Override
166    public boolean getCallForwardingIndicator() {
167        return false;
168    }
169
170    @Override
171    public List<? extends MmiCode> getPendingMmiCodes() {
172        return new ArrayList<MmiCode>(0);
173    }
174
175    @Override
176    public PhoneConstants.DataState getDataConnectionState() {
177        return PhoneConstants.DataState.DISCONNECTED;
178    }
179
180    @Override
181    public PhoneConstants.DataState getDataConnectionState(String apnType) {
182        return PhoneConstants.DataState.DISCONNECTED;
183    }
184
185    @Override
186    public DataActivityState getDataActivityState() {
187        return DataActivityState.NONE;
188    }
189
190    /**
191     * Notify any interested party of a Phone state change
192     * {@link com.android.internal.telephony.PhoneConstants.State}
193     */
194    /* package */ void notifyPhoneStateChanged() {
195        mNotifier.notifyPhoneState(this);
196    }
197
198    /**
199     * Notify registrants of a change in the call state. This notifies changes in
200     * {@link com.android.internal.telephony.Call.State}. Use this when changes
201     * in the precise call state are needed, else use notifyPhoneStateChanged.
202     */
203    /* package */ void notifyPreciseCallStateChanged() {
204        /* we'd love it if this was package-scoped*/
205        super.notifyPreciseCallStateChangedP();
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, "[VoltePhone] getEsn() is a CDMA method");
311        return "0";
312    }
313
314    @Override
315    public String getMeid() {
316        Rlog.e(LOG_TAG, "[VoltePhone] 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 getGroupIdLevel2() {
332        return null;
333    }
334
335    @Override
336    public String getIccSerialNumber() {
337        return null;
338    }
339
340    @Override
341    public String getLine1Number() {
342        return null;
343    }
344
345    @Override
346    public String getLine1AlphaTag() {
347        return null;
348    }
349
350    @Override
351    public boolean setLine1Number(String alphaTag, String number, Message onComplete) {
352        // FIXME: what to reply for Volte?
353        return false;
354    }
355
356    @Override
357    public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
358            Message onComplete) {
359        // FIXME: what to reply for Volte?
360        AsyncResult.forMessage(onComplete, null, null);
361        onComplete.sendToTarget();
362    }
363
364    @Override
365    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
366    }
367
368    @Override
369    public void setCallForwardingOption(int commandInterfaceCFAction,
370            int commandInterfaceCFReason, String dialingNumber,
371            int timerSeconds, Message onComplete) {
372    }
373
374    @Override
375    public void getOutgoingCallerIdDisplay(Message onComplete) {
376        // FIXME: what to reply?
377        AsyncResult.forMessage(onComplete, null, null);
378        onComplete.sendToTarget();
379    }
380
381    @Override
382    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
383            Message onComplete) {
384        // FIXME: what's this for Volte?
385        AsyncResult.forMessage(onComplete, null, null);
386        onComplete.sendToTarget();
387    }
388
389    @Override
390    public void getCallWaiting(Message onComplete) {
391        AsyncResult.forMessage(onComplete, null, null);
392        onComplete.sendToTarget();
393    }
394
395    @Override
396    public void setCallWaiting(boolean enable, Message onComplete) {
397        Rlog.e(LOG_TAG, "call waiting not supported");
398    }
399
400    @Override
401    public boolean getIccRecordsLoaded() {
402        return false;
403    }
404
405    @Override
406    public IccCard getIccCard() {
407        return null;
408    }
409
410    @Override
411    public void getAvailableNetworks(Message response) {
412    }
413
414    @Override
415    public void setNetworkSelectionModeAutomatic(Message response) {
416    }
417
418    @Override
419    public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
420            Message response) {
421    }
422
423    @Override
424    public void getNeighboringCids(Message response) {
425    }
426
427    @Override
428    public void getDataCallList(Message response) {
429    }
430
431    public List<DataConnection> getCurrentDataConnectionList () {
432        return null;
433    }
434
435    @Override
436    public void updateServiceLocation() {
437    }
438
439    @Override
440    public void enableLocationUpdates() {
441    }
442
443    @Override
444    public void disableLocationUpdates() {
445    }
446
447    @Override
448    public boolean getDataRoamingEnabled() {
449        return false;
450    }
451
452    @Override
453    public void setDataRoamingEnabled(boolean enable) {
454    }
455
456    @Override
457    public boolean getDataEnabled() {
458        return false;
459    }
460
461    @Override
462    public void setDataEnabled(boolean enable) {
463    }
464
465
466    public boolean enableDataConnectivity() {
467        return false;
468    }
469
470    public boolean disableDataConnectivity() {
471        return false;
472    }
473
474    @Override
475    public boolean isDataConnectivityPossible() {
476        return false;
477    }
478
479    public void saveClirSetting(int commandInterfaceCLIRMode) {
480    }
481
482    @Override
483    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
484        return null;
485    }
486
487    @Override
488    public IccFileHandler getIccFileHandler(){
489        return null;
490    }
491
492    @Override
493    public void activateCellBroadcastSms(int activate, Message response) {
494        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
495    }
496
497    @Override
498    public void getCellBroadcastSmsConfig(Message response) {
499        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
500    }
501
502    @Override
503    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
504        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
505    }
506
507    //@Override
508    @Override
509    public boolean needsOtaServiceProvisioning() {
510        // FIXME: what's this for Volte?
511        return false;
512    }
513
514    //@Override
515    @Override
516    public LinkProperties getLinkProperties(String apnType) {
517        // FIXME: what's this for Volte?
518        return null;
519    }
520
521    @Override
522    protected void onUpdateIccAvailability() {
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