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