1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1933ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braunimport android.content.ComponentName;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.net.LocalServerSocket;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Looper;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
2499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
25c67761d00a25bd095364e3ff4e4cb8e88b2e974cDavid Braunimport android.telephony.TelephonyManager;
2633ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.cdma.CDMALTEPhone;
28c67761d00a25bd095364e3ff4e4cb8e88b2e974cDavid Braunimport com.android.internal.telephony.cdma.CDMAPhone;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.gsm.GSMPhone;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.sip.SipPhone;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.sip.SipPhoneFactory;
33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic class PhoneFactory {
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "PhoneFactory";
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int SOCKET_OPEN_MAX_RETRY = 3;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Class Variables
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private Phone sProxyPhone = null;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private CommandsInterface sCommandsInterface = null;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private boolean sMadeDefaults = false;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private PhoneNotifier sPhoneNotifier;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private Looper sLooper;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static private Context sContext;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Class Methods
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static void makeDefaultPhones(Context context) {
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        makeDefaultPhone(context);
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * FIXME replace this with some other way of making these
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * instances
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static void makeDefaultPhone(Context context) {
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(Phone.class) {
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!sMadeDefaults) {
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sLooper = Looper.myLooper();
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sContext = context;
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (sLooper == null) {
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    throw new RuntimeException(
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        "PhoneFactory.makeDefaultPhone must be called from Looper thread");
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int retryCount = 0;
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                for(;;) {
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    boolean hasException = false;
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    retryCount ++;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    try {
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // use UNIX domain socket to
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // prevent subsequent initialization
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        new LocalServerSocket("com.android.internal.telephony");
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } catch (java.io.IOException ex) {
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        hasException = true;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if ( !hasException ) {
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        throw new RuntimeException("PhoneFactory probably already running");
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        try {
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } catch (InterruptedException er) {
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sPhoneNotifier = new DefaultPhoneNotifier();
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Get preferred network mode
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    preferredNetworkMode = Phone.NT_MODE_GLOBAL;
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1066ce6af4664de8d12c238f00b1f566db010d52a44Jeff Sharkey                int networkMode = Settings.Global.getInt(context.getContentResolver(),
1076ce6af4664de8d12c238f00b1f566db010d52a44Jeff Sharkey                        Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
10899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1105ceae6074e0729fbbc422db2f263bf7cf453bf1aNaveen Kalla                int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
11199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //reads the system properties and makes commandsinterface
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
116e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                // Instantiate UiccController so that all other classes can just call getInstance()
117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                UiccController.make(context, sCommandsInterface);
118e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int phoneType = TelephonyManager.getPhoneType(networkMode);
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
12199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.i(LOG_TAG, "Creating GSMPhone");
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    sProxyPhone = new PhoneProxy(new GSMPhone(context,
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            sCommandsInterface, sPhoneNotifier));
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    switch (TelephonyManager.getLteOnCdmaModeStatic()) {
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        case PhoneConstants.LTE_ON_CDMA_TRUE:
12799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                            Rlog.i(LOG_TAG, "Creating CDMALTEPhone");
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                sCommandsInterface, sPhoneNotifier));
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            break;
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        case PhoneConstants.LTE_ON_CDMA_FALSE:
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        default:
13399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                            Rlog.i(LOG_TAG, "Creating CDMAPhone");
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            sProxyPhone = new PhoneProxy(new CDMAPhone(context,
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    sCommandsInterface, sPhoneNotifier));
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            break;
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14033ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                // Ensure that we have a default SMS app. Requesting the app with
14133ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                // updateIfNeeded set to true is enough to configure a default SMS app.
14233ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                ComponentName componentName =
14333ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                        SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */);
14433ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                String packageName = "NONE";
14533ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                if (componentName != null) {
14633ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                    packageName = componentName.getPackageName();
14733ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                }
14833ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun                Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName);
14933ab7bad1f2ccb5dea26d0def6e43a4f2d1b9cb9David Braun
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sMadeDefaults = true;
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static Phone getDefaultPhone() {
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (sLooper != Looper.myLooper()) {
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new RuntimeException(
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                "PhoneFactory.getDefaultPhone must be called from Looper thread");
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!sMadeDefaults) {
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalStateException("Default phones haven't been made yet!");
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville       return sProxyPhone;
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static Phone getCdmaPhone() {
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Phone phone;
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            switch (TelephonyManager.getLteOnCdmaModeStatic()) {
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case PhoneConstants.LTE_ON_CDMA_TRUE: {
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case PhoneConstants.LTE_ON_CDMA_FALSE:
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case PhoneConstants.LTE_ON_CDMA_UNKNOWN:
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                default: {
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return phone;
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static Phone getGsmPhone() {
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return phone;
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Makes a {@link SipPhone} object.
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param sipUri the local SIP URI the phone runs on
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return the {@code SipPhone} object or null if the SIP URI is not valid
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static SipPhone makeSipPhone(String sipUri) {
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
202