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.ComponentName;
     20 import android.content.Context;
     21 import android.net.LocalServerSocket;
     22 import android.os.Looper;
     23 import android.provider.Settings;
     24 import android.telephony.Rlog;
     25 import android.telephony.TelephonyManager;
     26 
     27 import com.android.internal.telephony.cdma.CDMALTEPhone;
     28 import com.android.internal.telephony.cdma.CDMAPhone;
     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 = "PhoneFactory";
     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     //***** Class Methods
     54 
     55     public static void makeDefaultPhones(Context context) {
     56         makeDefaultPhone(context);
     57     }
     58 
     59     /**
     60      * FIXME replace this with some other way of making these
     61      * instances
     62      */
     63     public static void makeDefaultPhone(Context context) {
     64         synchronized(Phone.class) {
     65             if (!sMadeDefaults) {
     66                 sLooper = Looper.myLooper();
     67                 sContext = context;
     68 
     69                 if (sLooper == null) {
     70                     throw new RuntimeException(
     71                         "PhoneFactory.makeDefaultPhone must be called from Looper thread");
     72                 }
     73 
     74                 int retryCount = 0;
     75                 for(;;) {
     76                     boolean hasException = false;
     77                     retryCount ++;
     78 
     79                     try {
     80                         // use UNIX domain socket to
     81                         // prevent subsequent initialization
     82                         new LocalServerSocket("com.android.internal.telephony");
     83                     } catch (java.io.IOException ex) {
     84                         hasException = true;
     85                     }
     86 
     87                     if ( !hasException ) {
     88                         break;
     89                     } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
     90                         throw new RuntimeException("PhoneFactory probably already running");
     91                     } else {
     92                         try {
     93                             Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
     94                         } catch (InterruptedException er) {
     95                         }
     96                     }
     97                 }
     98 
     99                 sPhoneNotifier = new DefaultPhoneNotifier();
    100 
    101                 // Get preferred network mode
    102                 int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
    103                 if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
    104                     preferredNetworkMode = Phone.NT_MODE_GLOBAL;
    105                 }
    106                 int networkMode = Settings.Global.getInt(context.getContentResolver(),
    107                         Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
    108                 Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
    109 
    110                 int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
    111                 Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
    112 
    113                 //reads the system properties and makes commandsinterface
    114                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
    115 
    116                 // Instantiate UiccController so that all other classes can just call getInstance()
    117                 UiccController.make(context, sCommandsInterface);
    118 
    119                 int phoneType = TelephonyManager.getPhoneType(networkMode);
    120                 if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
    121                     Rlog.i(LOG_TAG, "Creating GSMPhone");
    122                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
    123                             sCommandsInterface, sPhoneNotifier));
    124                 } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
    125                     switch (TelephonyManager.getLteOnCdmaModeStatic()) {
    126                         case PhoneConstants.LTE_ON_CDMA_TRUE:
    127                             Rlog.i(LOG_TAG, "Creating CDMALTEPhone");
    128                             sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
    129                                 sCommandsInterface, sPhoneNotifier));
    130                             break;
    131                         case PhoneConstants.LTE_ON_CDMA_FALSE:
    132                         default:
    133                             Rlog.i(LOG_TAG, "Creating CDMAPhone");
    134                             sProxyPhone = new PhoneProxy(new CDMAPhone(context,
    135                                     sCommandsInterface, sPhoneNotifier));
    136                             break;
    137                     }
    138                 }
    139 
    140                 // Ensure that we have a default SMS app. Requesting the app with
    141                 // updateIfNeeded set to true is enough to configure a default SMS app.
    142                 ComponentName componentName =
    143                         SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */);
    144                 String packageName = "NONE";
    145                 if (componentName != null) {
    146                     packageName = componentName.getPackageName();
    147                 }
    148                 Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName);
    149 
    150                 // Set up monitor to watch for changes to SMS packages
    151                 SmsApplication.initSmsPackageMonitor(context);
    152 
    153                 sMadeDefaults = true;
    154             }
    155         }
    156     }
    157 
    158     public static Phone getDefaultPhone() {
    159         if (sLooper != Looper.myLooper()) {
    160             throw new RuntimeException(
    161                 "PhoneFactory.getDefaultPhone must be called from Looper thread");
    162         }
    163 
    164         if (!sMadeDefaults) {
    165             throw new IllegalStateException("Default phones haven't been made yet!");
    166         }
    167        return sProxyPhone;
    168     }
    169 
    170     public static Phone getCdmaPhone() {
    171         Phone phone;
    172         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    173             switch (TelephonyManager.getLteOnCdmaModeStatic()) {
    174                 case PhoneConstants.LTE_ON_CDMA_TRUE: {
    175                     phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
    176                     break;
    177                 }
    178                 case PhoneConstants.LTE_ON_CDMA_FALSE:
    179                 case PhoneConstants.LTE_ON_CDMA_UNKNOWN:
    180                 default: {
    181                     phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
    182                     break;
    183                 }
    184             }
    185         }
    186         return phone;
    187     }
    188 
    189     public static Phone getGsmPhone() {
    190         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
    191             Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
    192             return phone;
    193         }
    194     }
    195 
    196     /**
    197      * Makes a {@link SipPhone} object.
    198      * @param sipUri the local SIP URI the phone runs on
    199      * @return the {@code SipPhone} object or null if the SIP URI is not valid
    200      */
    201     public static SipPhone makeSipPhone(String sipUri) {
    202         return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
    203     }
    204 }
    205