wizard: create a wizard for sip account

Until now, we can create a sip or ring account everything from the same
wizard account. This commit creates a wizard to create a sip account.

Change-Id: I3405bb0fb287ebd971efa3967f7325eebc082fc9
Tuleap: #1286
Tuleap: #1280
diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
index 807b54d..4da7cef 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
@@ -26,7 +26,6 @@
 import android.app.AlertDialog;
 import android.app.Fragment;
 import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.app.ProgressDialog;
 import android.content.ComponentName;
 import android.content.Context;
@@ -56,6 +55,7 @@
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import cx.ring.R;
+import cx.ring.fragments.AccountCreationFragment;
 import cx.ring.fragments.HomeAccountCreationFragment;
 import cx.ring.fragments.ProfileCreationFragment;
 import cx.ring.fragments.RingAccountCreationFragment;
@@ -83,11 +83,14 @@
 
     private boolean mLinkAccount = false;
     private boolean mIsNew = false;
+    private boolean createdAccount = false;
     private Bitmap mPhotoProfile;
     private String mFullname;
     private String mUsername;
     private String mPassword;
     private String mPin;
+    private String mAccountType;
+    private Account mAccount;
 
     @BindView(R.id.pager)
     WizardViewPager mViewPager;
@@ -124,6 +127,8 @@
         mIsNew = !(mBound && !mService.getAccounts().isEmpty());
         Log.d(TAG, "is first account " + mIsNew);
         mViewPager.setAdapter(new WizardPagerAdapter(getFragmentManager()));
+
+        mAccountType = getIntent().getAction() != null ? getIntent().getAction() : AccountConfig.ACCOUNT_TYPE_RING;
     }
 
     @Override
@@ -173,6 +178,14 @@
 
     @Override
     public void onBackPressed() {
+        if (!createdAccount && mAccount != null) {
+            try {
+                mService.getRemoteService().removeAccount(mAccount.getAccountID());
+            } catch (Exception e) {
+                Log.e(TAG, "Error while deleting account", e);
+            }
+        }
+
         FragmentManager fragmentManager = getFragmentManager();
         if (fragmentManager.getBackStackEntryCount() >= 1) {
             fragmentManager.popBackStack();
@@ -187,83 +200,92 @@
     }
 
     @SuppressWarnings("unchecked")
-    public void initAccountCreation(boolean isRingAccount, String newUsername, String pin, String password, String host) {
-        final String accountType = isRingAccount ? AccountConfig.ACCOUNT_TYPE_RING : AccountConfig.ACCOUNT_TYPE_SIP;
-
+    private HashMap<String, String> initAccountDetails() {
         try {
-            HashMap<String, String> accountDetails = (HashMap<String, String>) mService.getRemoteService().getAccountTemplate(accountType);
+            HashMap<String, String> accountDetails = (HashMap<String, String>) mService.getRemoteService().getAccountTemplate(mAccountType);
             for (Map.Entry<String, String> e : accountDetails.entrySet()) {
                 Log.d(TAG, "Default account detail: " + e.getKey() + " -> " + e.getValue());
             }
-            //~ Checking the state of the Camera permission to enable Video or not.
+
             boolean hasCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
             accountDetails.put(ConfigKey.VIDEO_ENABLED.key(), Boolean.toString(hasCameraPermission));
 
             //~ Sipinfo is forced for any sipaccount since overrtp is not supported yet.
             //~ This will have to be removed when it will be supported.
             accountDetails.put(ConfigKey.ACCOUNT_DTMF_TYPE.key(), getString(R.string.account_sip_dtmf_type_sipinfo));
-
-            if (isRingAccount) {
-                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), "Ring");
-                accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), "bootstrap.ring.cx");
-                if (newUsername != null && !newUsername.isEmpty()) {
-                    accountDetails.put(ConfigKey.ACCOUNT_REGISTERED_NAME.key(), newUsername);
-                }
-                if (password != null && !password.isEmpty()) {
-                    accountDetails.put(ConfigKey.ARCHIVE_PASSWORD.key(), password);
-                }
-                if (pin != null && !pin.isEmpty()) {
-                    accountDetails.put(ConfigKey.ARCHIVE_PIN.key(), pin);
-                }
-                // Enable UPNP by default for Ring accounts
-                accountDetails.put(ConfigKey.ACCOUNT_UPNP_ENABLE.key(), AccountConfig.TRUE_STR);
-                createNewAccount(accountDetails, newUsername);
-            } else {
-                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), newUsername);
-                if (!TextUtils.isEmpty(host)) {
-                    accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), host);
-                    accountDetails.put(ConfigKey.ACCOUNT_USERNAME.key(), newUsername);
-                    accountDetails.put(ConfigKey.ACCOUNT_PASSWORD.key(), password);
-                }
-                createNewAccount(accountDetails, null);
-            }
-
-        } catch (RemoteException e) {
+            return accountDetails;
+        } catch (Exception e) {
             Toast.makeText(this, "Error creating account", Toast.LENGTH_SHORT).show();
             Log.e(TAG, "Error creating account", e);
+            return null;
         }
+    }
 
+    private HashMap<String, String> initRingAccountDetails() {
+        HashMap<String, String> accountDetails = initAccountDetails();
+        if (accountDetails != null) {
+            accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), "Ring");
+            accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), "bootstrap.ring.cx");
+            accountDetails.put(ConfigKey.ACCOUNT_UPNP_ENABLE.key(), AccountConfig.TRUE_STR);
+        }
+        return accountDetails;
+    }
+
+    public void initRingAccountCreation(String username, String password) {
+        HashMap<String, String> accountDetails = initRingAccountDetails();
+        if (accountDetails != null) {
+            if (!TextUtils.isEmpty(username)) {
+                accountDetails.put(ConfigKey.ACCOUNT_REGISTERED_NAME.key(), username);
+            }
+            if (!TextUtils.isEmpty(password)) {
+                accountDetails.put(ConfigKey.ARCHIVE_PASSWORD.key(), password);
+            }
+            createNewAccount(accountDetails, username);
+        }
+    }
+
+    public void initRingAccountLink(String pin, String password) {
+        HashMap<String, String> accountDetails = initRingAccountDetails();
+        if (accountDetails != null) {
+            if (!TextUtils.isEmpty(password)) {
+                accountDetails.put(ConfigKey.ARCHIVE_PASSWORD.key(), password);
+            }
+            if (!TextUtils.isEmpty(pin)) {
+                accountDetails.put(ConfigKey.ARCHIVE_PIN.key(), pin);
+            }
+            createNewAccount(accountDetails, null);
+        }
+    }
+
+    public void initSipAccountCreation(String alias, String username, String password, String host) {
+        HashMap<String, String> accountDetails = initAccountDetails();
+
+        if (accountDetails != null) {
+            mFullname = alias;
+            accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), alias);
+            if (!TextUtils.isEmpty(host)) {
+                accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), host);
+                accountDetails.put(ConfigKey.ACCOUNT_USERNAME.key(), username);
+                accountDetails.put(ConfigKey.ACCOUNT_PASSWORD.key(), password);
+            }
+            createNewAccount(accountDetails, null);
+        }
     }
 
     public void saveProfile(String accountID) {
         VCard vcard = new VCard();
         vcard.setFormattedName(new FormattedName(mFullname));
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        mPhotoProfile.compress(Bitmap.CompressFormat.PNG, 100, stream);
-        Photo photoVCard = new Photo(stream.toByteArray(), ImageType.PNG);
-        vcard.removeProperties(Photo.class);
-        vcard.addPhoto(photoVCard);
+        if (mPhotoProfile != null) {
+            mPhotoProfile.compress(Bitmap.CompressFormat.PNG, 100, stream);
+            Photo photoVCard = new Photo(stream.toByteArray(), ImageType.PNG);
+            vcard.removeProperties(Photo.class);
+            vcard.addPhoto(photoVCard);
+        }
         vcard.removeProperties(RawProperty.class);
         VCardUtils.saveLocalProfileToDisk(vcard, accountID, getFilesDir());
     }
 
-    public void ringCreate(boolean switchFragment) {
-        FragmentManager fragmentManager = getFragmentManager();
-        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-        if (!switchFragment) {
-            fragmentTransaction.addToBackStack(null);
-        }
-        mProfileFragment = new ProfileCreationFragment();
-    }
-
-    public void ringLogin(boolean switchFragment) {
-        FragmentManager fragmentManager = getFragmentManager();
-        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-        if (!switchFragment) {
-            fragmentTransaction.addToBackStack(null);
-        }
-    }
-
     public void newAccount(boolean linkAccount) {
         Log.d(TAG, "new account. linkAccount is " + linkAccount);
         mLinkAccount = linkAccount;
@@ -306,9 +328,9 @@
 
     public void createAccount() {
         if (mLinkAccount) {
-            initAccountCreation(true, null, mPin, mPassword, null);
+            initRingAccountLink(mPin, mPassword);
         } else {
-            initAccountCreation(true, mUsername, null, mPassword, null);
+            initRingAccountCreation(mUsername, mPassword);
         }
     }
 
@@ -319,19 +341,19 @@
     private class CreateAccountTask extends AsyncTask<HashMap<String, String>, Void, String> {
         private ProgressDialog progress = null;
         private final String username;
-        private final Context ctx;
+        private final Context context;
 
-        CreateAccountTask(String registerUsername, Context c) {
+        CreateAccountTask(String registerUsername, Context context) {
             Log.d(TAG, "CreateAccountTask ");
             username = registerUsername;
-            ctx = c;
+            this.context = context;
         }
 
         @Override
         protected void onPreExecute() {
-            progress = new ProgressDialog(ctx);
+            progress = new ProgressDialog(context);
             progress.setTitle(R.string.dialog_wait_create);
-            progress.setMessage(ctx.getString(R.string.dialog_wait_create_details));
+            progress.setMessage(context.getString(R.string.dialog_wait_create_details));
             progress.setCancelable(false);
             progress.setCanceledOnTouchOutside(false);
             progress.show();
@@ -340,15 +362,43 @@
         @SafeVarargs
         @Override
         protected final String doInBackground(HashMap<String, String>... accs) {
-            final Account account = mService.createAccount(accs[0]);
-            account.stateListener = new Account.OnStateChangedListener() {
+            if (mAccountType.equals(AccountConfig.ACCOUNT_TYPE_RING) || mAccount == null) {
+                mAccount = mService.createAccount(accs[0]);
+            } else {
+                mAccount.setDetail(ConfigKey.ACCOUNT_ALIAS, accs[0].get(ConfigKey.ACCOUNT_ALIAS.key()));
+                if (accs[0].containsKey(ConfigKey.ACCOUNT_HOSTNAME.key())) {
+                    mAccount.setDetail(ConfigKey.ACCOUNT_HOSTNAME, accs[0].get(ConfigKey.ACCOUNT_HOSTNAME.key()));
+                    mAccount.setDetail(ConfigKey.ACCOUNT_USERNAME, accs[0].get(ConfigKey.ACCOUNT_USERNAME.key()));
+                    mAccount.setDetail(ConfigKey.ACCOUNT_PASSWORD, accs[0].get(ConfigKey.ACCOUNT_PASSWORD.key()));
+                }
+                final IDRingService remote = getRemoteService();
+                if (remote == null) {
+                    Log.w(TAG, "Error updating account, remote service is null");
+                } else {
+                    mService.getThreadPool().submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            try {
+                                Log.i(TAG, "updating account");
+                                remote.setAccountDetails(mAccount.getAccountID(), mAccount.getDetails());
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "Exception updating account", e);
+                            }
+                        }
+                    });
+                }
+            }
+            mAccount.stateListener = new Account.OnStateChangedListener() {
                 @Override
                 public void stateChanged(String state, int code) {
                     Log.i(TAG, "stateListener -> stateChanged " + state + " " + code);
+
                     if (state.isEmpty() || state.contentEquals(AccountConfig.STATE_INITIALIZING)) {
                         return;
                     }
-                    account.stateListener = null;
+
+
+                    mAccount.stateListener = null;
                     if (progress != null) {
                         if (progress.isShowing()) {
                             progress.dismiss();
@@ -356,37 +406,20 @@
                         progress = null;
                     }
 
-                    AlertDialog.Builder dialog = new AlertDialog.Builder(ctx);
-                    dialog.setPositiveButton(android.R.string.ok, null);
-                    boolean success = false;
-                    switch (state) {
-                        case AccountConfig.STATE_UNREGISTERED:
-                            if (!mLinkAccount) {
-                                dialog.setTitle(R.string.account_device_added_title)
-                                        .setMessage(R.string.account_device_added_message);
-                                success = true;
-                                break;
+                    AlertDialog alertDialog = createAlertDialog(context, state);
+                    if (createdAccount) {
+                        saveProfile(mAccount.getAccountID());
+                        alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                            @Override
+                            public void onDismiss(DialogInterface dialogInterface) {
+                                setResult(Activity.RESULT_OK, new Intent());
+                                finish();
                             }
-                        case AccountConfig.STATE_ERROR_GENERIC:
-                            dialog.setTitle(R.string.account_cannot_be_found_title)
-                                    .setMessage(R.string.account_cannot_be_found_message);
-                            break;
-                        case AccountConfig.STATE_ERROR_NETWORK:
-                            dialog.setTitle(R.string.account_no_network_title)
-                                    .setMessage(R.string.account_no_network_message);
-                            break;
-                        default:
-                            dialog.setTitle(R.string.account_device_added_title)
-                                    .setMessage(R.string.account_device_added_message);
-                            success = true;
-                            break;
-                    }
-                    AlertDialog alertDialog = dialog.show();
-                    if (success) {
-                        saveProfile(account.getAccountID());
+                        });
+
                         if (!TextUtils.isEmpty(username)) {
                             Log.i(TAG, "Account created, registering " + username);
-                            mService.registerName(account, "", username, new LocalService.NameRegistrationCallback() {
+                            mService.registerName(mAccount, "", username, new LocalService.NameRegistrationCallback() {
                                 @Override
                                 public void onRegistered(String name) {
                                     Log.i(TAG, "Account wizard, onRegistered " + name);
@@ -398,21 +431,81 @@
                                 }
                             });
                         }
-
-                        alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
-                            @Override
-                            public void onDismiss(DialogInterface dialogInterface) {
-                                setResult(Activity.RESULT_OK, new Intent());
-                                finish();
-                            }
-                        });
                     }
                 }
-            }
-
-            ;
+            };
             mCreatingAccount = false;
-            return account.getAccountID();
+            return mAccount.getAccountID();
+        }
+
+        private AlertDialog createAlertDialog(Context context, String state) {
+            if (mAccount.isRing()) {
+                return createRingAlertDialog(context, state);
+            } else {
+                return createSIPAlertDialog(context, state);
+            }
+        }
+
+        private AlertDialog createSIPAlertDialog(Context context, String state) {
+            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
+            dialogBuilder.setPositiveButton(android.R.string.ok, null);
+            switch (state) {
+                case AccountConfig.STATE_ERROR_GENERIC:
+                case AccountConfig.STATE_UNREGISTERED:
+                    dialogBuilder.setTitle(R.string.account_sip_cannot_be_registered)
+                            .setMessage(R.string.account_sip_cannot_be_registered_message);
+                    break;
+                case AccountConfig.STATE_ERROR_NETWORK:
+                    dialogBuilder.setTitle(R.string.account_no_network_title)
+                            .setMessage(R.string.account_no_network_message);
+                    break;
+                default:
+                    dialogBuilder.setTitle(R.string.account_sip_success_title)
+                            .setMessage(R.string.account_sip_success_message);
+                    break;
+            }
+            AlertDialog result = dialogBuilder.show();
+            // SIP account are always created, dismiss wizard no matter the state
+            result.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialogInterface) {
+                    setResult(Activity.RESULT_OK, new Intent());
+                    finish();
+                }
+            });
+            return result;
+        }
+
+        private AlertDialog createRingAlertDialog(Context context, String state) {
+            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
+            dialogBuilder.setPositiveButton(android.R.string.ok, null);
+            switch (state) {
+                case AccountConfig.STATE_ERROR_GENERIC:
+                    dialogBuilder.setTitle(R.string.account_cannot_be_found_title)
+                            .setMessage(R.string.account_cannot_be_found_message);
+                    break;
+                case AccountConfig.STATE_UNREGISTERED:
+                    if (mLinkAccount) {
+                        dialogBuilder.setTitle(R.string.account_cannot_be_found_title)
+                                .setMessage(R.string.account_cannot_be_found_message);
+                    } else {
+                        dialogBuilder.setTitle(R.string.account_device_added_title)
+                                .setMessage(R.string.account_device_added_message);
+                        createdAccount = true;
+                        break;
+                    }
+                    break;
+                case AccountConfig.STATE_ERROR_NETWORK:
+                    dialogBuilder.setTitle(R.string.account_no_network_title)
+                            .setMessage(R.string.account_no_network_message);
+                    break;
+                default:
+                    dialogBuilder.setTitle(R.string.account_device_added_title)
+                            .setMessage(R.string.account_device_added_message);
+                    createdAccount = true;
+                    break;
+            }
+            return dialogBuilder.show();
         }
     }
 
@@ -475,7 +568,11 @@
             Log.d(TAG, "getItem");
             switch (position) {
                 case 0:
-                    return mHomeFragment;
+                    if (AccountConfig.ACCOUNT_TYPE_SIP.equals(mAccountType)) {
+                        return new AccountCreationFragment();
+                    } else {
+                        return mHomeFragment;
+                    }
                 case 1:
                     return mProfileFragment;
                 case 2:
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index e1db9ec..5131f62 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -68,6 +68,7 @@
 import cx.ring.fragments.AccountsManagementFragment;
 import cx.ring.fragments.SmartListFragment;
 import cx.ring.model.Account;
+import cx.ring.model.AccountConfig;
 import cx.ring.model.CallContact;
 import cx.ring.model.ConfigKey;
 import cx.ring.model.Phone;
@@ -602,13 +603,17 @@
     @Override
     public void onAddSipAccountSelected() {
         mNavigationDrawer.closeDrawers();
-        startActivityForResult(new Intent(HomeActivity.this, AccountWizard.class), AccountsManagementFragment.ACCOUNT_CREATE_REQUEST);
+        Intent intent = new Intent(HomeActivity.this, AccountWizard.class);
+        intent.setAction(AccountConfig.ACCOUNT_TYPE_SIP);
+        startActivityForResult(intent, AccountsManagementFragment.ACCOUNT_CREATE_REQUEST);
     }
 
     @Override
     public void onAddRingAccountSelected() {
         mNavigationDrawer.closeDrawers();
-        startActivityForResult(new Intent(HomeActivity.this, AccountWizard.class), AccountsManagementFragment.ACCOUNT_CREATE_REQUEST);
+        Intent intent = new Intent(HomeActivity.this, AccountWizard.class);
+        intent.setAction(AccountConfig.ACCOUNT_TYPE_RING);
+        startActivityForResult(intent, AccountsManagementFragment.ACCOUNT_CREATE_REQUEST);
     }
 
     private void goToShare() {
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
index f19274b..3f01614 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
@@ -41,7 +41,6 @@
 import android.provider.MediaStore;
 import android.provider.OpenableColumns;
 import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -50,9 +49,6 @@
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -85,9 +81,6 @@
     private String mDataPath;
     private LocalService.Callbacks mCallbacks = LocalService.DUMMY_CALLBACKS;
 
-    @BindView(R.id.sipFormLinearLayout)
-    LinearLayout mSipFormLinearLayout;
-
     @BindView(R.id.alias)
     EditText mAliasView;
 
@@ -100,18 +93,14 @@
     @BindView(R.id.password)
     EditText mPasswordView;
 
-    @BindView(R.id.login_form)
-    ScrollView mSIPLoginForm;
-
     @BindView(R.id.create_sip_button)
     Button mCreateSIPAccountButton;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
-        final View inflatedView = inflater.inflate(R.layout.frag_account_creation, parent, false);
+        final View inflatedView = inflater.inflate(R.layout.frag_acc_sip_create, parent, false);
 
         ButterKnife.bind(this, inflatedView);
-        mSipFormLinearLayout.setVisibility(View.GONE);
 
         return inflatedView;
     }
@@ -127,23 +116,6 @@
         return true;
     }
 
-    @OnClick(R.id.ring_create_btn)
-    public void createRingAccount() {
-        AccountWizard accountWizard = (AccountWizard) getActivity();
-        if (accountWizard != null) {
-            accountWizard.ringCreate(false);
-        }
-    }
-
-    @OnClick(R.id.ring_add_account)
-    @SuppressWarnings("unused")
-    public void addRingAccount() {
-        AccountWizard accountWizard = (AccountWizard) getActivity();
-        if (accountWizard != null) {
-            accountWizard.ringLogin(false);
-        }
-    }
-
     /************************
      * SIP Account ADD
      ***********************/
@@ -156,39 +128,6 @@
         attemptCreation();
     }
 
-    @OnClick(R.id.sipHeaderLinearLayout)
-    void presentSIPForm() {
-        if (mSipFormLinearLayout != null && mSipFormLinearLayout.getVisibility() != View.VISIBLE) {
-            mSipFormLinearLayout.setVisibility(View.VISIBLE);
-            //~ Let the time to perform setVisibility before scrolling.
-            mSIPLoginForm.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    mSIPLoginForm.fullScroll(ScrollView.FOCUS_DOWN);
-                    mAliasView.requestFocus();
-                }
-            }, 100);
-        }
-    }
-
-    @OnClick(R.id.sipHeaderLinearLayout)
-    @SuppressWarnings("unused")
-    public void onClickHeader(View v) {
-        if (null != mSipFormLinearLayout) {
-            if (mSipFormLinearLayout.getVisibility() != View.VISIBLE) {
-                mSipFormLinearLayout.setVisibility(View.VISIBLE);
-                //~ Let the time to perform setVisibility before scrolling.
-                mSIPLoginForm.postDelayed(new Runnable() {
-                    @Override
-                    public void run() {
-                        mSIPLoginForm.fullScroll(ScrollView.FOCUS_DOWN);
-                        mAliasView.requestFocus();
-                    }
-                }, 100);
-            }
-        }
-    }
-
     /**
      * Get a file path from a Uri. This will get the the path for Storage Access
      * Framework Documents, as well as the _data field for the MediaStore and
@@ -492,12 +431,6 @@
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
-        ((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.ab_account_creation);
-    }
-
-    @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         if (!(activity instanceof LocalService.Callbacks)) {
@@ -551,7 +484,7 @@
         } else {
             AccountWizard accountWizard = (AccountWizard) getActivity();
             if (accountWizard != null) {
-                accountWizard.initAccountCreation(false, mUsernameView.getText().toString(), null, mPasswordView.getText().toString(), mHostnameView.getText().toString());
+                accountWizard.initSipAccountCreation(mAliasView.getText().toString(), mUsernameView.getText().toString(), mPasswordView.getText().toString(), mHostnameView.getText().toString());
             }
         }
     }
@@ -565,7 +498,7 @@
                     public void onClick(DialogInterface dialog, int whichButton) {
                         AccountWizard a = (AccountWizard) getActivity();
                         if (a != null)
-                            a.initAccountCreation(false, mAliasView.getText().toString(), null, null, null);
+                            a.initSipAccountCreation(mAliasView.getText().toString(), null, null, null);
                     }
                 })
                 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
diff --git a/ring-android/app/src/main/res/layout/frag_acc_sip_create.xml b/ring-android/app/src/main/res/layout/frag_acc_sip_create.xml
new file mode 100644
index 0000000..cb32fa8
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/frag_acc_sip_create.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+Copyright (C) 2004-2016 Savoir-faire Linux Inc.
+
+Authors:    Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+            Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/login_form"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:theme="@style/WizardHome">
+
+    <cx.ring.views.BoundedScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:layout_gravity="center_horizontal"
+        app:bounded_width="500dp">
+
+        <LinearLayout
+            android:id="@+id/sipLinearLayout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:paddingLeft="16dp"
+                android:paddingRight="16dp"
+                android:paddingTop="24dp"
+                android:text="@string/help_sip_title"
+                android:textSize="24sp" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:paddingBottom="24dp"
+                android:paddingLeft="16dp"
+                android:paddingRight="16dp"
+                android:paddingTop="16dp"
+                android:text="@string/help_sip"
+                android:textSize="14sp" />
+
+            <android.support.design.widget.TextInputLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:passwordToggleEnabled="true"
+                android:textColorHint="@color/text_color_secondary_dark"
+                app:hintTextAppearance="@color/text_color_primary_dark">
+
+                <android.support.design.widget.TextInputEditText
+                    android:id="@+id/alias"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:hint="@string/prompt_alias"
+                    android:imeOptions="flagNoExtractUi"
+                    android:maxLines="1"
+                    android:singleLine="true"/>
+            </android.support.design.widget.TextInputLayout>
+
+            <android.support.design.widget.TextInputLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:passwordToggleEnabled="true"
+                android:textColorHint="@color/text_color_secondary_dark"
+                app:hintTextAppearance="@color/text_color_primary_dark">
+
+                <android.support.design.widget.TextInputEditText
+                    android:id="@+id/hostname"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:hint="@string/prompt_hostname"
+                    android:imeOptions="flagNoExtractUi"
+                    android:maxLines="1"
+                    android:singleLine="true"
+                    android:typeface="monospace" />
+            </android.support.design.widget.TextInputLayout>
+
+            <android.support.design.widget.TextInputLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:passwordToggleEnabled="true"
+                android:textColorHint="@color/text_color_secondary_dark"
+                app:hintTextAppearance="@color/text_color_primary_dark">
+
+                <android.support.design.widget.TextInputEditText
+                    android:id="@+id/username"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:hint="@string/prompt_username"
+                    android:imeOptions="flagNoExtractUi"
+                    android:maxLines="1"
+                    android:singleLine="true"
+                    android:typeface="monospace" />
+            </android.support.design.widget.TextInputLayout>
+
+            <android.support.design.widget.TextInputLayout
+                android:id="@+id/etSipPasswordLayout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:passwordToggleEnabled="true"
+                android:textColorHint="@color/text_color_secondary_dark"
+                app:hintTextAppearance="@color/text_color_primary_dark"
+                app:passwordToggleTint="@color/text_color_primary_dark">
+
+                <android.support.design.widget.TextInputEditText
+                    android:id="@+id/password"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:hint="@string/prompt_password"
+                    android:imeActionId="@integer/register_sip_account_actionid"
+                    android:imeActionLabel="@string/action_create_short"
+                    android:imeOptions="flagNoExtractUi"
+                    android:inputType="textPassword"
+                    android:maxLines="1"
+                    android:singleLine="true"
+                    android:typeface="monospace" />
+            </android.support.design.widget.TextInputLayout>
+
+            <Button
+                android:id="@+id/create_sip_button"
+                android:theme="@style/ButtonColored"
+                android:layout_width="200dp"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:text="@string/create_sip_account"/>
+
+        </LinearLayout>
+
+    </cx.ring.views.BoundedScrollView>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/strings_account.xml b/ring-android/app/src/main/res/values/strings_account.xml
index 1057fc1..ef0186d 100644
--- a/ring-android/app/src/main/res/values/strings_account.xml
+++ b/ring-android/app/src/main/res/values/strings_account.xml
@@ -165,11 +165,14 @@
     <string name="account_cannot_read">Can\'t read %1$s</string>
     <string name="account_cannot_be_found_title">Can\'t find account</string>
     <string name="account_cannot_be_found_message">Account couldn\'t be found on the Ring network.\nMake sure it was exported on Ring from an existing device, and that provided credentials are correct.</string>
+    <string name="account_sip_cannot_be_registered_message">Please go to the account settings to edit the provided host and credentials.</string>
     <string name="account_no_network_title">Can\'t connect to the network</string>
     <string name="account_no_network_message">Could not add account because Ring coudn\'t connect to the distributed network. Check your device connectivity.</string>
     <string name="account_device_added_title">Account device added</string>
     <string name="account_device_added_message">You have successfully setup your Ring account on this device.</string>
     <string name="account_device_updated_title">Account device updated</string>
+    <string name="account_sip_success_title">Sip account registered</string>
+    <string name="account_sip_success_message">You have successfully registered your Sip account.</string>
 
     <string name="account_link_button">Link this device to an account</string>
     <string name="account_import_title">Link to an existing account</string>
@@ -207,5 +210,6 @@
     <string name="account_creation_profile">Create your profile</string>
     <string name="account_creation_ring">Create your Ring account</string>
     <string name="account_link_title">Link this device</string>
+    <string name="account_sip_cannot_be_registered">Can\'t register account</string>
 
 </resources>
diff --git a/ring-android/app/src/main/res/values/styles.xml b/ring-android/app/src/main/res/values/styles.xml
index a028338..373e815 100644
--- a/ring-android/app/src/main/res/values/styles.xml
+++ b/ring-android/app/src/main/res/values/styles.xml
@@ -64,6 +64,13 @@
         <item name="colorAccent">@color/white</item>
         <item name="android:background">@color/color_primary_dark</item>
     </style>
+    <style name="WizardHome">
+        <item name="android:textColorPrimary">@color/text_color_primary_dark</item>
+        <item name="android:textColorSecondary">@color/text_color_secondary_dark</item>
+        <item name="android:textColor">@color/text_color_primary_dark</item>
+        <item name="colorAccent">@color/white</item>
+        <item name="android:background">@color/color_primary_light</item>
+    </style>
     <style name="ButtonColoredInverse" parent="Widget.AppCompat.Button.Colored">
         <item name="colorButtonNormal">@color/color_primary_light</item>
         <item name="android:textColor">@color/text_color_primary_dark</item>