allow 'login with certificate' from welcome screen. fixes #3724

Daniel Gultsch created

Change summary

src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java |  2 
src/conversations/java/eu/siacs/conversations/ui/WelcomeActivity.java       | 38 
src/conversations/res/menu/welcome_menu.xml                                 | 18 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java    |  1 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java            |  6 
5 files changed, 51 insertions(+), 14 deletions(-)

Detailed changes

src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java 🔗

@@ -369,7 +369,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
     }
 
     private void deleteAccount(final Account account) {
-        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
         builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
         builder.setIconAttribute(android.R.attr.alertDialogIcon);
         builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));

src/conversations/java/eu/siacs/conversations/ui/WelcomeActivity.java 🔗

@@ -1,11 +1,14 @@
 package eu.siacs.conversations.ui;
 
 import android.Manifest;
+import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.databinding.DataBindingUtil;
 import android.os.Bundle;
+import android.security.KeyChain;
+import android.security.KeyChainAliasCallback;
 import android.support.annotation.NonNull;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.Toolbar;
@@ -21,6 +24,7 @@ import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.ActivityWelcomeBinding;
 import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.utils.InstallReferrerUtils;
 import eu.siacs.conversations.utils.SignupUtils;
 import eu.siacs.conversations.utils.XmppUri;
@@ -29,7 +33,7 @@ import rocks.xmpp.addr.Jid;
 import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
 import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
 
-public class WelcomeActivity extends XmppActivity {
+public class WelcomeActivity extends XmppActivity implements XmppConnectionService.OnAccountCreated, KeyChainAliasCallback {
 
     private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
 
@@ -154,10 +158,42 @@ public class WelcomeActivity extends XmppActivity {
             case R.id.action_scan_qr_code:
                 UriHandlerActivity.scan(this);
                 break;
+            case R.id.action_add_account_with_cert:
+                addAccountFromKey();
+                break;
         }
         return super.onOptionsItemSelected(item);
     }
 
+    private void addAccountFromKey() {
+        try {
+            KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
+        } catch (ActivityNotFoundException e) {
+            Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
+        }
+    }
+
+    @Override
+    public void alias(final String alias) {
+        if (alias != null) {
+            xmppConnectionService.createAccountFromKey(alias, this);
+        }
+    }
+
+    @Override
+    public void onAccountCreated(final Account account) {
+        final Intent intent = new Intent(this, EditAccountActivity.class);
+        intent.putExtra("jid", account.getJid().asBareJid().toString());
+        intent.putExtra("init", true);
+        addInviteUri(intent);
+        startActivity(intent);
+    }
+
+    @Override
+    public void informUser(final int r) {
+        runOnUiThread(() -> Toast.makeText(this, r, Toast.LENGTH_LONG).show());
+    }
+
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
         UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);

src/conversations/res/menu/welcome_menu.xml 🔗

@@ -1,16 +1,22 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
-      xmlns:app="http://schemas.android.com/apk/res-auto">
+    xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <item
         android:id="@+id/action_scan_qr_code"
-        android:title="@string/scan_qr_code"
-        app:showAsAction="ifRoom"
+        android:icon="?attr/icon_scan_qr_code"
         android:orderInCategory="10"
+        android:title="@string/scan_qr_code"
         android:visible="@bool/show_qr_code_scan"
-        android:icon="?attr/icon_scan_qr_code"/>
+        app:showAsAction="ifRoom" />
+
+    <item
+        android:id="@+id/action_add_account_with_cert"
+        android:title="@string/action_add_account_with_certificate"
+        android:visible="true"
+        app:showAsAction="never" />
 
     <item
         android:id="@+id/action_import_backup"
-        app:showAsAction="never"
-        android:title="@string/restore_backup"/>
+        android:title="@string/restore_backup"
+        app:showAsAction="never" />
 </menu>

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -2199,6 +2199,7 @@ public class XmppConnectionService extends Service {
                     final Account account = new Account(info.first, "");
                     account.setPrivateKeyAlias(alias);
                     account.setOption(Account.OPTION_DISABLED, true);
+                    account.setOption(Account.OPTION_FIXED_USERNAME, true);
                     account.setDisplayName(info.second);
                     createAccount(account);
                     callback.onAccountCreated(account);

src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java 🔗

@@ -784,12 +784,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 
             this.mInitMode |= this.mAccount.isOptionSet(Account.OPTION_REGISTER);
             this.mUsernameMode |= mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) && mAccount.isOptionSet(Account.OPTION_REGISTER);
-            if (this.mAccount.getPrivateKeyAlias() != null) {
-                this.binding.accountPassword.setHint(R.string.authenticate_with_certificate);
-                if (this.mInitMode) {
-                    this.binding.accountPassword.requestFocus();
-                }
-            }
             if (mPendingFingerprintVerificationUri != null) {
                 processFingerprintVerification(mPendingFingerprintVerificationUri, false);
                 mPendingFingerprintVerificationUri = null;