SipManager.java revision 4e22f5d6687c18440e2f38c7e242d66ad834d1d7
198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang/* 298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Copyright (C) 2010 The Android Open Source Project 398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Licensed under the Apache License, Version 2.0 (the "License"); 598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * you may not use this file except in compliance with the License. 698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * You may obtain a copy of the License at 798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * http://www.apache.org/licenses/LICENSE-2.0 998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 1098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Unless required by applicable law or agreed to in writing, software 1198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * distributed under the License is distributed on an "AS IS" BASIS, 1298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * See the License for the specific language governing permissions and 1498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * limitations under the License. 1598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 1698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 1798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangpackage android.net.sip; 1898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 19845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyanimport android.app.PendingIntent; 2098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.content.Context; 2198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.content.Intent; 2269d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyanimport android.content.pm.PackageManager; 2398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.IBinder; 2498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.Looper; 2598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.RemoteException; 2698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.ServiceManager; 27e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyanimport android.util.Log; 2898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 2998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport java.text.ParseException; 3098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 3198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang/** 3298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * The class provides API for various SIP related tasks. Specifically, the API 33901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * allows an application to: 3498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <ul> 353adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * <li>open a {@link SipProfile} to get ready for making outbound calls or have 363adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * the background SIP service listen to incoming calls and broadcast them 373adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * with registered command string. See 38845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)}, 39901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #open(SipProfile)}, {@link #close}, {@link #isOpened} and 40901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #isRegistered}. It also facilitates handling of the incoming call 41901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * broadcast intent. See 42901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #isIncomingCallIntent}, {@link #getCallId}, 43901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #getOfferSessionDescription} and {@link #takeAudioCall}.</li> 4498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <li>make/take SIP-based audio calls. See 45901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #makeAudioCall} and {@link #takeAudioCall}.</li> 463adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * <li>register/unregister with a SIP service provider manually. See 47901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #register} and {@link #unregister}.</li> 483adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * <li>process SIP events directly with a {@link SipSession} created by 49901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #createSipSession}.</li> 5098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * </ul> 514e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * {@code SipManager} can only be instantiated if SIP API is supported by the 524e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * device. (See {@link #isApiSupported}). 5398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 5498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangpublic class SipManager { 553adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /** 56845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * The result code to be sent back with the incoming call 57845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link PendingIntent}. 58845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @see #open(SipProfile, PendingIntent, SipRegistrationListener) 59845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan */ 60845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan public static final int INCOMING_CALL_RESULT_CODE = 101; 61845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan 624e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan /** 634e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * Key to retrieve the call ID from an incoming call intent. 644e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @see #open(SipProfile, PendingIntent, SipRegistrationListener) 654e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan */ 66845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan public static final String EXTRA_CALL_ID = "android:sipCallID"; 67845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan 684e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan /** 694e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * Key to retrieve the offered session description from an incoming call 704e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * intent. 714e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @see #open(SipProfile, PendingIntent, SipRegistrationListener) 724e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan */ 73845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan public static final String EXTRA_OFFER_SD = "android:sipOfferSD"; 74845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan 75845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan /** 7622523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan * Action to broadcast when SipService is up. 7722523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan * Internal use only. 7822523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan * @hide 7922523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan */ 8022523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan public static final String ACTION_SIP_SERVICE_UP = 8122523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan "android.net.sip.SIP_SERVICE_UP"; 8222523a59d879cf47f1e9c202d001d569fad4f69eHung-ying Tyan /** 833adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Action string for the incoming call intent for the Phone app. 843adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Internal use only. 853adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @hide 863adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan */ 873adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static final String ACTION_SIP_INCOMING_CALL = 8898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_INCOMING_CALL"; 893adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /** 903adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Action string for the add-phone intent. 913adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Internal use only. 923adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @hide 933adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan */ 943adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static final String ACTION_SIP_ADD_PHONE = 9598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_ADD_PHONE"; 963adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /** 973adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Action string for the remove-phone intent. 983adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Internal use only. 993adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @hide 1003adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan */ 1013adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static final String ACTION_SIP_REMOVE_PHONE = 10298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_REMOVE_PHONE"; 1033adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /** 1043adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Part of the ACTION_SIP_ADD_PHONE and ACTION_SIP_REMOVE_PHONE intents. 1053adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Internal use only. 1063adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @hide 1073adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan */ 1083adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static final String EXTRA_LOCAL_URI = "android:localSipUri"; 10998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 110e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan private static final String TAG = "SipManager"; 111e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan 11298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private ISipService mSipService; 1133adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan private Context mContext; 11498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 11598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 1163adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Creates a manager instance. Returns null if SIP API is not supported. 11798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 1183adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @param context application context for creating the manager object 11969d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * @return the manager instance or null if SIP API is not supported 12098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 1213adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static SipManager newInstance(Context context) { 1223adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return (isApiSupported(context) ? new SipManager(context) : null); 12369d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan } 12469d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan 12569d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan /** 12669d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * Returns true if the SIP API is supported by the system. 12769d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan */ 12869d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan public static boolean isApiSupported(Context context) { 1290d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan return true; 1303adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /* TODO: uncomment this before ship 13169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan return context.getPackageManager().hasSystemFeature( 13269d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan PackageManager.FEATURE_SIP); 1330d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan */ 13469d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan } 13569d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan 13669d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan /** 13769d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * Returns true if the system supports SIP-based VoIP. 13869d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan */ 13969d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan public static boolean isVoipSupported(Context context) { 1400d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan return true; 1413adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan /* TODO: uncomment this before ship 14269d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan return context.getPackageManager().hasSystemFeature( 14369d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan PackageManager.FEATURE_SIP_VOIP) && isApiSupported(context); 1440d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan */ 14598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 14698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 147d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan /** 148d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan * Returns true if SIP is only available on WIFI. 149d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan */ 150d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan public static boolean isSipWifiOnly(Context context) { 151d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan return context.getResources().getBoolean( 152d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan com.android.internal.R.bool.config_sip_wifi_only); 153d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan } 154d96284491dfc918c72258f84b47a6554c21db92eHung-ying Tyan 1553adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan private SipManager(Context context) { 1563adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan mContext = context; 15769d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan createSipService(); 15898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 15998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 16069d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan private void createSipService() { 16168144a84e3cd43ba4f62c73dbd2ce9c74d50e1a6Chung-yih Wang IBinder b = ServiceManager.getService(Context.SIP_SERVICE); 16298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService = ISipService.Stub.asInterface(b); 16398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 16498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 16598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 1663adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Opens the profile for making calls. The caller may make subsequent calls 1673adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * through {@link #makeAudioCall}. If one also wants to receive calls on the 168845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * profile, use 169845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)} 1703adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * instead. 17198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 17298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to make calls from 17398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if the profile contains incorrect settings or 17498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calling the SIP service results in an error 17598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 17698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void open(SipProfile localProfile) throws SipException { 17798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 17898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.open(localProfile); 17998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 18098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("open()", e); 18198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 18298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 18398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 18498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 1853adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Opens the profile for making calls and/or receiving calls. The caller may 1863adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * make subsequent calls through {@link #makeAudioCall}. If the 1873adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * auto-registration option is enabled in the profile, the SIP service 1883adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * will register the profile to the corresponding SIP provider periodically 1894e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * in order to receive calls from the provider. When the SIP service 1904e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * receives a new call, it will send out an intent with the provided action 1914e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * string. The intent contains a call ID extra and an offer session 1924e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * description string extra. Use {@link #getCallId} and 1934e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * {@link #getOfferSessionDescription} to retrieve those extras. 19498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 19598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to receive incoming calls for 196845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @param incomingCallPendingIntent When an incoming call is received, the 197845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * SIP service will call 198845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link PendingIntent#send(Context, int, Intent)} to send back the 199845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * intent to the caller with {@link #INCOMING_CALL_RESULT_CODE} as the 200845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * result code and the intent to fill in the call ID and session 201845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * description information. It cannot be null. 20298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to registration events; can be null 203845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @see #getCallId 204845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @see #getOfferSessionDescription 205845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @see #takeAudioCall 206845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * @throws NullPointerException if {@code incomingCallPendingIntent} is null 20798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if the profile contains incorrect settings or 20898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calling the SIP service results in an error 2094e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @see #isIncomingCallIntent 2104e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @see #getCallId 2114e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @see #getOfferSessionDescription 21298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 21398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void open(SipProfile localProfile, 214845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan PendingIntent incomingCallPendingIntent, 21598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 216845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan if (incomingCallPendingIntent == null) { 217845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan throw new NullPointerException( 218845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan "incomingCallPendingIntent cannot be null"); 219845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan } 22098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 221845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan mSipService.open3(localProfile, incomingCallPendingIntent, 222f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan createRelay(listener, localProfile.getUriString())); 22398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 22498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("open()", e); 22598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 22698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 22798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 22898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 22998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Sets the listener to listen to registration events. No effect if the 230845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * profile has not been opened to receive calls (see 231845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)}). 23298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 23398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile 23498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to registration events; can be null 23598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 23698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 23798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void setRegistrationListener(String localProfileUri, 23898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 23998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 24098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.setRegistrationListener( 241f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan localProfileUri, createRelay(listener, localProfileUri)); 24298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 24398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("setRegistrationListener()", e); 24498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 24598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 24698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 24798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 24898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Closes the specified profile to not make/receive calls. All the resources 24998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * that were allocated to the profile are also released. 25098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 25198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile to close 25298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 25398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 25498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void close(String localProfileUri) throws SipException { 25598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 25698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.close(localProfileUri); 25798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 25898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("close()", e); 25998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 26098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 26198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 26298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 2633adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Checks if the specified profile is opened in the SIP service for 2643adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * making and/or receiving calls. 26598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 26698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile in question 26798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return true if the profile is enabled to receive calls 26898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 26998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 27098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public boolean isOpened(String localProfileUri) throws SipException { 27198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 27298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.isOpened(localProfileUri); 27398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 27498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("isOpened()", e); 27598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 27698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 27798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 27898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 2793adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Checks if the SIP service has successfully registered the profile to the 2803adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * SIP provider (specified in the profile) for receiving calls. Returning 2813adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * true from this method also implies the profile is opened 2823adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * ({@link #isOpened}). 28398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 28498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile in question 2853adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @return true if the profile is registered to the SIP provider; false if 2863adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * the profile has not been opened in the SIP service or the SIP 2873adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * service has not yet successfully registered the profile to the SIP 2883adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * provider 28998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 29098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 29198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public boolean isRegistered(String localProfileUri) throws SipException { 29298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 29398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.isRegistered(localProfileUri); 29498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 29598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("isRegistered()", e); 29698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 29798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 29898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 29998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 300f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * Creates a {@link SipAudioCall} to make a call. The attempt will be timed 301f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * out if the call is not established within {@code timeout} seconds and 302f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)} 303f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * will be called. 30498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 30598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to make the call from 30698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param peerProfile the SIP profile to make the call to 30798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 30898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 3094e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @param timeout the timeout value in seconds. Default value (defined by 3104e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * SIP protocol) is used if {@code timeout} is zero or negative. 31198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 31298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 313f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @see SipAudioCall.Listener.onError 31498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 3153adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public SipAudioCall makeAudioCall(SipProfile localProfile, 316f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan SipProfile peerProfile, SipAudioCall.Listener listener, int timeout) 31798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 3183adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan SipAudioCall call = new SipAudioCall(mContext, localProfile); 31998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setListener(listener); 3207a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan SipSession s = createSipSession(localProfile, null); 3217a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan if (s == null) { 3227a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan throw new SipException( 3237a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan "Failed to create SipSession; network available?"); 3247a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan } 3257a4ec7268fbfb56e22f1cb8497d37ed733d8aa8eHung-ying Tyan call.makeCall(peerProfile, s, timeout); 32698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return call; 32798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 32898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 32998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 330845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * Creates a {@link SipAudioCall} to make an audio call. The attempt will be 331845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * timed out if the call is not established within {@code timeout} seconds 332845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * and 333f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)} 334f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * will be called. 33598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 33698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri URI of the SIP profile to make the call from 33798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param peerProfileUri URI of the SIP profile to make the call to 33898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 33998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 3404e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * @param timeout the timeout value in seconds. Default value (defined by 3414e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * SIP protocol) is used if {@code timeout} is zero or negative. 34298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 34398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 344f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @see SipAudioCall.Listener.onError 34598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 3463adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public SipAudioCall makeAudioCall(String localProfileUri, 347f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan String peerProfileUri, SipAudioCall.Listener listener, int timeout) 34898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 34998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 3503adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return makeAudioCall( 35198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang new SipProfile.Builder(localProfileUri).build(), 352f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan new SipProfile.Builder(peerProfileUri).build(), listener, 353f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan timeout); 35498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (ParseException e) { 35598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("build SipProfile", e); 35698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 35798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 35898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 35998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 3603adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * The method calls {@code takeAudioCall(incomingCallIntent, 36198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * listener, true}. 36298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 3633adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * @see #takeAudioCall(Intent, SipAudioCall.Listener, boolean) 36498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 3653adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public SipAudioCall takeAudioCall(Intent incomingCallIntent, 3663adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan SipAudioCall.Listener listener) throws SipException { 3673adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return takeAudioCall(incomingCallIntent, listener, true); 36898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 36998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 37098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 37198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates a {@link SipAudioCall} to take an incoming call. Before the call 37298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * is returned, the listener will receive a 373901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link SipAudioCall.Listener#onRinging} 37498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * callback. 37598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 37698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 37798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 37898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 37998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 38098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 38198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 3823adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public SipAudioCall takeAudioCall(Intent incomingCallIntent, 3833adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan SipAudioCall.Listener listener, boolean ringtoneEnabled) 3843adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan throws SipException { 38598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (incomingCallIntent == null) return null; 38698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 38798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(incomingCallIntent); 38898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (callId == null) { 38998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("Call ID missing in incoming call intent"); 39098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 39198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 3926d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh String offerSd = getOfferSessionDescription(incomingCallIntent); 39398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (offerSd == null) { 39498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("Session description missing in incoming " 39598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang + "call intent"); 39698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 39798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 39898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 39998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang ISipSession session = mSipService.getPendingSession(callId); 40098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (session == null) return null; 4013adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan SipAudioCall call = new SipAudioCall( 4023adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan mContext, session.getLocalProfile()); 40398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setRingtoneEnabled(ringtoneEnabled); 4043adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan call.attachCall(new SipSession(session), offerSd); 40598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setListener(listener); 40698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return call; 40798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (Throwable t) { 40898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("takeAudioCall()", t); 40998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 41098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 41198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 41298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 41398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Checks if the intent is an incoming call broadcast intent. 41498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 41598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param intent the intent in question 41698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return true if the intent is an incoming call broadcast intent 41798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 41898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static boolean isIncomingCallIntent(Intent intent) { 41998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (intent == null) return false; 42098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(intent); 4216d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh String offerSd = getOfferSessionDescription(intent); 42298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return ((callId != null) && (offerSd != null)); 42398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 42498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 42598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 42698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the call ID from the specified incoming call broadcast intent. 42798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 42898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 42998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the call ID or null if the intent does not contain it 43098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 43198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static String getCallId(Intent incomingCallIntent) { 4323adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return incomingCallIntent.getStringExtra(EXTRA_CALL_ID); 43398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 43498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 43598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 43698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the offer session description from the specified incoming call 43798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * broadcast intent. 43898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 43998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 44098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the offer session description or null if the intent does not 44198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * have it 44298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 4436d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh public static String getOfferSessionDescription(Intent incomingCallIntent) { 4443adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return incomingCallIntent.getStringExtra(EXTRA_OFFER_SD); 44598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 44698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 44798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 44898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates an incoming call broadcast intent. 44998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 45098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param callId the call ID of the incoming call 45198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param sessionDescription the session description of the incoming call 45298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the incoming call intent 45398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @hide 45498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 4553adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public static Intent createIncomingCallBroadcast(String callId, 4563adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan String sessionDescription) { 4573adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan Intent intent = new Intent(); 4583adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan intent.putExtra(EXTRA_CALL_ID, callId); 4593adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan intent.putExtra(EXTRA_OFFER_SD, sessionDescription); 46098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return intent; 46198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 46298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 46398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 4643adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Manually registers the profile to the corresponding SIP provider for 465845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * receiving calls. 466845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * {@link #open(SipProfile, PendingIntent, SipRegistrationListener)} is 467845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * still needed to be called at least once in order for the SIP service to 468845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * notify the caller with the {@code PendingIntent} when an incoming call is 469845f7332f04864c5483b3e63da5db076fc7a888aHung-ying Tyan * received. 47098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 47198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to register with 472901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * @param expiryTime registration expiration time (in seconds) 47398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the registration events 47498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 47598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 47698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void register(SipProfile localProfile, int expiryTime, 47798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 47898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 479f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan ISipSession session = mSipService.createSession(localProfile, 480f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan createRelay(listener, localProfile.getUriString())); 48198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang session.register(expiryTime); 48298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 48398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("register()", e); 48498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 48598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 48698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 48798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 4883adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * Manually unregisters the profile from the corresponding SIP provider for 4893adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * stop receiving further calls. This may interference with the auto 4903adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * registration process in the SIP service if the auto-registration option 4913adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan * in the profile is enabled. 49298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 49398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to register with 49498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the registration events 49598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 49698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 49798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void unregister(SipProfile localProfile, 49898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 49998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 500f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan ISipSession session = mSipService.createSession(localProfile, 501f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan createRelay(listener, localProfile.getUriString())); 50298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang session.unregister(); 50398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 50498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("unregister()", e); 50598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 50698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 50798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 50898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 5094e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * Gets the {@link SipSession} that handles the incoming call. For audio 51098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calls, consider to use {@link SipAudioCall} to handle the incoming call. 511901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * See {@link #takeAudioCall}. Note that the method may be called only once 512901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * for the same intent. For subsequent calls on the same intent, the method 513901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * returns null. 51498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 51598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 51698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the session object that handles the incoming call 51798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 5184e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan public SipSession getSessionFor(Intent incomingCallIntent) 51998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 52098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 52198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(incomingCallIntent); 5224e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan ISipSession s = mSipService.getPendingSession(callId); 5234e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan return new SipSession(s); 52498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 52598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("getSessionFor()", e); 52698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 52798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 52898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 52998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static ISipSessionListener createRelay( 530f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan SipRegistrationListener listener, String uri) { 531f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan return ((listener == null) ? null : new ListenerRelay(listener, uri)); 53298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 53398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 53498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 5354e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * Creates a {@link SipSession} with the specified profile. Use other 5364e22f5d6687c18440e2f38c7e242d66ad834d1d7Hung-ying Tyan * methods, if applicable, instead of interacting with {@link SipSession} 53798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * directly. 53898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 53998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile the session is associated with 54098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to SIP session events 54198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 5423adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan public SipSession createSipSession(SipProfile localProfile, 5433adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan SipSession.Listener listener) throws SipException { 54498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 5453adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan ISipSession s = mSipService.createSession(localProfile, null); 5463adf1946e78b52686fa5458e24645b05da57dc22Hung-ying Tyan return new SipSession(s, listener); 54798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 54898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("createSipSession()", e); 54998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 55098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 55198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 55298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 55398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the list of profiles hosted by the SIP service. The user information 55498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * (username, password and display name) are crossed out. 55598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @hide 55698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 55798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipProfile[] getListOfProfiles() { 55898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 55998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.getListOfProfiles(); 56098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 56198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return null; 56298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 56398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 56498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 56598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static class ListenerRelay extends SipSessionAdapter { 56698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private SipRegistrationListener mListener; 567f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan private String mUri; 56898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 56998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang // listener must not be null 570f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan public ListenerRelay(SipRegistrationListener listener, String uri) { 57198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener = listener; 572f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan mUri = uri; 57398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 57498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 57598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private String getUri(ISipSession session) { 57698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 577d8d3b15f408314ac88201eee3e401a35556ba669Hung-ying Tyan return ((session == null) 578f3d1e1fd0f86eb956c82634c075b167dc367757cHung-ying Tyan ? mUri 579d8d3b15f408314ac88201eee3e401a35556ba669Hung-ying Tyan : session.getLocalProfile().getUriString()); 580e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan } catch (Throwable e) { 581e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan // SipService died? SIP stack died? 582e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan Log.w(TAG, "getUri(): " + e); 583e8782e2fdfd256296a0d1fd2a1c3f98d58103eaaHung-ying Tyan return null; 58498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 58598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 58698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 58798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 58898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistering(ISipSession session) { 58998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistering(getUri(session)); 59098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 59198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 59298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 59398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistrationDone(ISipSession session, int duration) { 59498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang long expiryTime = duration; 59598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (duration > 0) expiryTime += System.currentTimeMillis(); 59698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistrationDone(getUri(session), expiryTime); 59798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 59898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 59998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 600a0171082cfc4b860a82dcf5ebbd498b253f1032fHung-ying Tyan public void onRegistrationFailed(ISipSession session, int errorCode, 60198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String message) { 602a0171082cfc4b860a82dcf5ebbd498b253f1032fHung-ying Tyan mListener.onRegistrationFailed(getUri(session), errorCode, message); 60398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 60498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 60598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 60698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistrationTimeout(ISipSession session) { 60798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistrationFailed(getUri(session), 6081ab079168ccc185408a8691c6b804021d79f7376Hung-ying Tyan SipErrorCode.TIME_OUT, "registration timed out"); 60998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 61098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 61198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang} 612