ImsPhoneBase.java revision a8467dd0c524787104b1ccdddc5e8af10ba729ed
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.Registrant;
25import android.os.RegistrantList;
26import android.os.SystemProperties;
27import android.telephony.CellInfo;
28import android.telephony.CellLocation;
29import android.telephony.ServiceState;
30import android.telephony.SignalStrength;
31import android.telephony.Rlog;
32
33import com.android.internal.telephony.Call;
34import com.android.internal.telephony.CallStateException;
35import com.android.internal.telephony.Connection;
36import com.android.internal.telephony.dataconnection.DataConnection;
37import com.android.internal.telephony.IccCard;
38import com.android.internal.telephony.IccPhoneBookInterfaceManager;
39import com.android.internal.telephony.MmiCode;
40import com.android.internal.telephony.OperatorInfo;
41import com.android.internal.telephony.PhoneBase;
42import com.android.internal.telephony.PhoneConstants;
43import com.android.internal.telephony.PhoneNotifier;
44import com.android.internal.telephony.PhoneSubInfo;
45import com.android.internal.telephony.TelephonyProperties;
46import com.android.internal.telephony.UUSInfo;
47import com.android.internal.telephony.uicc.IccFileHandler;
48
49import java.util.ArrayList;
50import java.util.List;
51
52abstract class ImsPhoneBase extends PhoneBase {
53    private static final String LOG_TAG = "ImsPhoneBase";
54
55    private RegistrantList mRingbackRegistrants = new RegistrantList();
56    private RegistrantList mOnHoldRegistrants = new RegistrantList();
57    private PhoneConstants.State mState = PhoneConstants.State.IDLE;
58
59    public ImsPhoneBase(String name, Context context, PhoneNotifier notifier) {
60        super(name, notifier, context, new ImsPhoneCommandInterface(context), false);
61    }
62
63    @Override
64    public Connection dial(String dialString, UUSInfo uusInfo)
65            throws CallStateException {
66        // ignore UUSInfo
67        return dial(dialString);
68    }
69
70    void migrateFrom(ImsPhoneBase from) {
71        migrate(mRingbackRegistrants, from.mRingbackRegistrants);
72        migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
73        migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
74        migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
75        migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
76        migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
77        migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
78        migrate(mMmiRegistrants, from.mMmiRegistrants);
79        migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
80        migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
81    }
82
83    static void migrate(RegistrantList to, RegistrantList from) {
84        from.removeCleared();
85        for (int i = 0, n = from.size(); i < n; i++) {
86            to.add((Registrant) from.get(i));
87        }
88    }
89
90    @Override
91    public void registerForRingbackTone(Handler h, int what, Object obj) {
92        mRingbackRegistrants.addUnique(h, what, obj);
93    }
94
95    @Override
96    public void unregisterForRingbackTone(Handler h) {
97        mRingbackRegistrants.remove(h);
98    }
99
100    protected void startRingbackTone() {
101        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
102        mRingbackRegistrants.notifyRegistrants(result);
103    }
104
105    protected void stopRingbackTone() {
106        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
107        mRingbackRegistrants.notifyRegistrants(result);
108    }
109
110    @Override
111    public void registerForOnHoldTone(Handler h, int what, Object obj) {
112        mOnHoldRegistrants.addUnique(h, what, obj);
113    }
114
115    @Override
116    public void unregisterForOnHoldTone(Handler h) {
117        mOnHoldRegistrants.remove(h);
118    }
119
120    protected void startOnHoldTone() {
121        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
122        mOnHoldRegistrants.notifyRegistrants(result);
123    }
124
125    protected void stopOnHoldTone() {
126        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
127        mOnHoldRegistrants.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 notifyNewRingingConnection(Connection c) {
216        super.notifyNewRingingConnectionP(c);
217    }
218
219    void notifyDisconnect(Connection cn) {
220        mDisconnectRegistrants.notifyResult(cn);
221    }
222
223    void notifyUnknownConnection() {
224        mUnknownConnectionRegistrants.notifyResult(this);
225    }
226
227    void notifySuppServiceFailed(SuppService code) {
228        mSuppServiceFailedRegistrants.notifyResult(code);
229    }
230
231    void notifyServiceStateChanged(ServiceState ss) {
232        super.notifyServiceStateChangedP(ss);
233    }
234
235    @Override
236    public void notifyCallForwardingIndicator() {
237        mNotifier.notifyCallForwardingChanged(this);
238    }
239
240    public boolean canDial() {
241        int serviceState = getServiceState().getState();
242        Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState);
243        if (serviceState == ServiceState.STATE_POWER_OFF) return false;
244
245        String disableCall = SystemProperties.get(
246                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
247        Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall);
248        if (disableCall.equals("true")) return false;
249
250        Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState());
251        Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState());
252        Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState());
253        return !getRingingCall().isRinging()
254                && (!getForegroundCall().getState().isAlive()
255                    || !getBackgroundCall().getState().isAlive());
256    }
257
258    @Override
259    public boolean handleInCallMmiCommands(String dialString) {
260        return false;
261    }
262
263    boolean isInCall() {
264        Call.State foregroundCallState = getForegroundCall().getState();
265        Call.State backgroundCallState = getBackgroundCall().getState();
266        Call.State ringingCallState = getRingingCall().getState();
267
268       return (foregroundCallState.isAlive() || backgroundCallState.isAlive()
269               || ringingCallState.isAlive());
270    }
271
272    @Override
273    public boolean handlePinMmi(String dialString) {
274        return false;
275    }
276
277    @Override
278    public void sendUssdResponse(String ussdMessge) {
279    }
280
281    @Override
282    public void registerForSuppServiceNotification(
283            Handler h, int what, Object obj) {
284    }
285
286    @Override
287    public void unregisterForSuppServiceNotification(Handler h) {
288    }
289
290    @Override
291    public void setRadioPower(boolean power) {
292    }
293
294    @Override
295    public String getVoiceMailNumber() {
296        return null;
297    }
298
299    @Override
300    public String getVoiceMailAlphaTag() {
301        return null;
302    }
303
304    @Override
305    public String getDeviceId() {
306        return null;
307    }
308
309    @Override
310    public String getDeviceSvn() {
311        return null;
312    }
313
314    @Override
315    public String getImei() {
316        return null;
317    }
318
319    @Override
320    public String getEsn() {
321        Rlog.e(LOG_TAG, "[VoltePhone] getEsn() is a CDMA method");
322        return "0";
323    }
324
325    @Override
326    public String getMeid() {
327        Rlog.e(LOG_TAG, "[VoltePhone] getMeid() is a CDMA method");
328        return "0";
329    }
330
331    @Override
332    public String getSubscriberId() {
333        return null;
334    }
335
336    @Override
337    public String getGroupIdLevel1() {
338        return null;
339    }
340
341    @Override
342    public String getIccSerialNumber() {
343        return null;
344    }
345
346    @Override
347    public String getLine1Number() {
348        return null;
349    }
350
351    @Override
352    public String getLine1AlphaTag() {
353        return null;
354    }
355
356    @Override
357    public void setLine1Number(String alphaTag, String number, 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 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