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 17package com.android.internal.telephony; 18 19import android.content.Context; 20import android.net.LocalServerSocket; 21import android.os.Looper; 22import android.provider.Settings; 23import android.util.Log; 24 25import com.android.internal.telephony.cdma.CDMAPhone; 26import com.android.internal.telephony.gsm.GSMPhone; 27import com.android.internal.telephony.sip.SipPhone; 28import com.android.internal.telephony.sip.SipPhoneFactory; 29 30/** 31 * {@hide} 32 */ 33public class PhoneFactory { 34 static final String LOG_TAG = "PHONE"; 35 static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000; 36 static final int SOCKET_OPEN_MAX_RETRY = 3; 37 //***** Class Variables 38 39 static private Phone sProxyPhone = null; 40 static private CommandsInterface sCommandsInterface = null; 41 42 static private boolean sMadeDefaults = false; 43 static private PhoneNotifier sPhoneNotifier; 44 static private Looper sLooper; 45 static private Context sContext; 46 47 static final int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE; 48 49 static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION; 50 51 //***** Class Methods 52 53 public static void makeDefaultPhones(Context context) { 54 makeDefaultPhone(context); 55 } 56 57 /** 58 * FIXME replace this with some other way of making these 59 * instances 60 */ 61 public static void makeDefaultPhone(Context context) { 62 synchronized(Phone.class) { 63 if (!sMadeDefaults) { 64 sLooper = Looper.myLooper(); 65 sContext = context; 66 67 if (sLooper == null) { 68 throw new RuntimeException( 69 "PhoneFactory.makeDefaultPhone must be called from Looper thread"); 70 } 71 72 int retryCount = 0; 73 for(;;) { 74 boolean hasException = false; 75 retryCount ++; 76 77 try { 78 // use UNIX domain socket to 79 // prevent subsequent initialization 80 new LocalServerSocket("com.android.internal.telephony"); 81 } catch (java.io.IOException ex) { 82 hasException = true; 83 } 84 85 if ( !hasException ) { 86 break; 87 } else if (retryCount > SOCKET_OPEN_MAX_RETRY) { 88 throw new RuntimeException("PhoneFactory probably already running"); 89 } else { 90 try { 91 Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); 92 } catch (InterruptedException er) { 93 } 94 } 95 } 96 97 sPhoneNotifier = new DefaultPhoneNotifier(); 98 99 //Get preferredNetworkMode from Settings.System 100 int networkMode = Settings.Secure.getInt(context.getContentResolver(), 101 Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode); 102 Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode)); 103 104 //Get preferredNetworkMode from Settings.System 105 int cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(), 106 Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION, preferredCdmaSubscription); 107 Log.i(LOG_TAG, "Cdma Subscription set to " + Integer.toString(cdmaSubscription)); 108 109 //reads the system properties and makes commandsinterface 110 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); 111 112 int phoneType = getPhoneType(networkMode); 113 if (phoneType == Phone.PHONE_TYPE_GSM) { 114 Log.i(LOG_TAG, "Creating GSMPhone"); 115 sProxyPhone = new PhoneProxy(new GSMPhone(context, 116 sCommandsInterface, sPhoneNotifier)); 117 } else if (phoneType == Phone.PHONE_TYPE_CDMA) { 118 Log.i(LOG_TAG, "Creating CDMAPhone"); 119 sProxyPhone = new PhoneProxy(new CDMAPhone(context, 120 sCommandsInterface, sPhoneNotifier)); 121 } 122 123 sMadeDefaults = true; 124 } 125 } 126 } 127 128 /* 129 * This function returns the type of the phone, depending 130 * on the network mode. 131 * 132 * @param network mode 133 * @return Phone Type 134 */ 135 public static int getPhoneType(int networkMode) { 136 switch(networkMode) { 137 case RILConstants.NETWORK_MODE_CDMA: 138 case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: 139 case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: 140 return Phone.PHONE_TYPE_CDMA; 141 142 case RILConstants.NETWORK_MODE_WCDMA_PREF: 143 case RILConstants.NETWORK_MODE_GSM_ONLY: 144 case RILConstants.NETWORK_MODE_WCDMA_ONLY: 145 case RILConstants.NETWORK_MODE_GSM_UMTS: 146 return Phone.PHONE_TYPE_GSM; 147 148 case RILConstants.NETWORK_MODE_GLOBAL: 149 return Phone.PHONE_TYPE_CDMA; 150 default: 151 return Phone.PHONE_TYPE_GSM; 152 } 153 } 154 155 public static Phone getDefaultPhone() { 156 if (sLooper != Looper.myLooper()) { 157 throw new RuntimeException( 158 "PhoneFactory.getDefaultPhone must be called from Looper thread"); 159 } 160 161 if (!sMadeDefaults) { 162 throw new IllegalStateException("Default phones haven't been made yet!"); 163 } 164 return sProxyPhone; 165 } 166 167 public static Phone getCdmaPhone() { 168 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 169 Phone phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier); 170 return phone; 171 } 172 } 173 174 public static Phone getGsmPhone() { 175 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 176 Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier); 177 return phone; 178 } 179 } 180 181 /** 182 * Makes a {@link SipPhone} object. 183 * @param sipUri the local SIP URI the phone runs on 184 * @return the {@code SipPhone} object or null if the SIP URI is not valid 185 */ 186 public static SipPhone makeSipPhone(String sipUri) { 187 return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier); 188 } 189} 190