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