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