Do not use ISipService binder if it is null

Currently, if the com.android.phone process crashes, the ISipService
binder will become null. Check the Binder before using it to prevent the
SipManager from crashing. If attempts at reconnecting to the Binder
fail, throw a SipException.

Bug: 28100417
Change-Id: I23ab582e88fdb73fee820e3e52a7afbc2395f0d0
diff --git a/src/java/android/net/sip/SipManager.java b/src/java/android/net/sip/SipManager.java
index b483d5d..0cb1feb 100644
--- a/src/java/android/net/sip/SipManager.java
+++ b/src/java/android/net/sip/SipManager.java
@@ -171,8 +171,17 @@
     }
 
     private void createSipService() {
-        IBinder b = ServiceManager.getService(Context.SIP_SERVICE);
-        mSipService = ISipService.Stub.asInterface(b);
+        if (mSipService == null) {
+            IBinder b = ServiceManager.getService(Context.SIP_SERVICE);
+            mSipService = ISipService.Stub.asInterface(b);
+        }
+    }
+
+    private void checkSipServiceConnection() throws SipException {
+        createSipService();
+        if (mSipService == null) {
+            throw new SipException("SipService is dead and is restarting...", new Exception());
+        }
     }
 
     /**
@@ -188,6 +197,7 @@
      */
     public void open(SipProfile localProfile) throws SipException {
         try {
+            checkSipServiceConnection();
             mSipService.open(localProfile, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw new SipException("open()", e);
@@ -231,6 +241,7 @@
                     "incomingCallPendingIntent cannot be null");
         }
         try {
+            checkSipServiceConnection();
             mSipService.open3(localProfile, incomingCallPendingIntent,
                     createRelay(listener, localProfile.getUriString()),
                     mContext.getOpPackageName());
@@ -251,6 +262,7 @@
     public void setRegistrationListener(String localProfileUri,
             SipRegistrationListener listener) throws SipException {
         try {
+            checkSipServiceConnection();
             mSipService.setRegistrationListener(
                     localProfileUri, createRelay(listener, localProfileUri),
                     mContext.getOpPackageName());
@@ -268,6 +280,7 @@
      */
     public void close(String localProfileUri) throws SipException {
         try {
+            checkSipServiceConnection();
             mSipService.close(localProfileUri, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw new SipException("close()", e);
@@ -284,6 +297,7 @@
      */
     public boolean isOpened(String localProfileUri) throws SipException {
         try {
+            checkSipServiceConnection();
             return mSipService.isOpened(localProfileUri, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw new SipException("isOpened()", e);
@@ -305,6 +319,7 @@
      */
     public boolean isRegistered(String localProfileUri) throws SipException {
         try {
+            checkSipServiceConnection();
             return mSipService.isRegistered(localProfileUri, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw new SipException("isRegistered()", e);
@@ -407,6 +422,7 @@
         }
 
         try {
+            checkSipServiceConnection();
             ISipSession session = mSipService.getPendingSession(callId,
                     mContext.getOpPackageName());
             if (session == null) {
@@ -489,6 +505,7 @@
     public void register(SipProfile localProfile, int expiryTime,
             SipRegistrationListener listener) throws SipException {
         try {
+            checkSipServiceConnection();
             ISipSession session = mSipService.createSession(localProfile,
                     createRelay(listener, localProfile.getUriString()),
                     mContext.getOpPackageName());
@@ -515,6 +532,7 @@
     public void unregister(SipProfile localProfile,
             SipRegistrationListener listener) throws SipException {
         try {
+            checkSipServiceConnection();
             ISipSession session = mSipService.createSession(localProfile,
                     createRelay(listener, localProfile.getUriString()),
                     mContext.getOpPackageName());
@@ -541,6 +559,7 @@
     public SipSession getSessionFor(Intent incomingCallIntent)
             throws SipException {
         try {
+            checkSipServiceConnection();
             String callId = getCallId(incomingCallIntent);
             ISipSession s = mSipService.getPendingSession(callId,
                     mContext.getOpPackageName());
@@ -566,6 +585,7 @@
     public SipSession createSipSession(SipProfile localProfile,
             SipSession.Listener listener) throws SipException {
         try {
+            checkSipServiceConnection();
             ISipSession s = mSipService.createSession(localProfile, null,
                     mContext.getOpPackageName());
             if (s == null) {
@@ -583,8 +603,9 @@
      * (username, password and display name) are crossed out.
      * @hide
      */
-    public SipProfile[] getListOfProfiles() {
+    public SipProfile[] getListOfProfiles() throws SipException {
         try {
+            checkSipServiceConnection();
             return mSipService.getListOfProfiles(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return new SipProfile[0];
diff --git a/src/java/com/android/server/sip/SipService.java b/src/java/com/android/server/sip/SipService.java
index 6e1f428..97abfb7 100644
--- a/src/java/com/android/server/sip/SipService.java
+++ b/src/java/com/android/server/sip/SipService.java
@@ -100,9 +100,11 @@
      */
     public static void start(Context context) {
         if (SipManager.isApiSupported(context)) {
-            ServiceManager.addService("sip", new SipService(context));
-            context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
-            if (DBG) slog("start:");
+            if (ServiceManager.getService("sip") == null) {
+                ServiceManager.addService("sip", new SipService(context));
+                context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
+                if (DBG) slog("start:");
+            }
         }
     }