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