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