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