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