SipManager.java revision f498e98d2e2910e866ec0728cebbe676dd475d9e
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 1998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.content.Context; 2098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.content.Intent; 2169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyanimport android.content.pm.PackageManager; 2298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.IBinder; 2398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.Looper; 2498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.RemoteException; 2598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport android.os.ServiceManager; 2698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 2798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangimport java.text.ParseException; 2898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 2998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang/** 3098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * The class provides API for various SIP related tasks. Specifically, the API 31901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * allows an application to: 3298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <ul> 3398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <li>register a {@link SipProfile} to have the background SIP service listen 3498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * to incoming calls and broadcast them with registered command string. See 3598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * {@link #open(SipProfile, String, SipRegistrationListener)}, 36901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #open(SipProfile)}, {@link #close}, {@link #isOpened} and 37901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #isRegistered}. It also facilitates handling of the incoming call 38901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * broadcast intent. See 39901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #isIncomingCallIntent}, {@link #getCallId}, 40901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #getOfferSessionDescription} and {@link #takeAudioCall}.</li> 4198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <li>make/take SIP-based audio calls. See 42901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #makeAudioCall} and {@link #takeAudioCall}.</li> 4398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <li>register/unregister with a SIP service provider. See 44901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #register} and {@link #unregister}.</li> 4598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * <li>process SIP events directly with a {@link ISipSession} created by 46901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #createSipSession}.</li> 4798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * </ul> 4898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @hide 4998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 5098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wangpublic class SipManager { 5198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** @hide */ 5298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static final String SIP_INCOMING_CALL_ACTION = 5398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_INCOMING_CALL"; 5498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** @hide */ 5598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static final String SIP_ADD_PHONE_ACTION = 5698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_ADD_PHONE"; 5798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** @hide */ 5898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static final String SIP_REMOVE_PHONE_ACTION = 5998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang "com.android.phone.SIP_REMOVE_PHONE"; 6098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** @hide */ 6198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static final String LOCAL_URI_KEY = "LOCAL SIPURI"; 6298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 6398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static final String CALL_ID_KEY = "CallID"; 6498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static final String OFFER_SD_KEY = "OfferSD"; 6598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 6698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private ISipService mSipService; 6798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 6898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 6969d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * Gets a manager instance. Returns null if SIP API is not supported. 7098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 7169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * @param context application context for checking if SIP API is supported 7269d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * @return the manager instance or null if SIP API is not supported 7398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 7469d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan public static SipManager getInstance(Context context) { 7569d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan return (isApiSupported(context) ? new SipManager() : null); 7669d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan } 7769d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan 7869d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan /** 7969d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * Returns true if the SIP API is supported by the system. 8069d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan */ 8169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan public static boolean isApiSupported(Context context) { 820d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan return true; 830d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan /* 8469d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan return context.getPackageManager().hasSystemFeature( 8569d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan PackageManager.FEATURE_SIP); 860d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan */ 8769d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan } 8869d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan 8969d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan /** 9069d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan * Returns true if the system supports SIP-based VoIP. 9169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan */ 9269d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan public static boolean isVoipSupported(Context context) { 930d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan return true; 940d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan /* 9569d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan return context.getPackageManager().hasSystemFeature( 9669d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan PackageManager.FEATURE_SIP_VOIP) && isApiSupported(context); 970d889a979d7e2e6f21de72de0c45a9c8ffa930e6Hung-ying Tyan */ 9898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 9998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 10098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private SipManager() { 10169d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan createSipService(); 10298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 10398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 10469d66b75112e2763bf8bce718c22c7baa1efac7dHung-ying Tyan private void createSipService() { 10598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (mSipService != null) return; 10668144a84e3cd43ba4f62c73dbd2ce9c74d50e1a6Chung-yih Wang IBinder b = ServiceManager.getService(Context.SIP_SERVICE); 10798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService = ISipService.Stub.asInterface(b); 10898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 10998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 11098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 11198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Opens the profile for making calls and/or receiving calls. Subsequent 11298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * SIP calls can be made through the default phone UI. The caller may also 113901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * make subsequent calls through {@link #makeAudioCall}. 11498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * If the receiving-call option is enabled in the profile, the SIP service 11598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * will register the profile to the corresponding server periodically in 11698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * order to receive calls from the server. 11798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 11898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to make calls from 11998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if the profile contains incorrect settings or 12098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calling the SIP service results in an error 12198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 12298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void open(SipProfile localProfile) throws SipException { 12398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 12498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.open(localProfile); 12598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 12698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("open()", e); 12798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 12898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 12998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 13098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 13198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Opens the profile for making calls and/or receiving calls. Subsequent 13298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * SIP calls can be made through the default phone UI. The caller may also 133901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * make subsequent calls through {@link #makeAudioCall}. 13498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * If the receiving-call option is enabled in the profile, the SIP service 13598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * will register the profile to the corresponding server periodically in 13698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * order to receive calls from the server. 13798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 13898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to receive incoming calls for 13998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallBroadcastAction the action to be broadcast when an 14098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * incoming call is received 14198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to registration events; can be null 14298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if the profile contains incorrect settings or 14398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calling the SIP service results in an error 14498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 14598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void open(SipProfile localProfile, 14698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String incomingCallBroadcastAction, 14798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 14898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 14998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.open3(localProfile, incomingCallBroadcastAction, 15098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang createRelay(listener)); 15198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 15298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("open()", e); 15398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 15498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 15598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 15698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 15798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Sets the listener to listen to registration events. No effect if the 158901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * profile has not been opened to receive calls (see {@link #open}). 15998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 16098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile 16198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to registration events; can be null 16298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 16398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 16498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void setRegistrationListener(String localProfileUri, 16598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 16698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 16798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.setRegistrationListener( 16898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang localProfileUri, createRelay(listener)); 16998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 17098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("setRegistrationListener()", e); 17198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 17298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 17398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 17498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 17598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Closes the specified profile to not make/receive calls. All the resources 17698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * that were allocated to the profile are also released. 17798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 17898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile to close 17998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 18098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 18198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void close(String localProfileUri) throws SipException { 18298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 18398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mSipService.close(localProfileUri); 18498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 18598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("close()", e); 18698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 18798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 18898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 18998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 19098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Checks if the specified profile is enabled to receive calls. 19198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 19298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile in question 19398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return true if the profile is enabled to receive calls 19498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 19598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 19698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public boolean isOpened(String localProfileUri) throws SipException { 19798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 19898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.isOpened(localProfileUri); 19998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 20098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("isOpened()", e); 20198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 20298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 20398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 20498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 20598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Checks if the specified profile is registered to the server for 20698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * receiving calls. 20798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 20898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri the URI of the profile in question 20998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return true if the profile is registered to the server 21098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 21198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 21298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public boolean isRegistered(String localProfileUri) throws SipException { 21398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 21498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.isRegistered(localProfileUri); 21598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 21698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("isRegistered()", e); 21798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 21898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 21998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 22098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 221f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * Creates a {@link SipAudioCall} to make a call. The attempt will be timed 222f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * out if the call is not established within {@code timeout} seconds and 223f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)} 224f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * will be called. 22598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 22698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param context context to create a {@link SipAudioCall} object 22798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to make the call from 22898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param peerProfile the SIP profile to make the call to 22998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 23098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 231f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @param timeout the timeout value in seconds 23298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 23398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 234f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @see SipAudioCall.Listener.onError 23598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 23698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipAudioCall makeAudioCall(Context context, SipProfile localProfile, 237f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan SipProfile peerProfile, SipAudioCall.Listener listener, int timeout) 23898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 23998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipAudioCall call = new SipAudioCallImpl(context, localProfile); 24098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setListener(listener); 241f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan call.makeCall(peerProfile, this, timeout); 24298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return call; 24398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 24498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 24598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 24698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates a {@link SipAudioCall} to make a call. To use this method, one 247f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * must call {@link #open(SipProfile)} first. The attempt will be timed out 248f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * if the call is not established within {@code timeout} seconds and 249f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * {@code SipAudioCall.Listener.onError(SipAudioCall, SipErrorCode.TIME_OUT, String)} 250f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * will be called. 25198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 25298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param context context to create a {@link SipAudioCall} object 25398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfileUri URI of the SIP profile to make the call from 25498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param peerProfileUri URI of the SIP profile to make the call to 25598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 25698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 257f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @param timeout the timeout value in seconds 25898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 25998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 260f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan * @see SipAudioCall.Listener.onError 26198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 26298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipAudioCall makeAudioCall(Context context, String localProfileUri, 263f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan String peerProfileUri, SipAudioCall.Listener listener, int timeout) 26498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 26598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 26698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return makeAudioCall(context, 26798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang new SipProfile.Builder(localProfileUri).build(), 268f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan new SipProfile.Builder(peerProfileUri).build(), listener, 269f498e98d2e2910e866ec0728cebbe676dd475d9eHung-ying Tyan timeout); 27098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (ParseException e) { 27198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("build SipProfile", e); 27298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 27398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 27498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 27598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 27698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * The method calls {@code takeAudioCall(context, incomingCallIntent, 27798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * listener, true}. 27898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 27998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @see #takeAudioCall(Context, Intent, SipAudioCall.Listener, boolean) 28098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 28198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipAudioCall takeAudioCall(Context context, 28298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang Intent incomingCallIntent, SipAudioCall.Listener listener) 28398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 28498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return takeAudioCall(context, incomingCallIntent, listener, true); 28598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 28698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 28798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 28898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates a {@link SipAudioCall} to take an incoming call. Before the call 28998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * is returned, the listener will receive a 290901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link SipAudioCall.Listener#onRinging} 29198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * callback. 29298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 29398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param context context to create a {@link SipAudioCall} object 29498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 29598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the call events from {@link SipAudioCall}; 29698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * can be null 29798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return a {@link SipAudioCall} object 29898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 29998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 30098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipAudioCall takeAudioCall(Context context, 30198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang Intent incomingCallIntent, SipAudioCall.Listener listener, 30298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang boolean ringtoneEnabled) throws SipException { 30398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (incomingCallIntent == null) return null; 30498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 30598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(incomingCallIntent); 30698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (callId == null) { 30798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("Call ID missing in incoming call intent"); 30898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 30998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 3106d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh String offerSd = getOfferSessionDescription(incomingCallIntent); 31198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (offerSd == null) { 31298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("Session description missing in incoming " 31398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang + "call intent"); 31498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 31598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 31698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 31798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang ISipSession session = mSipService.getPendingSession(callId); 31898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (session == null) return null; 31998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipAudioCall call = new SipAudioCallImpl( 32098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang context, session.getLocalProfile()); 32198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setRingtoneEnabled(ringtoneEnabled); 3226d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh call.attachCall(session, offerSd); 32398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang call.setListener(listener); 32498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return call; 32598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (Throwable t) { 32698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("takeAudioCall()", t); 32798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 32898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 32998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 33098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 33198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Checks if the intent is an incoming call broadcast intent. 33298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 33398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param intent the intent in question 33498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return true if the intent is an incoming call broadcast intent 33598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 33698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static boolean isIncomingCallIntent(Intent intent) { 33798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (intent == null) return false; 33898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(intent); 3396d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh String offerSd = getOfferSessionDescription(intent); 34098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return ((callId != null) && (offerSd != null)); 34198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 34298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 34398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 34498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the call ID from the specified incoming call broadcast intent. 34598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 34698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 34798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the call ID or null if the intent does not contain it 34898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 34998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static String getCallId(Intent incomingCallIntent) { 35098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return incomingCallIntent.getStringExtra(CALL_ID_KEY); 35198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 35298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 35398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 35498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the offer session description from the specified incoming call 35598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * broadcast intent. 35698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 35798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 35898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the offer session description or null if the intent does not 35998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * have it 36098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 3616d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh public static String getOfferSessionDescription(Intent incomingCallIntent) { 3626d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh return incomingCallIntent.getStringExtra(OFFER_SD_KEY); 36398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 36498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 36598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 36698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates an incoming call broadcast intent. 36798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 36898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param action the action string to broadcast 36998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param callId the call ID of the incoming call 37098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param sessionDescription the session description of the incoming call 37198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the incoming call intent 37298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @hide 37398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 37498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public static Intent createIncomingCallBroadcast(String action, 3756d0ef774a2492b0996ded3a43c300c7f72a94897Chia-chi Yeh String callId, String sessionDescription) { 37698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang Intent intent = new Intent(action); 37798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang intent.putExtra(CALL_ID_KEY, callId); 37898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang intent.putExtra(OFFER_SD_KEY, sessionDescription); 37998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return intent; 38098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 38198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 38298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 38398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Registers the profile to the corresponding server for receiving calls. 384901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * {@link #open} is still needed to be called at least once in order for 385901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * the SIP service to broadcast an intent when an incoming call is received. 38698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 38798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to register with 388901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * @param expiryTime registration expiration time (in seconds) 38998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the registration events 39098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 39198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 39298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void register(SipProfile localProfile, int expiryTime, 39398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 39498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 39598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang ISipSession session = mSipService.createSession( 39698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang localProfile, createRelay(listener)); 39798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang session.register(expiryTime); 39898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 39998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("register()", e); 40098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 40198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 40298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 40398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 40498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Unregisters the profile from the corresponding server for not receiving 40598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * further calls. 40698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 40798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile to register with 40898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to the registration events 40998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @throws SipException if calling the SIP service results in an error 41098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 41198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void unregister(SipProfile localProfile, 41298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) throws SipException { 41398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 41498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang ISipSession session = mSipService.createSession( 41598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang localProfile, createRelay(listener)); 41698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang session.unregister(); 41798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 41898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("unregister()", e); 41998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 42098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 42198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 42298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 42398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the {@link ISipSession} that handles the incoming call. For audio 42498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * calls, consider to use {@link SipAudioCall} to handle the incoming call. 425901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * See {@link #takeAudioCall}. Note that the method may be called only once 426901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * for the same intent. For subsequent calls on the same intent, the method 427901503e1cf8b6cfac1540a22c325eb5cdd879429Hung-ying Tyan * returns null. 42898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 42998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param incomingCallIntent the incoming call broadcast intent 43098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @return the session object that handles the incoming call 43198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 43298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public ISipSession getSessionFor(Intent incomingCallIntent) 43398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throws SipException { 43498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 43598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String callId = getCallId(incomingCallIntent); 43698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.getPendingSession(callId); 43798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 43898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("getSessionFor()", e); 43998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 44098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 44198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 44298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static ISipSessionListener createRelay( 44398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang SipRegistrationListener listener) { 44498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return ((listener == null) ? null : new ListenerRelay(listener)); 44598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 44698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 44798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 44898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Creates a {@link ISipSession} with the specified profile. Use other 44998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * methods, if applicable, instead of interacting with {@link ISipSession} 45098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * directly. 45198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * 45298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param localProfile the SIP profile the session is associated with 45398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @param listener to listen to SIP session events 45498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 45598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public ISipSession createSipSession(SipProfile localProfile, 45698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang ISipSessionListener listener) throws SipException { 45798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 45898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.createSession(localProfile, listener); 45998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 46098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new SipException("createSipSession()", e); 46198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 46298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 46398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 46498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang /** 46598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * Gets the list of profiles hosted by the SIP service. The user information 46698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * (username, password and display name) are crossed out. 46798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang * @hide 46898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang */ 46998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public SipProfile[] getListOfProfiles() { 47098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 47198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return mSipService.getListOfProfiles(); 47298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 47398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return null; 47498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 47598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 47698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 47798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private static class ListenerRelay extends SipSessionAdapter { 47898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private SipRegistrationListener mListener; 47998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 48098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang // listener must not be null 48198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public ListenerRelay(SipRegistrationListener listener) { 48298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener = listener; 48398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 48498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 48598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang private String getUri(ISipSession session) { 48698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang try { 48798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang return session.getLocalProfile().getUriString(); 48898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } catch (RemoteException e) { 48998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang throw new RuntimeException(e); 49098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 49198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 49298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 49398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 49498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistering(ISipSession session) { 49598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistering(getUri(session)); 49698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 49798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 49898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 49998cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistrationDone(ISipSession session, int duration) { 50098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang long expiryTime = duration; 50198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang if (duration > 0) expiryTime += System.currentTimeMillis(); 50298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistrationDone(getUri(session), expiryTime); 50398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 50498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 50598cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 506bba28d83647438df39b55d59161e3f69ff8209f6Hung-ying Tyan public void onRegistrationFailed(ISipSession session, String errorCode, 50798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang String message) { 5081ab079168ccc185408a8691c6b804021d79f7376Hung-ying Tyan mListener.onRegistrationFailed(getUri(session), 5091ab079168ccc185408a8691c6b804021d79f7376Hung-ying Tyan Enum.valueOf(SipErrorCode.class, errorCode), message); 51098cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 51198cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang 51298cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang @Override 51398cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang public void onRegistrationTimeout(ISipSession session) { 51498cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang mListener.onRegistrationFailed(getUri(session), 5151ab079168ccc185408a8691c6b804021d79f7376Hung-ying Tyan SipErrorCode.TIME_OUT, "registration timed out"); 51698cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 51798cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang } 51898cee0ce2354234e72bafb836864ec10a490ea4dChung-yih Wang} 519