463f7d3c6756b17b3fd7046bc8315bb895591e52
[android/platform/frameworks/opt/telephony.git] / src / java / com / android / internal / telephony / PhoneFactory.java
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.telephony.Rlog;
25 import com.android.internal.telephony.cdma.CDMAPhone;
26 import com.android.internal.telephony.cdma.CDMALTEPhone;
27 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
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 import com.android.internal.telephony.uicc.UiccController;
32
33 /**
34  * {@hide}
35  */
36 public class PhoneFactory {
37     static final String LOG_TAG = "PhoneFactory";
38     static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
39     static final int SOCKET_OPEN_MAX_RETRY = 3;
40
41     //***** Class Variables
42
43     static private Phone sProxyPhone = null;
44     static private CommandsInterface sCommandsInterface = null;
45
46     static private boolean sMadeDefaults = false;
47     static private PhoneNotifier sPhoneNotifier;
48     static private Looper sLooper;
49     static private Context sContext;
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 preferred network mode
100                 int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
101                 if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
102                     preferredNetworkMode = Phone.NT_MODE_GLOBAL;
103                 }
104                 int networkMode = Settings.Global.getInt(context.getContentResolver(),
105                         Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
106                 Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
107
108                 int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
109                 Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
110
111                 //reads the system properties and makes commandsinterface
112                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
113
114                 // Instantiate UiccController so that all other classes can just call getInstance()
115                 UiccController.make(context, sCommandsInterface);
116
117                 int phoneType = TelephonyManager.getPhoneType(networkMode);
118                 if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
119                     Rlog.i(LOG_TAG, "Creating GSMPhone");
120                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
121                             sCommandsInterface, sPhoneNotifier));
122                 } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
123                     switch (TelephonyManager.getLteOnCdmaModeStatic()) {
124                         case PhoneConstants.LTE_ON_CDMA_TRUE:
125                             Rlog.i(LOG_TAG, "Creating CDMALTEPhone");
126                             sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
127                                 sCommandsInterface, sPhoneNotifier));
128                             break;
129                         case PhoneConstants.LTE_ON_CDMA_FALSE:
130                         default:
131                             Rlog.i(LOG_TAG, "Creating CDMAPhone");
132                             sProxyPhone = new PhoneProxy(new CDMAPhone(context,
133                                     sCommandsInterface, sPhoneNotifier));
134                             break;
135                     }
136                 }
137
138                 sMadeDefaults = true;
139             }
140         }
141     }
142
143     public static Phone getDefaultPhone() {
144         if (sLooper != Looper.myLooper()) {
145             throw new RuntimeException(
146                 "PhoneFactory.getDefaultPhone must be called from Looper thread");
147         }
148
149         if (!sMadeDefaults) {
150             throw new IllegalStateException("Default phones haven't been made yet!");
151         }
152        return sProxyPhone;
153     }
154
155     public static Phone getCdmaPhone() {
156         Phone phone;
157         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
158             switch (TelephonyManager.getLteOnCdmaModeStatic()) {
159                 case PhoneConstants.LTE_ON_CDMA_TRUE: {
160                     phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
161                     break;
162                 }
163                 case PhoneConstants.LTE_ON_CDMA_FALSE:
164                 case PhoneConstants.LTE_ON_CDMA_UNKNOWN:
165                 default: {
166                     phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
167                     break;
168                 }
169             }
170         }
171         return phone;
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 }