From 0a4d74ee3e563d4be4b05e5a383c4aa41015f987 Mon Sep 17 00:00:00 2001
From: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Date: Mon, 8 Aug 2016 12:49:23 -0400
Subject: [PATCH] account: fix crash in details screen

This was due to the account observer not being removed. When reopening
the details, the previous observer was still alive and was trying to
refresh the UI account on a destroyed view instance

Change-Id: I14021b9ae231e32bb019d6c10d4d88f558b150db
Tuleap: #894
---
 .../ring/client/AccountEditionActivity.java   | 85 ++++++++++---------
 1 file changed, 45 insertions(+), 40 deletions(-)

diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
index 5e12fbf37..a412bc200 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
@@ -94,7 +94,31 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
 
         @Override
         public void update(Observable observable, Object data) {
-            processAccount();
+            if (mAccSelected == null || mService == null) {
+                return;
+            }
+
+            final Account acc = mAccSelected;
+            if (getSupportActionBar() != null) {
+                getSupportActionBar().setTitle(acc.getAlias());
+            }
+
+            final IDRingService remote = getRemoteService();
+            if (remote == null) {
+                Log.w(TAG, "Error updating account, remote service is null");
+                return;
+            }
+            mService.getThreadPool().submit(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        remote.setCredentials(acc.getAccountID(), acc.getCredentialsHashMapList());
+                        remote.setAccountDetails(acc.getAccountID(), acc.getDetails());
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                }
+            });
         }
     };
 
@@ -106,12 +130,13 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
             mService = binder.getService();
             mBound = true;
 
-            String account_id = getIntent().getData().getLastPathSegment();
+            String accountId = getIntent().getData().getLastPathSegment();
             Log.i(TAG, "Service connected " + className.getClassName() + " " + getIntent().getData().toString());
 
-            mAccSelected = mService.getAccount(account_id);
-            if (mAccSelected == null)
+            mAccSelected = mService.getAccount(accountId);
+            if (mAccSelected == null) {
                 finish();
+            }
 
             mAccSelected.addObserver(mAccountObserver);
             getSupportActionBar().setTitle(mAccSelected.getAlias());
@@ -134,6 +159,7 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
 
         @Override
         public void onServiceDisconnected(ComponentName arg0) {
+            // Called in case of service crashing or getting killed
             mAccSelected.deleteObserver(mAccountObserver);
             mBound = false;
         }
@@ -167,6 +193,9 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
 
         if (mBound) {
             unbindService(mConnection);
+            if (mAccSelected != null) {
+                mAccSelected.deleteObserver(mAccountObserver);
+            }
             mBound = false;
         }
     }
@@ -184,33 +213,13 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
             case R.id.menuitem_export:
                 startExport();
                 break;
+            default:
+                break;
         }
 
         return true;
     }
 
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-
-    private void processAccount() {
-        final Account acc = mAccSelected;
-        final IDRingService remote = getRemoteService();
-        getSupportActionBar().setTitle(acc.getAlias());
-        mService.getThreadPool().submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    remote.setCredentials(acc.getAccountID(), acc.getCredentialsHashMapList());
-                    remote.setAccountDetails(acc.getAccountID(), acc.getDetails());
-                } catch (RemoteException e) {
-                    e.printStackTrace();
-                }
-            }
-        });
-    }
-
     private AlertDialog createDeleteDialog() {
         Activity ownerActivity = this;
         AlertDialog.Builder builder = new AlertDialog.Builder(ownerActivity);
@@ -268,7 +277,7 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
     }
 
     private void startExport() {
-        boolean hasPermission = (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
+        boolean hasPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
         if (hasPermission) {
             showExportDialog();
         } else {
@@ -297,7 +306,7 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
         LayoutInflater inflater = getLayoutInflater();
         ViewGroup v = (ViewGroup) inflater.inflate(R.layout.dialog_account_export, null);
         final TextView pwd = (TextView) v.findViewById(R.id.newpwd_txt);
-        final TextView pwd_confirm = (TextView) v.findViewById(R.id.newpwd_confirm_txt);
+        final TextView pwdConfirm = (TextView) v.findViewById(R.id.newpwd_confirm_txt);
         builder.setMessage(R.string.account_export_message)
                 .setTitle(R.string.account_export_title)
                 .setPositiveButton(R.string.account_export, null)
@@ -313,10 +322,8 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
         pwd.setOnEditorActionListener(new TextView.OnEditorActionListener() {
             @Override
             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-                Log.w(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
-                if (actionId == EditorInfo.IME_ACTION_NEXT)
-                    return checkPassword(v, null);
-                return false;
+                Log.i(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
+                return actionId == EditorInfo.IME_ACTION_NEXT && checkPassword(v, null);
             }
         });
         pwd.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@@ -329,15 +336,13 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
                 }
             }
         });
-        pwd_confirm.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+        pwdConfirm.setOnEditorActionListener(new TextView.OnEditorActionListener() {
             @Override
             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                 Log.w(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
-                if (actionId == EditorInfo.IME_ACTION_DONE) {
-                    if (!checkPassword(pwd, v)) {
-                        alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
-                        return true;
-                    }
+                if (actionId == EditorInfo.IME_ACTION_DONE && !checkPassword(pwd, v)) {
+                    alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
+                    return true;
                 }
                 return false;
             }
@@ -349,7 +354,7 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
         alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                if (!checkPassword(pwd, pwd_confirm)) {
+                if (!checkPassword(pwd, pwdConfirm)) {
                     final String pwd_txt = pwd.getText().toString();
                     alertDialog.dismiss();
 
@@ -409,7 +414,7 @@ public class AccountEditionActivity extends AppCompatActivity implements LocalSe
         }
 
         protected void onPostExecute(Integer ret) {
-            if (exportDialog != null){
+            if (exportDialog != null) {
                 exportDialog.dismiss();
             }
 
-- 
GitLab