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