12d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang/* 22d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * Copyright (C) 2010 The Android Open Source Project 32d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * 42d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * Licensed under the Apache License, Version 2.0 (the "License"); 52d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * you may not use this file except in compliance with the License. 62d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * You may obtain a copy of the License at 72d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * 82d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * http://www.apache.org/licenses/LICENSE-2.0 92d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * 102d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * Unless required by applicable law or agreed to in writing, software 112d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * distributed under the License is distributed on an "AS IS" BASIS, 122d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * See the License for the specific language governing permissions and 142d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang * limitations under the License. 152d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang */ 162d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 172d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangpackage com.android.server.sip; 182d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 192d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangimport android.net.sip.ISipSession; 202d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangimport android.net.sip.ISipSessionListener; 212d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangimport android.net.sip.SipProfile; 221b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyanimport android.os.DeadObjectException; 232d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangimport android.util.Log; 242d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 252d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang/** Class to help safely run a callback in a different thread. */ 262d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wangclass SipSessionListenerProxy extends ISipSessionListener.Stub { 272d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang private static final String TAG = "SipSession"; 282d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 292d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang private ISipSessionListener mListener; 302d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 312d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void setListener(ISipSessionListener listener) { 322d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener = listener; 332d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 342d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 352d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public ISipSessionListener getListener() { 362d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang return mListener; 372d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 382d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 392d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang private void proxy(Runnable runnable) { 402d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang // One thread for each calling back. 412d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang // Note: Guarantee ordering if the issue becomes important. Currently, 422d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang // the chance of handling two callback events at a time is none. 4384a357bb6a8005e1c5e924e96a8ecf310e77c47cHung-ying Tyan new Thread(runnable, "SipSessionCallbackThread").start(); 442d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 452d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 462d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onCalling(final ISipSession session) { 472d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 482d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 492d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 502d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 512d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onCalling(session); 522d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 531b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onCalling()"); 542d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 552d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 562d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 572d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 582d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 592d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRinging(final ISipSession session, final SipProfile caller, 6095b15c35608fe3ea679c8a478c6cbd841623371eChia-chi Yeh final String sessionDescription) { 612d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 622d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 632d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 642d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 652d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onRinging(session, caller, sessionDescription); 662d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 671b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRinging()"); 682d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 692d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 702d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 712d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 722d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 732d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRingingBack(final ISipSession session) { 742d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 752d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 762d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 772d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 782d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onRingingBack(session); 792d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 801b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRingingBack()"); 812d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 822d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 832d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 842d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 852d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 862d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onCallEstablished(final ISipSession session, 8795b15c35608fe3ea679c8a478c6cbd841623371eChia-chi Yeh final String sessionDescription) { 882d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 892d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 902d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 912d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 922d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onCallEstablished(session, sessionDescription); 932d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 941b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onCallEstablished()"); 952d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 962d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 972d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 982d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 992d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1002d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onCallEnded(final ISipSession session) { 1012d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1022d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1032d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1042d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 1052d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onCallEnded(session); 1062d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1071b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onCallEnded()"); 1082d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1092d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1102d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1112d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1122d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1132d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onCallBusy(final ISipSession session) { 1142d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1152d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1162d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1172d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 1182d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onCallBusy(session); 1192d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1201b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onCallBusy()"); 1212d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1222d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1232d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1242d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1252d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1262d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onCallChangeFailed(final ISipSession session, 12797963794af1e18674dd111e3ad344d90b16c922cHung-ying Tyan final int errorCode, final String message) { 1282d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1292d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1302d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1312d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 132903e1031605d715e904811b0dd06cc6a518f0048Hung-ying Tyan mListener.onCallChangeFailed(session, errorCode, message); 1332d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1341b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onCallChangeFailed()"); 1352d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1362d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1372d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1382d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1392d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 14097963794af1e18674dd111e3ad344d90b16c922cHung-ying Tyan public void onError(final ISipSession session, final int errorCode, 1412d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang final String message) { 1422d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1432d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1442d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1452d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 146903e1031605d715e904811b0dd06cc6a518f0048Hung-ying Tyan mListener.onError(session, errorCode, message); 1472d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1481b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onError()"); 1492d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1502d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1512d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1522d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1532d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1542d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRegistering(final ISipSession session) { 1552d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1562d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1572d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1582d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 1592d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onRegistering(session); 1602d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1611b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRegistering()"); 1622d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1632d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1642d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1652d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1662d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1672d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRegistrationDone(final ISipSession session, 1682d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang final int duration) { 1692d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1702d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1712d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1722d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 1732d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onRegistrationDone(session, duration); 1742d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1751b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRegistrationDone()"); 1762d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1772d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1782d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1792d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1802d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1812d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRegistrationFailed(final ISipSession session, 18297963794af1e18674dd111e3ad344d90b16c922cHung-ying Tyan final int errorCode, final String message) { 1832d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1842d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1852d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1862d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 187903e1031605d715e904811b0dd06cc6a518f0048Hung-ying Tyan mListener.onRegistrationFailed(session, errorCode, message); 1882d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 1891b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRegistrationFailed()"); 1902d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1912d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1922d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 1932d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 1942d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang 1952d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void onRegistrationTimeout(final ISipSession session) { 1962d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang if (mListener == null) return; 1972d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang proxy(new Runnable() { 1982d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang public void run() { 1992d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang try { 2002d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang mListener.onRegistrationTimeout(session); 2012d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } catch (Throwable t) { 2021b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan handle(t, "onRegistrationTimeout()"); 2032d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 2042d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 2052d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang }); 2062d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang } 2071b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan 2081b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan private void handle(Throwable t, String message) { 2091b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan if (t instanceof DeadObjectException) { 2101b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan mListener = null; 2111b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan // This creates race but it's harmless. Just don't log the error 2121b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan // when it happens. 2131b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan } else if (mListener != null) { 2141b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan Log.w(TAG, message, t); 2151b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan } 2161b1601d740c34de4680ec96368002893aa5f71deHung-ying Tyan } 2172d94231ef91c732f649ff7af9520ee9eac441b16Chung-yih Wang} 218