SIP: hide ISipService from apps.

Change-Id: I63676fb5767f9b237ee4cc6d976ab80968975470
diff --git a/src/android/net/sip/SipManager.java b/src/android/net/sip/SipManager.java
index 02611e9..9546b75 100644
--- a/src/android/net/sip/SipManager.java
+++ b/src/android/net/sip/SipManager.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.Looper;
 import android.os.RemoteException;
 
 import javax.sip.SipException;
@@ -38,19 +39,31 @@
     }
 
 
-    /**
-     * ISipService must be obtained from non-main thread.
-     * (tentative; will be relaxed after integrated into framework)
-     */
-    public static ISipService getSipService(Context context) {
-        if (sSipService != null) return sSipService;
+    private static void createSipService(Context context) {
+        if (sSipService != null) return;
         if (sBinderHelper == null) {
             sBinderHelper = new BinderHelper<ISipService>(
                     context, ISipService.class);
             sBinderHelper.startService();
         }
         sSipService = ISipService.Stub.asInterface(sBinderHelper.getBinder());
-        return sSipService;
+    }
+
+    /**
+     * Initializes the background SIP service. Will be removed once the SIP
+     * service is integrated into framework.
+     */
+    public static void initialize(final Context context) {
+        // ISipService must be created from non-main thread.
+        if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
+            new Thread(new Runnable() {
+                public void run() {
+                    createSipService(context);
+                }
+            }).start();
+        } else {
+            createSipService(context);
+        }
     }
 
     public static void openToReceiveCalls(SipProfile localProfile,
@@ -164,4 +177,25 @@
         intent.putExtra(OFFER_SD_KEY, sessionDescription);
         return intent;
     }
+
+    public static void register(SipProfile localProfile, int expiryTime,
+            ISipSessionListener listener) throws SipException {
+        try {
+            ISipSession session = sSipService.createSession(
+                    localProfile, listener);
+            session.register(expiryTime);
+        } catch (RemoteException e) {
+            throw new SipException("register()", e);
+        }
+    }
+    public static void unregister(SipProfile localProfile,
+            ISipSessionListener listener) throws SipException {
+        try {
+            ISipSession session = sSipService.createSession(
+                    localProfile, listener);
+            session.unregister();
+        } catch (RemoteException e) {
+            throw new SipException("unregister()", e);
+        }
+    }
 }
diff --git a/src/com/android/settings/sip/SipSettings.java b/src/com/android/settings/sip/SipSettings.java
index 181c5c4..067913c 100644
--- a/src/com/android/settings/sip/SipSettings.java
+++ b/src/com/android/settings/sip/SipSettings.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.sip.ISipService;
 import android.net.sip.ISipSession;
 import android.net.sip.ISipSessionListener;
 import android.net.sip.SipProfile;
@@ -78,7 +77,6 @@
     private String mProfilesDirectory;
 
     private SipProfile mProfile;
-    private ISipService mSipService;
 
     private PreferenceCategory mSipListContainer;
     private Map<String, SipPreference> mSipPreferenceMap;
@@ -118,13 +116,7 @@
         registerForContextMenu(getListView());
         retrieveSipListFromStorage();
 
-        new Thread(new Runnable() {
-            public void run() {
-                // SipService must be obtained from non-main thread
-                mSipService = SipManager.getSipService(SipSettings.this);
-                Log.v(TAG, "got SipService: " + mSipService);
-            }
-        }).start();
+        SipManager.initialize(this);
     }
 
     private void retrieveSipListFromStorage() {
@@ -227,21 +219,16 @@
         case CONTEXT_MENU_REGISTER_ID:
             if (p != null) {
                 try {
-                    openToReceiveCalls(p);
-                    ISipSession session = mSipService.createSession(p,
-                            createSessionAdapter());
-                    session.register(EXPIRY_TIME);
+                    SipManager.openToReceiveCalls(p, INCOMING_CALL_ACTION);
                 } catch (Exception e) {
-                    Log.e(TAG, "register failed:" + e.toString());
+                    Log.e(TAG, "register failed", e);
                 }
             }
             return true;
         case CONTEXT_MENU_UNREGISTER_ID:
             if (p != null) {
                 try {
-                    ISipSession session = mSipService.createSession(p,
-                            createSessionAdapter());
-                    session.unregister();
+                    SipManager.close(p);
                 } catch (Exception e) {
                     Log.e(TAG, "unregister failed:" + e);
                 }
@@ -364,12 +351,4 @@
             }
         };
     }
-
-    private synchronized void openToReceiveCalls(SipProfile p) {
-        try {
-            mSipService.openToReceiveCalls(p, INCOMING_CALL_ACTION);
-        } catch (Exception e) {
-            Log.e(TAG, "Can not openToReceiveCalls:" + e);
-        }
-    }
 }
diff --git a/src/com/android/sip/demo/SipMain.java b/src/com/android/sip/demo/SipMain.java
index c5f893a..6bf2d6d 100644
--- a/src/com/android/sip/demo/SipMain.java
+++ b/src/com/android/sip/demo/SipMain.java
@@ -23,7 +23,6 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.net.sip.ISipService;
 import android.net.sip.ISipSession;
 import android.net.sip.ISipSessionListener;
 import android.net.sip.SipProfile;
@@ -81,8 +80,6 @@
     private boolean mChanged;
     private boolean mSpeakerMode;
 
-    private ISipService mSipService;
-
     private BroadcastReceiver mIncomingCallReceiver =
             new IncomingCallReceiver();
 
@@ -123,7 +120,6 @@
                 });
         setCallStatus();
 
-        final Intent intent = getIntent();
         new Thread(new Runnable() {
             public void run() {
                 final String localIp = getLocalIp();
@@ -133,10 +129,7 @@
                     }
                 });
 
-                // SipService must be obtained from non-main thread
-                mSipService = SipManager.getSipService(SipMain.this);
-                Log.v(TAG, "got SipService: " + mSipService);
-
+                SipManager.initialize(SipMain.this);
                 openToReceiveCalls();
                 receiveCall();
             }
@@ -162,7 +155,7 @@
         // TODO: resolve offerSd to differnt apps
         Intent intent = getIntent();
         Log.v(TAG, "receiveCall(): any call comes in? " + intent);
-        if ((mSipService != null) && SipManager.isIncomingCallIntent(intent)) {
+        if (SipManager.isIncomingCallIntent(intent)) {
             createSipAudioCall(intent);
             setIntent(null);
         }
@@ -170,7 +163,7 @@
 
     private synchronized void openToReceiveCalls() {
         try {
-            mSipService.openToReceiveCalls(createLocalProfile(),
+            SipManager.openToReceiveCalls(createLocalProfile(),
                     INCOMING_CALL_ACTION);
         } catch (Exception e) {
             setCallStatus(e);
@@ -284,28 +277,36 @@
     private SipAudioCall.Listener createListener() {
         return new SipAudioCall.Adapter() {
             public void onChanged(SipAudioCall call) {
+                Log.v(TAG, "onChanged(): " + call + " <--> " + mAudioCall);
+                if (mAudioCall != call) return;
                 setCallStatus();
             }
 
             public void onCalling(SipAudioCall call) {
+                if (mAudioCall != call) return;
                 mSipSession = call.getSipSession();
                 setCallStatus();
             }
 
             public void onRinging(SipAudioCall call, SipProfile caller) {
+                Log.v(TAG, "onRinging(): " + call + " <--> " + mAudioCall);
+                if (mAudioCall != null) return;
                 mSipSession = call.getSipSession();
                 showCallNotificationDialog(caller);
                 setCallStatus();
             }
 
             public void onCallEstablished(SipAudioCall call) {
+                Log.v(TAG, "onCallEstablished(): " + call + " <--> " + mAudioCall);
+                if (mAudioCall != call) return;
                 setAllPreferencesEnabled(false);
                 setCallStatus();
             }
 
             public void onCallEnded(SipAudioCall call) {
+                Log.v(TAG, "onCallEnded(): " + call + " <--> " + mAudioCall);
+                if (mAudioCall != call) return;
                 if (mDialog != null) {
-
                     runOnUiThread(new Runnable() {
                         public void run() {
                             dismissDialog(mDialog.getId());
@@ -314,13 +315,17 @@
                 }
                 setCallStatus();
                 mSipSession = null;
+                mAudioCall = null;
                 setAllPreferencesEnabled(true);
             }
 
             public void onError(SipAudioCall call, String errorMessage) {
+                Log.v(TAG, "onError(): " + call + " <--> " + mAudioCall);
+                if (mAudioCall != call) return;
                 mError = new SipException(errorMessage);
                 setCallStatus();
                 mSipSession = null;
+                mAudioCall = null;
                 setAllPreferencesEnabled(true);
             }
         };
@@ -356,14 +361,10 @@
         try {
             if (mLocalProfile == null) createLocalProfile();
             if (mChanged) {
-                ISipSession session = mSipService.createSession(mLocalProfile,
-                    new SipSessionAdapter());
-                session.unregister();
+                SipManager.unregister(mLocalProfile, null);
             }
-            ISipSession session = mSipService.createSession(
-                    createLocalProfile(), createRegistrationListener());
-            session.register(EXPIRY_TIME);
-            mSipSession = session;
+            SipManager.register(createLocalProfile(), EXPIRY_TIME,
+                    createRegistrationListener());
             mChanged = false;
             setCallStatus();
         } catch (Exception e) {