Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 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;
     18 
     19 import android.content.Context;
     20 import android.net.LocalServerSocket;
     21 import android.os.Looper;
     22 import android.provider.Settings;
     23 import android.util.Log;
     24 import android.os.SystemProperties;
     25 
     26 import com.android.internal.telephony.cdma.CDMAPhone;
     27 import com.android.internal.telephony.cdma.CDMALTEPhone;
     28 import com.android.internal.telephony.gsm.GSMPhone;
     29 import com.android.internal.telephony.sip.SipPhone;
     30 import com.android.internal.telephony.sip.SipPhoneFactory;
     31 
     32 /**
     33  * {@hide}
     34  */
     35 public class PhoneFactory {
     36     static final String LOG_TAG = "PHONE";
     37     static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
     38     static final int SOCKET_OPEN_MAX_RETRY = 3;
     39 
     40     //***** Class Variables
     41 
     42     static private Phone sProxyPhone = null;
     43     static private CommandsInterface sCommandsInterface = null;
     44 
     45     static private boolean sMadeDefaults = false;
     46     static private PhoneNotifier sPhoneNotifier;
     47     static private Looper sLooper;
     48     static private Context sContext;
     49 
     50     static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION;
     51 
     52     //***** Class Methods
     53 
     54     public static void makeDefaultPhones(Context context) {
     55         makeDefaultPhone(context);
     56     }
     57 
     58     /**
     59      * FIXME replace this with some other way of making these
     60      * instances
     61      */
     62     public static void makeDefaultPhone(Context context) {
     63         synchronized(Phone.class) {
     64             if (!sMadeDefaults) {
     65                 sLooper = Looper.myLooper();
     66                 sContext = context;
     67 
     68                 if (sLooper == null) {
     69                     throw new RuntimeException(
     70                         "PhoneFactory.makeDefaultPhone must be called from Looper thread");
     71                 }
     72 
     73                 int retryCount = 0;
     74                 for(;;) {
     75                     boolean hasException = false;
     76                     retryCount ++;
     77 
     78                     try {
     79                         // use UNIX domain socket to
     80                         // prevent subsequent initialization
     81                         new LocalServerSocket("com.android.internal.telephony");
     82                     } catch (java.io.IOException ex) {
     83                         hasException = true;
     84                     }
     85 
     86                     if ( !hasException ) {
     87                         break;
     88                     } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
     89                         throw new RuntimeException("PhoneFactory probably already running");
     90                     } else {
     91                         try {
     92                             Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
     93                         } catch (InterruptedException er) {
     94                         }
     95                     }
     96                 }
     97 
     98                 sPhoneNotifier = new DefaultPhoneNotifier();
     99 
    100                 // Get preferred network mode
    101                 int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
    102                 if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
    103                     preferredNetworkMode = Phone.NT_MODE_GLOBAL;
    104                 }
    105                 int networkMode = Settings.Secure.getInt(context.getContentResolver(),
    106                         Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
    107                 Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
    108 
    109                 // Get cdmaSubscription
    110                 // TODO: Change when the ril will provides a way to know at runtime
    111                 //       the configuration, bug 4202572. And the ril issues the
    112                 //       RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439.
    113                 int cdmaSubscription;
    114                 int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
    115                 switch (lteOnCdma) {
    116                     case Phone.LTE_ON_CDMA_FALSE:
    117                         cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_NV;
    118                         Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
    119                         break;
    120                     case Phone.LTE_ON_CDMA_TRUE:
    121                         cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_RUIM;
    122                         Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
    123                         break;
    124                     case Phone.LTE_ON_CDMA_UNKNOWN:
    125                     default:
    126                         //Get cdmaSubscription mode from Settings.System
    127                         cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
    128                                 Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
    129                                 preferredCdmaSubscription);
    130                         Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
    131                         break;
    132                 }
    133                 Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
    134 
    135                 //reads the system properties and makes commandsinterface
    136                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
    137 
    138                 int phoneType = getPhoneType(networkMode);
    139                 if (phoneType == Phone.PHONE_TYPE_GSM) {
    140                     Log.i(LOG_TAG, "Creating GSMPhone");
    141                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
    142                             sCommandsInterface, sPhoneNotifier));
    143                 } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
    144                     switch (BaseCommands.getLteOnCdmaModeStatic()) {
    145                         case Phone.LTE_ON_CDMA_TRUE:
    146                             Log.i(LOG_TAG, "Creating CDMALTEPhone");
    147                             sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
    148                                 sCommandsInterface, sPhoneNotifier));
    149                             break;
    150                         case Phone.LTE_ON_CDMA_FALSE:
    151                         default:
    152                             Log.i(LOG_TAG, "Creating CDMAPhone");
    153                             sProxyPhone = new PhoneProxy(new CDMAPhone(context,
    154                                     sCommandsInterface, sPhoneNotifier));
    155                             break;
    156                     }
    157                 }
    158 
    159                 sMadeDefaults = true;
    160             }
    161         }
    162     }
    163 
    164     /*
    165      * This function returns the type of the phone, depending
    166      * on the network mode.
    167      *
    168      * @param network mode
    169      * @return Phone Type
    170      */
    171     public static int getPhoneType(int networkMode) {
    172         switch(networkMode) {
    173         case RILConstants.NETWORK_MODE_CDMA:
    174         case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
    175         case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
    176             return Phone.PHONE_TYPE_CDMA;
    177 
    178         case RILConstants.NETWORK_MODE_WCDMA_PREF:
    179         case RILConstants.NETWORK_MODE_GSM_ONLY:
    180         case RILConstants.NETWORK_MODE_WCDMA_ONLY:
    181         case RILConstants.NETWORK_MODE_GSM_UMTS:
    182             return Phone.PHONE_TYPE_GSM;
    183 
    184         // Use CDMA Phone for the global mode including CDMA
    185         case RILConstants.NETWORK_MODE_GLOBAL:
    186         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
    187         case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
    188             return Phone.PHONE_TYPE_CDMA;
    189 
    190         case RILConstants.NETWORK_MODE_LTE_ONLY:
    191             if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
    192                 return Phone.PHONE_TYPE_CDMA;
    193             } else {
    194                 return Phone.PHONE_TYPE_GSM;
    195             }
    196         default:
    197             return Phone.PHONE_TYPE_GSM;
    198         }
    199     }
    200 
    201     public static Phone getDefaultPhone() {
    202         if (sLooper != Looper.myLooper()) {
    203             throw new RuntimeException(
    204                 "PhoneFactory.getDefaultPhone must be called from Looper thread");
    205         }
    206 
    207         if (!sMadeDefaults) {
    208             throw new IllegalStateException("Default phones haven't been made yet!");
    209         }
    210        return sProxyPhone;
    211     }
    212 
    213     public static Phone getCdmaPhone() {
    214         Phone phone;
    215         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    216             switch (BaseCommands.getLteOnCdmaModeStatic()) {
    217                 case Phone.LTE_ON_CDMA_TRUE: {
    218                     phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
    219                     break;
    220                 }
    221                 case Phone.LTE_ON_CDMA_FALSE:
    222                 case Phone.LTE_ON_CDMA_UNKNOWN:
    223                 default: {
    224                     phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
    225                     break;
    226                 }
    227             }
    228         }
    229         return phone;
    230     }
    231 
    232     public static Phone getGsmPhone() {
    233         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    234             Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
    235             return phone;
    236         }
    237     }
    238 
    239     /**
    240      * Makes a {@link SipPhone} object.
    241      * @param sipUri the local SIP URI the phone runs on
    242      * @return the {@code SipPhone} object or null if the SIP URI is not valid
    243      */
    244     public static SipPhone makeSipPhone(String sipUri) {
    245         return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
    246     }
    247 }
    248