From cc0785a7e7ea999dfca727b1f9a0124e177d0ea5 Mon Sep 17 00:00:00 2001
From: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
Date: Tue, 6 Nov 2012 19:07:48 -0500
Subject: [PATCH] #17220: fix app crash when device rotates

Conflicts:

	src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
---
 .../sflphone/client/CallElementList.java      |  1 +
 .../sflphone/client/ContactListFragment.java  | 15 ++---
 .../sflphone/client/SFLPhoneHome.java         | 60 +++++++++----------
 .../sflphone/client/SFLphoneApplication.java  | 43 ++++++++++++-
 .../sflphone/utils/AccountList.java           |  3 +-
 .../utils/AccountSelectionButton.java         |  1 -
 6 files changed, 79 insertions(+), 44 deletions(-)

diff --git a/src/com/savoirfairelinux/sflphone/client/CallElementList.java b/src/com/savoirfairelinux/sflphone/client/CallElementList.java
index 336bd3335..961a0270f 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallElementList.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallElementList.java
@@ -97,6 +97,7 @@ public class CallElementList extends ListFragment implements LoaderManager.Loade
         super.onAttach(activity);
         sflphoneHome = (SFLPhoneHome) activity;
         service = ((SFLphoneApplication) sflphoneHome.getApplication()).getSipService();
+        mAccountList = ((SFLphoneApplication) sflphoneHome.getApplication()).getAccountList();
         Log.i(TAG, "onAttach() service " + service);
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/ContactListFragment.java b/src/com/savoirfairelinux/sflphone/client/ContactListFragment.java
index a1df22c17..5e590d312 100644
--- a/src/com/savoirfairelinux/sflphone/client/ContactListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/client/ContactListFragment.java
@@ -86,7 +86,7 @@ public class ContactListFragment extends ListFragment implements OnQueryTextList
 {
     final String TAG = "ContactListFragment";
     ContactElementAdapter mAdapter;
-    Context mContext;
+    Activity mContext;
     String mCurFilter;
     private SFLPhoneHome sflphoneHome;
     private ISipService service;
@@ -104,7 +104,9 @@ public class ContactListFragment extends ListFragment implements OnQueryTextList
         super.onAttach(activity);
         sflphoneHome = (SFLPhoneHome) activity;
         service = ((SFLphoneApplication) sflphoneHome.getApplication()).getSipService();
-        Log.i(TAG, "onAttach() service " + service);
+        mAccountList = ((SFLphoneApplication)sflphoneHome.getApplication()).getAccountList();
+
+        Log.i(TAG, "onAttach() service=" + service + ", mAccountList=" + mAccountList);
     }
 
     public static class InfosLoader implements Runnable
@@ -200,10 +202,6 @@ public class ContactListFragment extends ListFragment implements OnQueryTextList
         super();
     }
 
-    public void setAccountList(AccountList accountList) {
-        mAccountList = accountList;
-    }
-
     @Override
     public void onActivityCreated(Bundle savedInstanceState)
     {
@@ -213,12 +211,11 @@ public class ContactListFragment extends ListFragment implements OnQueryTextList
         // In order to onCreateOptionsMenu be called 
         setHasOptionsMenu(true);
 
-        mAdapter = new ContactElementAdapter(getActivity(), null);
+        mAdapter = new ContactElementAdapter(mContext, null);
         setListAdapter(mAdapter);
 
         getLoaderManager().initLoader(0, null, this);
 
-        final Context context = getActivity();
         ListView lv = getListView();
         lv.setOnItemLongClickListener(new OnItemLongClickListener() {
             @Override
@@ -231,7 +228,7 @@ public class ContactListFragment extends ListFragment implements OnQueryTextList
                 // TODO getCallInstnace should be implemented in SipCallList
                 // final SipCall call = SipCall.getCallInstance(info);
                 final SipCall call = new SipCall(info);
-                AlertDialog.Builder builder = new AlertDialog.Builder(context);
+                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                 builder.setTitle("Action to perform with " + call.mCallInfo.mDisplayName)
                       .setCancelable(true)
                       .setItems(items, new DialogInterface.OnClickListener() {
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
index c879bc40b..99b9e1106 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
@@ -87,7 +87,7 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
     CallElementList mCallElementList;
     private boolean mBound = false;
     private ISipService service;
-    public AccountList mAccountList = new AccountList();
+    public AccountList mAccountList;
     public CallList mCallList = new CallList(this);
     private SFLphoneApplication mApplication;
 
@@ -111,11 +111,6 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
 
         mApplication = (SFLphoneApplication) getApplication();
 
-        if (!mApplication.isServiceRunning()) {
-            Log.i(TAG, "starting SipService");
-            startSipService();
-        }
-
         // Bind to LocalService
         if (!mBound) {
             Log.i(TAG, "onStart: Binding service...");
@@ -176,6 +171,8 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
         LocalBroadcastManager.getInstance(this).registerReceiver(mCallList, new IntentFilter("call-state-changed"));
         LocalBroadcastManager.getInstance(this).registerReceiver(mCallList, new IntentFilter("incoming-call"));
 
+        mAccountList = mApplication.getAccountList();
+
         LocalBroadcastManager.getInstance(this).registerReceiver(mAccountList, new IntentFilter("accounts-changed"));
         LocalBroadcastManager.getInstance(this).registerReceiver(mAccountList, new IntentFilter("account-state-changed"));
 
@@ -222,9 +219,9 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
             unbindService(mConnection);
             mBound = false;
         }
-        Log.i(TAG, "onDestroy: stopping SipService...");
-        stopService(new Intent(this, SipService.class));
-        mApplication.setServiceRunning(false);
+//        Log.i(TAG, "onDestroy: stopping SipService...");
+//        stopService(new Intent(this, SipService.class));
+//        mApplication.setServiceRunning(false);
 
         /* unregister broadcast receiver */
         LocalBroadcastManager.getInstance(this).unregisterReceiver(mCallList);
@@ -232,7 +229,7 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
 
         super.onDestroy();
     }
-
+    
     /** Defines callbacks for service binding, passed to bindService() */
     private ServiceConnection mConnection = new ServiceConnection() {
 
@@ -243,36 +240,36 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
             mApplication.setSipService(service);
             mBound = true;
             mAccountList.setSipService(service);
-            Log.d(TAG, "Service connected");
+            Log.d(TAG, "Service connected service=" + service);
         }
 
         @Override
         public void onServiceDisconnected(ComponentName arg0) {
             mApplication.setSipService(null);
             mBound = false;
-            Log.d(TAG, "Service disconnected");
+            Log.w(TAG, "Service disconnected service=" + service);
         }
     };
 
-    private void startSipService() {
-        Thread thread = new Thread("StartSFLphoneService") {
-            public void run() {
-                Intent sipServiceIntent = new Intent(SFLPhoneHome.this, SipService.class);
-                //sipServiceIntent.putExtra(ServiceConstants.EXTRA_OUTGOING_ACTIVITY, new ComponentName(SFLPhoneHome.this, SFLPhoneHome.class));
-                startService(sipServiceIntent);
-                mApplication.setServiceRunning(true);
-            };
-        };
-        try {
-            thread.start();
-        } catch (IllegalThreadStateException e) {
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setMessage("Cannot start SFLPhone SipService!");
-            AlertDialog alert = builder.create();
-            alert.show();
-            finish();
-        }
-    }
+//    private void startSipService() {
+//        Thread thread = new Thread("StartSFLphoneService") {
+//            public void run() {
+//                Intent sipServiceIntent = new Intent(SFLPhoneHome.this, SipService.class);
+//                //sipServiceIntent.putExtra(ServiceConstants.EXTRA_OUTGOING_ACTIVITY, new ComponentName(SFLPhoneHome.this, SFLPhoneHome.class));
+//                startService(sipServiceIntent);
+//                mApplication.setServiceRunning(true);
+//            };
+//        };
+//        try {
+//            thread.start();
+//        } catch (IllegalThreadStateException e) {
+//            AlertDialog.Builder builder = new AlertDialog.Builder(this);
+//            builder.setMessage("Cannot start SFLPhone SipService!");
+//            AlertDialog alert = builder.create();
+//            alert.show();
+//            finish();
+//        }
+//    }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
@@ -364,7 +361,6 @@ public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnC
             switch (i) {
             case 0:
                 mContactListFragment = new ContactListFragment();
-                mContactListFragment.setAccountList(mAccountList);
                 fragment = mContactListFragment;
                 break;
             case 1:
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLphoneApplication.java b/src/com/savoirfairelinux/sflphone/client/SFLphoneApplication.java
index 17dcd6c20..13739475a 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLphoneApplication.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLphoneApplication.java
@@ -1,29 +1,66 @@
 package com.savoirfairelinux.sflphone.client;
 
+import android.app.AlertDialog;
 import android.app.Application;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.util.Log;
 
 import com.savoirfairelinux.sflphone.service.ISipService;
+import com.savoirfairelinux.sflphone.service.SipService;
+import com.savoirfairelinux.sflphone.utils.AccountList;
 
 public class SFLphoneApplication extends Application {
 
     static final String TAG = "SFLphoneApplication";
-    private boolean serviceRunning;
+    private boolean serviceRunning = false;
     private ISipService sipService;
+    private AccountList accountList = new AccountList();
+
+    private void startSipService() {
+        Thread thread = new Thread("StartSFLphoneService") {
+            public void run() {
+                Log.i(TAG, "SipService launching thread");
+                Intent sipServiceIntent = new Intent(SFLphoneApplication.this, SipService.class);
+                //sipServiceIntent.putExtra(ServiceConstants.EXTRA_OUTGOING_ACTIVITY, new ComponentName(SFLPhoneHome.this, SFLPhoneHome.class));
+                startService(sipServiceIntent);
+                serviceRunning = true;
+            };
+        };
+        try {
+            thread.start();
+        } catch (IllegalThreadStateException e) {
+            AlertDialog.Builder builder = new AlertDialog.Builder(this);
+            builder.setMessage("Cannot start SFLPhone SipService!");
+            AlertDialog alert = builder.create();
+            alert.show();
+            //TODO exit application
+        }
+    }
 
     @Override
     public void onCreate() {
         super.onCreate();
         Log.i(TAG, "onCreate");
+
+        if (!serviceRunning) {
+            Log.i(TAG, "starting SipService");
+            startSipService();
+        }
     }
 
     @Override
     public void onTerminate() {
         super.onTerminate();
         Log.i(TAG, "onTerminate");
+
+        if (serviceRunning) {
+            Log.i(TAG, "onDestroy: stopping SipService...");
+            stopService(new Intent(this, SipService.class));
+            serviceRunning = false;
+        }
     }
 
     public boolean isServiceRunning() {
@@ -42,6 +79,10 @@ public class SFLphoneApplication extends Application {
         sipService = service;
     }
 
+    public AccountList getAccountList() {
+        return accountList;
+    }
+
     public String getAppPath() {
         PackageManager pkgMng = getPackageManager();
         String pkgName = getPackageName();
diff --git a/src/com/savoirfairelinux/sflphone/utils/AccountList.java b/src/com/savoirfairelinux/sflphone/utils/AccountList.java
index 441f149a2..3a8c791be 100644
--- a/src/com/savoirfairelinux/sflphone/utils/AccountList.java
+++ b/src/com/savoirfairelinux/sflphone/utils/AccountList.java
@@ -44,11 +44,12 @@ import com.savoirfairelinux.sflphone.service.ISipService;
 
 public class AccountList extends BroadcastReceiver 
 {
+    private static final long serialVersionUID = -9178386308804218835L;
     static final String TAG = "AccountList";
     private String currentAccountID = "";
     private ArrayList<String> mList = new ArrayList<String>();
     private ArrayList<AccountManagementUI> mUserInterfaceList = new ArrayList<AccountManagementUI>();
-    private ISipService mService;
+    private static ISipService mService = null;
     // private HashMap<String, AccountPreferenceScreen> mAccountList = new HashMap<String, AccountPreferenceScreen>();
 
     public static final String DEFAULT_ACCOUNT_ID = "IP2IP";
diff --git a/src/com/savoirfairelinux/sflphone/utils/AccountSelectionButton.java b/src/com/savoirfairelinux/sflphone/utils/AccountSelectionButton.java
index 2ba03dea0..ad18e8bf6 100644
--- a/src/com/savoirfairelinux/sflphone/utils/AccountSelectionButton.java
+++ b/src/com/savoirfairelinux/sflphone/utils/AccountSelectionButton.java
@@ -45,7 +45,6 @@ import java.util.ArrayList;
 public class AccountSelectionButton extends Button implements AccountManagementUI
 {
     private static final String TAG = "AccountSelectionButton";
-    private ISipService mService;
     private Context mContext;
     private ArrayList<String> mList = new ArrayList<String>();
     private AccountList mAccountList = null;
-- 
GitLab