• 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.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