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