ImsPhoneBase.java revision df0280231c51a24a0b66c24034827d7f73d6e1ac
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.Bundle;
23import android.os.Handler;
24import android.os.Message;
25import android.os.Registrant;
26import android.os.RegistrantList;
27import android.os.SystemProperties;
28import android.telephony.CellInfo;
29import android.telephony.CellLocation;
30import android.telephony.ServiceState;
31import android.telephony.SignalStrength;
32import android.telephony.Rlog;
33
34import com.android.internal.telephony.Call;
35import com.android.internal.telephony.CallStateException;
36import com.android.internal.telephony.Connection;
37import com.android.internal.telephony.dataconnection.DataConnection;
38import com.android.internal.telephony.cdma.CDMAPhone;
39import com.android.internal.telephony.gsm.GSMPhone;
40import com.android.internal.telephony.CallManager;
41import com.android.internal.telephony.IccCard;
42import com.android.internal.telephony.IccPhoneBookInterfaceManager;
43import com.android.internal.telephony.MmiCode;
44import com.android.internal.telephony.OperatorInfo;
45import com.android.internal.telephony.Phone;
46import com.android.internal.telephony.PhoneBase;
47import com.android.internal.telephony.PhoneConstants;
48import com.android.internal.telephony.PhoneNotifier;
49import com.android.internal.telephony.PhoneSubInfo;
50import com.android.internal.telephony.TelephonyProperties;
51import com.android.internal.telephony.UUSInfo;
52import com.android.internal.telephony.uicc.IccFileHandler;
53
54import java.util.ArrayList;
55import java.util.List;
56
57abstract class ImsPhoneBase extends PhoneBase {
58    private static final String LOG_TAG = "ImsPhoneBase";
59
60    private RegistrantList mRingbackRegistrants = new RegistrantList();
61    private RegistrantList mOnHoldRegistrants = new RegistrantList();
62    private RegistrantList mTtyModeReceivedRegistrants = new RegistrantList();
63    private PhoneConstants.State mState = PhoneConstants.State.IDLE;
64
65    public ImsPhoneBase(String name, Context context, PhoneNotifier notifier) {
66        super(name, notifier, context, new ImsPhoneCommandInterface(context), false);
67    }
68
69    @Override
70    public void migrateFrom(PhoneBase from) {
71        super.migrateFrom(from);
72        migrate(mRingbackRegistrants, ((ImsPhoneBase)from).mRingbackRegistrants);
73    }
74
75    @Override
76    public void registerForRingbackTone(Handler h, int what, Object obj) {
77        mRingbackRegistrants.addUnique(h, what, obj);
78    }
79
80    @Override
81    public void unregisterForRingbackTone(Handler h) {
82        mRingbackRegistrants.remove(h);
83    }
84
85    protected void startRingbackTone() {
86        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
87        mRingbackRegistrants.notifyRegistrants(result);
88    }
89
90    protected void stopRingbackTone() {
91        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
92        mRingbackRegistrants.notifyRegistrants(result);
93    }
94
95    @Override
96    public void registerForOnHoldTone(Handler h, int what, Object obj) {
97        mOnHoldRegistrants.addUnique(h, what, obj);
98    }
99
100    @Override
101    public void unregisterForOnHoldTone(Handler h) {
102        mOnHoldRegistrants.remove(h);
103    }
104
105    protected void startOnHoldTone() {
106        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
107        mOnHoldRegistrants.notifyRegistrants(result);
108    }
109
110    protected void stopOnHoldTone() {
111        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
112        mOnHoldRegistrants.notifyRegistrants(result);
113    }
114
115    @Override
116    public void registerForTtyModeReceived(Handler h, int what, Object obj){
117        mTtyModeReceivedRegistrants.addUnique(h, what, obj);
118    }
119
120    @Override
121    public void unregisterForTtyModeReceived(Handler h) {
122        mTtyModeReceivedRegistrants.remove(h);
123    }
124
125    public void onTtyModeReceived(int mode) {
126        AsyncResult result = new AsyncResult(null, Integer.valueOf(mode), null);
127        mTtyModeReceivedRegistrants.notifyRegistrants(result);
128    }
129
130    @Override
131    public ServiceState getServiceState() {
132        // FIXME: we may need to provide this when data connectivity is lost
133        // or when server is down
134        ServiceState s = new ServiceState();
135        s.setState(ServiceState.STATE_IN_SERVICE);
136        return s;
137    }
138
139    /**
140     * @return all available cell information or null if none.
141     */
142    @Override
143    public List<CellInfo> getAllCellInfo() {
144        return getServiceStateTracker().getAllCellInfo();
145    }
146
147    @Override
148    public CellLocation getCellLocation() {
149        return null;
150    }
151
152    @Override
153    public PhoneConstants.State getState() {
154        return mState;
155    }
156
157    @Override
158    public int getPhoneType() {
159        return PhoneConstants.PHONE_TYPE_IMS;
160    }
161
162    @Override
163    public SignalStrength getSignalStrength() {
164        return new SignalStrength();
165    }
166
167    @Override
168    public boolean getMessageWaitingIndicator() {
169        return false;
170    }
171
172    @Override
173    public boolean getCallForwardingIndicator() {
174        return false;
175    }
176
177    @Override
178    public List<? extends MmiCode> getPendingMmiCodes() {
179        return new ArrayList<MmiCode>(0);
180    }
181
182    @Override
183    public PhoneConstants.DataState getDataConnectionState() {
184        return PhoneConstants.DataState.DISCONNECTED;
185    }
186
187    @Override
188    public PhoneConstants.DataState getDataConnectionState(String apnType) {
189        return PhoneConstants.DataState.DISCONNECTED;
190    }
191
192    @Override
193    public DataActivityState getDataActivityState() {
194        return DataActivityState.NONE;
195    }
196
197    /**
198     * Notify any interested party of a Phone state change
199     * {@link com.android.internal.telephony.PhoneConstants.State}
200     */
201    /* package */ void notifyPhoneStateChanged() {
202        mNotifier.notifyPhoneState(this);
203    }
204
205    /**
206     * Notify registrants of a change in the call state. This notifies changes in
207     * {@link com.android.internal.telephony.Call.State}. Use this when changes
208     * in the precise call state are needed, else use notifyPhoneStateChanged.
209     */
210    /* package */ void notifyPreciseCallStateChanged() {
211        /* we'd love it if this was package-scoped*/
212        super.notifyPreciseCallStateChangedP();
213    }
214
215    void notifyDisconnect(Connection cn) {
216        mDisconnectRegistrants.notifyResult(cn);
217    }
218
219    void notifyUnknownConnection() {
220        mUnknownConnectionRegistrants.notifyResult(this);
221    }
222
223    void notifySuppServiceFailed(SuppService code) {
224        mSuppServiceFailedRegistrants.notifyResult(code);
225    }
226
227    void notifyServiceStateChanged(ServiceState ss) {
228        super.notifyServiceStateChangedP(ss);
229    }
230
231    @Override
232    public void notifyCallForwardingIndicator() {
233        mNotifier.notifyCallForwardingChanged(this);
234    }
235
236    public boolean canDial() {
237        int serviceState = getServiceState().getState();
238        Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState);
239        if (serviceState == ServiceState.STATE_POWER_OFF) return false;
240
241        String disableCall = SystemProperties.get(
242                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
243        Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall);
244        if (disableCall.equals("true")) return false;
245
246        Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState());
247        Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState());
248        Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState());
249        return !getRingingCall().isRinging()
250                && (!getForegroundCall().getState().isAlive()
251                    || !getBackgroundCall().getState().isAlive());
252    }
253
254    @Override
255    public boolean handleInCallMmiCommands(String dialString) {
256        return false;
257    }
258
259    boolean isInCall() {
260        Call.State foregroundCallState = getForegroundCall().getState();
261        Call.State backgroundCallState = getBackgroundCall().getState();
262        Call.State ringingCallState = getRingingCall().getState();
263
264       return (foregroundCallState.isAlive() || backgroundCallState.isAlive()
265               || ringingCallState.isAlive());
266    }
267
268    @Override
269    public boolean handlePinMmi(String dialString) {
270        return false;
271    }
272
273    @Override
274    public void sendUssdResponse(String ussdMessge) {
275    }
276
277    @Override
278    public void registerForSuppServiceNotification(
279            Handler h, int what, Object obj) {
280    }
281
282    @Override
283    public void unregisterForSuppServiceNotification(Handler h) {
284    }
285
286    @Override
287    public void setRadioPower(boolean power) {
288    }
289
290    @Override
291    public String getVoiceMailNumber() {
292        return null;
293    }
294
295    @Override
296    public String getVoiceMailAlphaTag() {
297        return null;
298    }
299
300    @Override
301    public String getDeviceId() {
302        return null;
303    }
304
305    @Override
306    public String getDeviceSvn() {
307        return null;
308    }
309
310    @Override
311    public String getImei() {
312        return null;
313    }
314
315    @Override
316    public String getEsn() {
317        Rlog.e(LOG_TAG, "[VoltePhone] getEsn() is a CDMA method");
318        return "0";
319    }
320
321    @Override
322    public String getMeid() {
323        Rlog.e(LOG_TAG, "[VoltePhone] getMeid() is a CDMA method");
324        return "0";
325    }
326
327    @Override
328    public String getSubscriberId() {
329        return null;
330    }
331
332    @Override
333    public String getGroupIdLevel1() {
334        return null;
335    }
336
337    @Override
338    public String getGroupIdLevel2() {
339        return null;
340    }
341
342    @Override
343    public String getIccSerialNumber() {
344        return null;
345    }
346
347    @Override
348    public String getLine1Number() {
349        return null;
350    }
351
352    @Override
353    public String getLine1AlphaTag() {
354        return null;
355    }
356
357    @Override
358    public boolean setLine1Number(String alphaTag, String number, Message onComplete) {
359        // FIXME: what to reply for Volte?
360        return false;
361    }
362
363    @Override
364    public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
365            Message onComplete) {
366        // FIXME: what to reply for Volte?
367        AsyncResult.forMessage(onComplete, null, null);
368        onComplete.sendToTarget();
369    }
370
371    @Override
372    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
373    }
374
375    @Override
376    public void setCallForwardingOption(int commandInterfaceCFAction,
377            int commandInterfaceCFReason, String dialingNumber,
378            int timerSeconds, Message onComplete) {
379    }
380
381    @Override
382    public void getOutgoingCallerIdDisplay(Message onComplete) {
383        // FIXME: what to reply?
384        AsyncResult.forMessage(onComplete, null, null);
385        onComplete.sendToTarget();
386    }
387
388    @Override
389    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
390            Message onComplete) {
391        // FIXME: what's this for Volte?
392        AsyncResult.forMessage(onComplete, null, null);
393        onComplete.sendToTarget();
394    }
395
396    @Override
397    public void getCallWaiting(Message onComplete) {
398        AsyncResult.forMessage(onComplete, null, null);
399        onComplete.sendToTarget();
400    }
401
402    @Override
403    public void setCallWaiting(boolean enable, Message onComplete) {
404        Rlog.e(LOG_TAG, "call waiting not supported");
405    }
406
407    @Override
408    public boolean getIccRecordsLoaded() {
409        return false;
410    }
411
412    @Override
413    public IccCard getIccCard() {
414        return null;
415    }
416
417    @Override
418    public void getAvailableNetworks(Message response) {
419    }
420
421    @Override
422    public void setNetworkSelectionModeAutomatic(Message response) {
423    }
424
425    @Override
426    public void selectNetworkManually(
427            OperatorInfo network,
428            Message response) {
429    }
430
431    @Override
432    public void getNeighboringCids(Message response) {
433    }
434
435    @Override
436    public void getDataCallList(Message response) {
437    }
438
439    public List<DataConnection> getCurrentDataConnectionList () {
440        return null;
441    }
442
443    @Override
444    public void updateServiceLocation() {
445    }
446
447    @Override
448    public void enableLocationUpdates() {
449    }
450
451    @Override
452    public void disableLocationUpdates() {
453    }
454
455    @Override
456    public boolean getDataRoamingEnabled() {
457        return false;
458    }
459
460    @Override
461    public void setDataRoamingEnabled(boolean enable) {
462    }
463
464    @Override
465    public boolean getDataEnabled() {
466        return false;
467    }
468
469    @Override
470    public void setDataEnabled(boolean enable) {
471    }
472
473
474    public boolean enableDataConnectivity() {
475        return false;
476    }
477
478    public boolean disableDataConnectivity() {
479        return false;
480    }
481
482    @Override
483    public boolean isDataConnectivityPossible() {
484        return false;
485    }
486
487    boolean updateCurrentCarrierInProvider() {
488        return false;
489    }
490
491    public void saveClirSetting(int commandInterfaceCLIRMode) {
492    }
493
494    @Override
495    public PhoneSubInfo getPhoneSubInfo(){
496        return null;
497    }
498
499    @Override
500    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
501        return null;
502    }
503
504    @Override
505    public IccFileHandler getIccFileHandler(){
506        return null;
507    }
508
509    @Override
510    public void activateCellBroadcastSms(int activate, Message response) {
511        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
512    }
513
514    @Override
515    public void getCellBroadcastSmsConfig(Message response) {
516        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
517    }
518
519    @Override
520    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
521        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for Volte.");
522    }
523
524    //@Override
525    @Override
526    public boolean needsOtaServiceProvisioning() {
527        // FIXME: what's this for Volte?
528        return false;
529    }
530
531    //@Override
532    @Override
533    public LinkProperties getLinkProperties(String apnType) {
534        // FIXME: what's this for Volte?
535        return null;
536    }
537
538    @Override
539    protected void onUpdateIccAvailability() {
540    }
541
542    void updatePhoneState() {
543        PhoneConstants.State oldState = mState;
544
545        if (getRingingCall().isRinging()) {
546            mState = PhoneConstants.State.RINGING;
547        } else if (getForegroundCall().isIdle()
548                && getBackgroundCall().isIdle()) {
549            mState = PhoneConstants.State.IDLE;
550        } else {
551            mState = PhoneConstants.State.OFFHOOK;
552        }
553
554        if (mState != oldState) {
555            Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState);
556            notifyPhoneStateChanged();
557        }
558    }
559}
560