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