• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import android.os.SystemProperties;
25 
26 import com.android.internal.telephony.cdma.CDMAPhone;
27 import com.android.internal.telephony.cdma.CDMALTEPhone;
28 import com.android.internal.telephony.gsm.GSMPhone;
29 import com.android.internal.telephony.sip.SipPhone;
30 import com.android.internal.telephony.sip.SipPhoneFactory;
31 
32 /**
33  * {@hide}
34  */
35 public class PhoneFactory {
36     static final String LOG_TAG = "PHONE";
37     static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
38     static final int SOCKET_OPEN_MAX_RETRY = 3;
39 
40     //***** Class Variables
41 
42     static private Phone sProxyPhone = null;
43     static private CommandsInterface sCommandsInterface = null;
44 
45     static private boolean sMadeDefaults = false;
46     static private PhoneNotifier sPhoneNotifier;
47     static private Looper sLooper;
48     static private Context sContext;
49 
50     static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION;
51 
52     //***** Class Methods
53 
makeDefaultPhones(Context context)54     public static void makeDefaultPhones(Context context) {
55         makeDefaultPhone(context);
56     }
57 
58     /**
59      * FIXME replace this with some other way of making these
60      * instances
61      */
makeDefaultPhone(Context context)62     public static void makeDefaultPhone(Context context) {
63         synchronized(Phone.class) {
64             if (!sMadeDefaults) {
65                 sLooper = Looper.myLooper();
66                 sContext = context;
67 
68                 if (sLooper == null) {
69                     throw new RuntimeException(
70                         "PhoneFactory.makeDefaultPhone must be called from Looper thread");
71                 }
72 
73                 int retryCount = 0;
74                 for(;;) {
75                     boolean hasException = false;
76                     retryCount ++;
77 
78                     try {
79                         // use UNIX domain socket to
80                         // prevent subsequent initialization
81                         new LocalServerSocket("com.android.internal.telephony");
82                     } catch (java.io.IOException ex) {
83                         hasException = true;
84                     }
85 
86                     if ( !hasException ) {
87                         break;
88                     } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
89                         throw new RuntimeException("PhoneFactory probably already running");
90                     } else {
91                         try {
92                             Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
93                         } catch (InterruptedException er) {
94                         }
95                     }
96                 }
97 
98                 sPhoneNotifier = new DefaultPhoneNotifier();
99 
100                 // Get preferred network mode
101                 int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
102                 if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
103                     preferredNetworkMode = Phone.NT_MODE_GLOBAL;
104                 }
105                 int networkMode = Settings.Secure.getInt(context.getContentResolver(),
106                         Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
107                 Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
108 
109                 // Get cdmaSubscription
110                 // TODO: Change when the ril will provides a way to know at runtime
111                 //       the configuration, bug 4202572. And the ril issues the
112                 //       RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439.
113                 int cdmaSubscription;
114                 int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
115                 switch (lteOnCdma) {
116                     case Phone.LTE_ON_CDMA_FALSE:
117                         cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_NV;
118                         Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
119                         break;
120                     case Phone.LTE_ON_CDMA_TRUE:
121                         cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_RUIM;
122                         Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
123                         break;
124                     case Phone.LTE_ON_CDMA_UNKNOWN:
125                     default:
126                         //Get cdmaSubscription mode from Settings.System
127                         cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
128                                 Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
129                                 preferredCdmaSubscription);
130                         Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
131                         break;
132                 }
133                 Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
134 
135                 //reads the system properties and makes commandsinterface
136                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
137 
138                 int phoneType = getPhoneType(networkMode);
139                 if (phoneType == Phone.PHONE_TYPE_GSM) {
140                     Log.i(LOG_TAG, "Creating GSMPhone");
141                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
142                             sCommandsInterface, sPhoneNotifier));
143                 } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
144                     switch (BaseCommands.getLteOnCdmaModeStatic()) {
145                         case Phone.LTE_ON_CDMA_TRUE:
146                             Log.i(LOG_TAG, "Creating CDMALTEPhone");
147                             sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
148                                 sCommandsInterface, sPhoneNotifier));
149                             break;
150                         case Phone.LTE_ON_CDMA_FALSE:
151                         default:
152                             Log.i(LOG_TAG, "Creating CDMAPhone");
153                             sProxyPhone = new PhoneProxy(new CDMAPhone(context,
154                                     sCommandsInterface, sPhoneNotifier));
155                             break;
156                     }
157                 }
158 
159                 sMadeDefaults = true;
160             }
161         }
162     }
163 
164     /*
165      * This function returns the type of the phone, depending
166      * on the network mode.
167      *
168      * @param network mode
169      * @return Phone Type
170      */
getPhoneType(int networkMode)171     public static int getPhoneType(int networkMode) {
172         switch(networkMode) {
173         case RILConstants.NETWORK_MODE_CDMA:
174         case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
175         case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
176             return Phone.PHONE_TYPE_CDMA;
177 
178         case RILConstants.NETWORK_MODE_WCDMA_PREF:
179         case RILConstants.NETWORK_MODE_GSM_ONLY:
180         case RILConstants.NETWORK_MODE_WCDMA_ONLY:
181         case RILConstants.NETWORK_MODE_GSM_UMTS:
182             return Phone.PHONE_TYPE_GSM;
183 
184         // Use CDMA Phone for the global mode including CDMA
185         case RILConstants.NETWORK_MODE_GLOBAL:
186         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
187         case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
188             return Phone.PHONE_TYPE_CDMA;
189 
190         case RILConstants.NETWORK_MODE_LTE_ONLY:
191             if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
192                 return Phone.PHONE_TYPE_CDMA;
193             } else {
194                 return Phone.PHONE_TYPE_GSM;
195             }
196         default:
197             return Phone.PHONE_TYPE_GSM;
198         }
199     }
200 
getDefaultPhone()201     public static Phone getDefaultPhone() {
202         if (sLooper != Looper.myLooper()) {
203             throw new RuntimeException(
204                 "PhoneFactory.getDefaultPhone must be called from Looper thread");
205         }
206 
207         if (!sMadeDefaults) {
208             throw new IllegalStateException("Default phones haven't been made yet!");
209         }
210        return sProxyPhone;
211     }
212 
getCdmaPhone()213     public static Phone getCdmaPhone() {
214         Phone phone;
215         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
216             switch (BaseCommands.getLteOnCdmaModeStatic()) {
217                 case Phone.LTE_ON_CDMA_TRUE: {
218                     phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
219                     break;
220                 }
221                 case Phone.LTE_ON_CDMA_FALSE:
222                 case Phone.LTE_ON_CDMA_UNKNOWN:
223                 default: {
224                     phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
225                     break;
226                 }
227             }
228         }
229         return phone;
230     }
231 
getGsmPhone()232     public static Phone getGsmPhone() {
233         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
234             Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
235             return phone;
236         }
237     }
238 
239     /**
240      * Makes a {@link SipPhone} object.
241      * @param sipUri the local SIP URI the phone runs on
242      * @return the {@code SipPhone} object or null if the SIP URI is not valid
243      */
makeSipPhone(String sipUri)244     public static SipPhone makeSipPhone(String sipUri) {
245         return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
246     }
247 }
248