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