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 makeDefaultPhones(Context context)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 */ makeDefaultPhone(Context context)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 getDefaultPhone()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 getCdmaPhone()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 getGsmPhone()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 */ makeSipPhone(String sipUri)201 public static SipPhone makeSipPhone(String sipUri) { 202 return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier); 203 } 204 } 205