Home | History | Annotate | Download | only in sip
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.sip;
     18 
     19 import android.net.sip.ISipSession;
     20 import android.net.sip.ISipSessionListener;
     21 import android.net.sip.SipProfile;
     22 import android.os.DeadObjectException;
     23 import android.util.Log;
     24 
     25 /** Class to help safely run a callback in a different thread. */
     26 class SipSessionListenerProxy extends ISipSessionListener.Stub {
     27     private static final String TAG = "SipSession";
     28 
     29     private ISipSessionListener mListener;
     30 
     31     public void setListener(ISipSessionListener listener) {
     32         mListener = listener;
     33     }
     34 
     35     public ISipSessionListener getListener() {
     36         return mListener;
     37     }
     38 
     39     private void proxy(Runnable runnable) {
     40         // One thread for each calling back.
     41         // Note: Guarantee ordering if the issue becomes important. Currently,
     42         // the chance of handling two callback events at a time is none.
     43         new Thread(runnable, "SipSessionCallbackThread").start();
     44     }
     45 
     46     public void onCalling(final ISipSession session) {
     47         if (mListener == null) return;
     48         proxy(new Runnable() {
     49             public void run() {
     50                 try {
     51                     mListener.onCalling(session);
     52                 } catch (Throwable t) {
     53                     handle(t, "onCalling()");
     54                 }
     55             }
     56         });
     57     }
     58 
     59     public void onRinging(final ISipSession session, final SipProfile caller,
     60             final String sessionDescription) {
     61         if (mListener == null) return;
     62         proxy(new Runnable() {
     63             public void run() {
     64                 try {
     65                     mListener.onRinging(session, caller, sessionDescription);
     66                 } catch (Throwable t) {
     67                     handle(t, "onRinging()");
     68                 }
     69             }
     70         });
     71     }
     72 
     73     public void onRingingBack(final ISipSession session) {
     74         if (mListener == null) return;
     75         proxy(new Runnable() {
     76             public void run() {
     77                 try {
     78                     mListener.onRingingBack(session);
     79                 } catch (Throwable t) {
     80                     handle(t, "onRingingBack()");
     81                 }
     82             }
     83         });
     84     }
     85 
     86     public void onCallEstablished(final ISipSession session,
     87             final String sessionDescription) {
     88         if (mListener == null) return;
     89         proxy(new Runnable() {
     90             public void run() {
     91                 try {
     92                     mListener.onCallEstablished(session, sessionDescription);
     93                 } catch (Throwable t) {
     94                     handle(t, "onCallEstablished()");
     95                 }
     96             }
     97         });
     98     }
     99 
    100     public void onCallEnded(final ISipSession session) {
    101         if (mListener == null) return;
    102         proxy(new Runnable() {
    103             public void run() {
    104                 try {
    105                     mListener.onCallEnded(session);
    106                 } catch (Throwable t) {
    107                     handle(t, "onCallEnded()");
    108                 }
    109             }
    110         });
    111     }
    112 
    113     public void onCallBusy(final ISipSession session) {
    114         if (mListener == null) return;
    115         proxy(new Runnable() {
    116             public void run() {
    117                 try {
    118                     mListener.onCallBusy(session);
    119                 } catch (Throwable t) {
    120                     handle(t, "onCallBusy()");
    121                 }
    122             }
    123         });
    124     }
    125 
    126     public void onCallChangeFailed(final ISipSession session,
    127             final int errorCode, final String message) {
    128         if (mListener == null) return;
    129         proxy(new Runnable() {
    130             public void run() {
    131                 try {
    132                     mListener.onCallChangeFailed(session, errorCode, message);
    133                 } catch (Throwable t) {
    134                     handle(t, "onCallChangeFailed()");
    135                 }
    136             }
    137         });
    138     }
    139 
    140     public void onError(final ISipSession session, final int errorCode,
    141             final String message) {
    142         if (mListener == null) return;
    143         proxy(new Runnable() {
    144             public void run() {
    145                 try {
    146                     mListener.onError(session, errorCode, message);
    147                 } catch (Throwable t) {
    148                     handle(t, "onError()");
    149                 }
    150             }
    151         });
    152     }
    153 
    154     public void onRegistering(final ISipSession session) {
    155         if (mListener == null) return;
    156         proxy(new Runnable() {
    157             public void run() {
    158                 try {
    159                     mListener.onRegistering(session);
    160                 } catch (Throwable t) {
    161                     handle(t, "onRegistering()");
    162                 }
    163             }
    164         });
    165     }
    166 
    167     public void onRegistrationDone(final ISipSession session,
    168             final int duration) {
    169         if (mListener == null) return;
    170         proxy(new Runnable() {
    171             public void run() {
    172                 try {
    173                     mListener.onRegistrationDone(session, duration);
    174                 } catch (Throwable t) {
    175                     handle(t, "onRegistrationDone()");
    176                 }
    177             }
    178         });
    179     }
    180 
    181     public void onRegistrationFailed(final ISipSession session,
    182             final int errorCode, final String message) {
    183         if (mListener == null) return;
    184         proxy(new Runnable() {
    185             public void run() {
    186                 try {
    187                     mListener.onRegistrationFailed(session, errorCode, message);
    188                 } catch (Throwable t) {
    189                     handle(t, "onRegistrationFailed()");
    190                 }
    191             }
    192         });
    193     }
    194 
    195     public void onRegistrationTimeout(final ISipSession session) {
    196         if (mListener == null) return;
    197         proxy(new Runnable() {
    198             public void run() {
    199                 try {
    200                     mListener.onRegistrationTimeout(session);
    201                 } catch (Throwable t) {
    202                     handle(t, "onRegistrationTimeout()");
    203                 }
    204             }
    205         });
    206     }
    207 
    208     private void handle(Throwable t, String message) {
    209         if (t instanceof DeadObjectException) {
    210             mListener = null;
    211             // This creates race but it's harmless. Just don't log the error
    212             // when it happens.
    213         } else if (mListener != null) {
    214             Log.w(TAG, message, t);
    215         }
    216     }
    217 }
    218