/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.sip;

import android.net.sip.ISipSession;
import android.net.sip.ISipSessionListener;
import android.net.sip.SipProfile;
import android.os.DeadObjectException;
import android.util.Log;

/** Class to help safely run a callback in a different thread. */
class SipSessionListenerProxy extends ISipSessionListener.Stub {
    private static final String TAG = "SipSession";

    private ISipSessionListener mListener;

    public void setListener(ISipSessionListener listener) {
        mListener = listener;
    }

    public ISipSessionListener getListener() {
        return mListener;
    }

    private void proxy(Runnable runnable) {
        // One thread for each calling back.
        // Note: Guarantee ordering if the issue becomes important. Currently,
        // the chance of handling two callback events at a time is none.
        new Thread(runnable).start();
    }

    public void onCalling(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onCalling(session);
                } catch (Throwable t) {
                    handle(t, "onCalling()");
                }
            }
        });
    }

    public void onRinging(final ISipSession session, final SipProfile caller,
            final String sessionDescription) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRinging(session, caller, sessionDescription);
                } catch (Throwable t) {
                    handle(t, "onRinging()");
                }
            }
        });
    }

    public void onRingingBack(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRingingBack(session);
                } catch (Throwable t) {
                    handle(t, "onRingingBack()");
                }
            }
        });
    }

    public void onCallEstablished(final ISipSession session,
            final String sessionDescription) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onCallEstablished(session, sessionDescription);
                } catch (Throwable t) {
                    handle(t, "onCallEstablished()");
                }
            }
        });
    }

    public void onCallEnded(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onCallEnded(session);
                } catch (Throwable t) {
                    handle(t, "onCallEnded()");
                }
            }
        });
    }

    public void onCallBusy(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onCallBusy(session);
                } catch (Throwable t) {
                    handle(t, "onCallBusy()");
                }
            }
        });
    }

    public void onCallChangeFailed(final ISipSession session,
            final String className, final String message) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onCallChangeFailed(session, className, message);
                } catch (Throwable t) {
                    handle(t, "onCallChangeFailed()");
                }
            }
        });
    }

    public void onError(final ISipSession session, final String className,
            final String message) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onError(session, className, message);
                } catch (Throwable t) {
                    handle(t, "onError()");
                }
            }
        });
    }

    public void onRegistering(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRegistering(session);
                } catch (Throwable t) {
                    handle(t, "onRegistering()");
                }
            }
        });
    }

    public void onRegistrationDone(final ISipSession session,
            final int duration) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRegistrationDone(session, duration);
                } catch (Throwable t) {
                    handle(t, "onRegistrationDone()");
                }
            }
        });
    }

    public void onRegistrationFailed(final ISipSession session,
            final String className, final String message) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRegistrationFailed(session, className, message);
                } catch (Throwable t) {
                    handle(t, "onRegistrationFailed()");
                }
            }
        });
    }

    public void onRegistrationTimeout(final ISipSession session) {
        if (mListener == null) return;
        proxy(new Runnable() {
            public void run() {
                try {
                    mListener.onRegistrationTimeout(session);
                } catch (Throwable t) {
                    handle(t, "onRegistrationTimeout()");
                }
            }
        });
    }

    private void handle(Throwable t, String message) {
        if (t instanceof DeadObjectException) {
            mListener = null;
            // This creates race but it's harmless. Just don't log the error
            // when it happens.
        } else if (mListener != null) {
            Log.w(TAG, message, t);
        }
    }
}
