Move login logic to vm

This commit is contained in:
Paul Schaub 2019-07-29 22:14:35 +02:00
parent 0b27a66dcd
commit 1e1ded9795
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
14 changed files with 314 additions and 91 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/classes" />
</component>
</project>

View file

@ -10,6 +10,7 @@ import android.widget.Button;
import android.widget.TextView;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.google.android.material.textfield.TextInputEditText;
@ -44,9 +45,6 @@ import butterknife.ButterKnife;
*/
public class LoginActivity extends BindingActivity implements TextView.OnEditorActionListener {
@Inject
AccountRepository accountRepository;
// UI references.
@BindView(R.id.jid)
TextInputEditText mJidView;
@ -72,13 +70,50 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
displayCredentials(viewModel.getAccount());
viewModel.getJidError().observe(this, jidError -> {
if (jidError == null) return;
String errorMessage = null;
switch (jidError) {
case none:
break;
case emptyJid:
errorMessage = getResources().getString(R.string.error_field_required);
break;
case invalidJid:
errorMessage = getResources().getString(R.string.error_invalid_jid);
break;
case unknownJid:
errorMessage = "Unknown Jid!";
}
mJidView.setError(errorMessage);
});
viewModel.getPasswordError().observe(this, passwordError -> {
if (passwordError == null) return;
String errorMessage = null;
switch (passwordError) {
case none:
break;
case emptyPassword:
errorMessage = getResources().getString(R.string.error_field_required);
break;
case invalidPassword:
errorMessage = getResources().getString(R.string.error_invalid_password);
break;
case incorrectPassword:
errorMessage = getResources().getString(R.string.error_incorrect_password);
break;
}
mPasswordView.setError(errorMessage);
});
mJidView.setOnEditorActionListener(this);
mPasswordView.setOnEditorActionListener(this);
mSignInView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
loginDetailsEntered();
viewModel.loginDetailsEntered();
}
});
mSignInView.setEnabled(false);
@ -87,12 +122,14 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
@Override
protected void onServiceBound() {
super.onServiceBound();
viewModel.setConnectionService(connectionService);
mSignInView.setEnabled(true);
}
@Override
protected void onServiceUnbound() {
super.onServiceUnbound();
viewModel.setConnectionService(null);
mSignInView.setEnabled(false);
}
@ -112,88 +149,7 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
});
}
// TODO: Move to ViewModel
private void loginDetailsEntered() {
boolean loginIntact = true;
String jidInput = mJidView.getText().toString();
if (jidInput.isEmpty()) {
mJidView.setError(getResources().getString(R.string.error_field_required));
loginIntact = false;
}
EntityBareJid jid = asValidJidOrNull(jidInput);
if (jid == null) {
mJidView.setError(getResources().getString(R.string.error_invalid_jid));
loginIntact = false;
}
String password = mPasswordView.getText().toString();
if (!isPasswordValid(password)) {
mPasswordView.setError(getResources().getString(R.string.error_invalid_password));
loginIntact = false;
}
if (loginIntact) {
RoomAccountModel accountModel = new RoomAccountModel();
accountModel.setEnabled(true);
accountModel.setJid(jid);
accountModel.setPassword(password);
long id = accountRepository.insertAccount(accountModel);
accountModel.setId(id);
Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted.");
attemptLogin(accountModel);
}
}
private void attemptLogin(AccountModel accountModel) {
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
.setHost(accountModel.getJid().getDomain().toString())
.setXmppAddressAndPassword(accountModel.getJid(), accountModel.getPassword())
.setConnectTimeout(2 * 60 * 1000)
.build();
new Thread() {
@Override
public void run() {
try {
XMPPTCPConnection connection = new XMPPTCPConnection(configuration);
connection.setUseStreamManagementResumption(true);
connection.setUseStreamManagement(true);
MercuryConnection mercuryConnection = new AndroidMercuryConnection(connection, accountModel.getId());
connectionService.putConnection(accountModel.getId(), mercuryConnection);
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
connection.connect().login();
Log.d(MercuryImApplication.TAG, "Logged in for " + accountModel.getJid().toString());
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
}
}.start();
super.finish();
}
/**
* Try to parse the input string into a {@link EntityBareJid} and return it.
* Return null on failure.
* @param input input string
* @return valid jid or null
*/
private EntityBareJid asValidJidOrNull(String input) {
return JidCreate.entityBareFromOrNull(input);
}
private boolean isPasswordValid(String password) {
return !password.isEmpty();
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
@ -207,7 +163,7 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
case R.id.password:
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
loginDetailsEntered();
viewModel.loginDetailsEntered();
return true;
}
}

View file

@ -1,12 +1,31 @@
package org.mercury_im.messenger.ui.login;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.mercury_im.messenger.AndroidMercuryConnection;
import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.handler.RoomPlainMessageHandler;
import org.mercury_im.messenger.handler.RoomRosterHandler;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.service.XmppConnectionService;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
import java.io.IOException;
import javax.inject.Inject;
@ -16,6 +35,14 @@ public class LoginViewModel extends ViewModel {
@Inject
AccountRepository accountRepository;
private XmppConnectionService connectionService;
private String jid;
private String password;
private MutableLiveData<JidError> jidError = new MutableLiveData<>();
private MutableLiveData<PasswordError> passwordError = new MutableLiveData<>();
private MutableLiveData<RoomAccountModel> account = new MutableLiveData<>();
public LoginViewModel() {
@ -23,6 +50,50 @@ public class LoginViewModel extends ViewModel {
init(new RoomAccountModel());
}
public enum JidError {
none,
emptyJid,
invalidJid,
unknownJid
}
public enum PasswordError {
none,
emptyPassword,
invalidPassword,
incorrectPassword
}
public void onJidInputChanged(String input) {
this.jid = input;
}
public void onPasswordInputChanged(String input) {
this.password = input;
}
public LiveData<JidError> getJidError() {
return jidError;
}
public LiveData<PasswordError> getPasswordError() {
return passwordError;
}
/**
* Try to parse the input string into a {@link EntityBareJid} and return it.
* Return null on failure.
* @param input input string
* @return valid jid or null
*/
private EntityBareJid asValidJidOrNull(String input) {
return JidCreate.entityBareFromOrNull(input);
}
private boolean isPasswordValid(String password) {
return !password.isEmpty();
}
public void init(@NonNull RoomAccountModel account) {
this.account.setValue(account);
}
@ -37,4 +108,74 @@ public class LoginViewModel extends ViewModel {
accountRepository.insertAccount(account);
}
}
// TODO: Move to ViewModel
public void loginDetailsEntered() {
boolean loginIntact = true;
if (jid.isEmpty()) {
jidError.postValue(JidError.emptyJid);
loginIntact = false;
}
EntityBareJid bareJid = asValidJidOrNull(jid);
if (bareJid == null) {
jidError.postValue(JidError.invalidJid);
loginIntact = false;
}
if (!isPasswordValid(password)) {
passwordError.postValue(PasswordError.invalidPassword);
loginIntact = false;
}
if (loginIntact) {
RoomAccountModel accountModel = new RoomAccountModel();
accountModel.setEnabled(true);
accountModel.setJid(bareJid);
accountModel.setPassword(password);
long id = accountRepository.insertAccount(accountModel);
accountModel.setId(id);
Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted.");
attemptLogin(accountModel);
}
}
private void attemptLogin(AccountModel accountModel) {
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
.setHost(accountModel.getJid().getDomain().toString())
.setXmppAddressAndPassword(accountModel.getJid(), accountModel.getPassword())
.setConnectTimeout(2 * 60 * 1000)
.build();
new Thread() {
@Override
public void run() {
try {
XMPPTCPConnection connection = new XMPPTCPConnection(configuration);
connection.setUseStreamManagementResumption(true);
connection.setUseStreamManagement(true);
MercuryConnection mercuryConnection = new AndroidMercuryConnection(connection, accountModel.getId());
connectionService.putConnection(accountModel.getId(), mercuryConnection);
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
connection.connect().login();
Log.d(MercuryImApplication.TAG, "Logged in for " + accountModel.getJid().toString());
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
}
}.start();
}
public void setConnectionService(XmppConnectionService connectionService) {
this.connectionService = connectionService;
}
}

View file

@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.android.tools.build:gradle:3.4.2'
// NOTE: Do not place your application dependencies here; they belong
@ -25,6 +25,7 @@ allprojects {
repositories {
google()
jcenter()
mavenLocal()
maven {
url 'https://igniterealtime.org/repo/'
}

View file

@ -3,19 +3,34 @@ ext {
// Quickly switch between unique and normal releases using the toggle below
// Version Strings for non-unique releases
/*
smackVersion = "4.4.0-alpha2-SNAPSHOT"
//*
smackVersion = "4.4.0-alpha3-SNAPSHOT"
smackAndroidVersion = smackVersion
smackAndroidExtensionsVersion = smackVersion
smackBoshVersion = smackVersion
smackCompressionJzlibVersion = smackVersion
smackCoreVersion = smackVersion
smackDebugVersion = smackVersion
smackDebugSlf4jVersion = smackVersion
smackExperimentalVersion = smackVersion
smackExtensionsVersion = smackVersion
smackImVersion = smackVersion
smackIntegrationTestVersion = smackVersion
smackJava7Version = smackVersion
smackJingleOldVersion = smackVersion
smackLegacyVersion = smackVersion
smackOmemoVersion = smackVersion
smackOmemoSignalVersion = smackVersion
smackOmemoSignalIntegrationTestVersion = smackVersion
smackOpenpgpVersion = smackVersion
smackResolverMiniDnsVersion = smackVersion
smackReplVersion = smackVersion
smackResolverDnsjavaVersion = smackVersion
smackResolverJavaxVersion = smackVersion
smackResolverMinidnsVersion = smackVersion
smackResolverMinidnsDoxVersion = smackVersion
smackSaslJavaxVersion = smackVersion
smackSaslProvidedVersion = smackVersion
smackTcpVersion = smackVersion
/*/

View file

@ -0,0 +1,13 @@
/**
* Automatically generated file. DO NOT MODIFY
*/
package org.mercury_im.messenger.xmpp_android.test;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "org.mercury_im.messenger.xmpp_android.test";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}

View file

@ -0,0 +1,13 @@
/**
* Automatically generated file. DO NOT MODIFY
*/
package org.mercury_im.messenger.xmpp_android;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "org.mercury_im.messenger.xmpp_android";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mercury_im.messenger.xmpp_android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="28" />
</manifest>

View file

@ -0,0 +1 @@
[{"outputType":{"type":"AAPT_FRIENDLY_MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"xmpp_android-debug.aar","fullName":"debug","baseName":"debug"},"path":"AndroidManifest.xml","properties":{"packageId":"org.mercury_im.messenger.xmpp_android","split":""}}]

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mercury_im.messenger.xmpp_android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="28" />
</manifest>

View file

@ -0,0 +1 @@
[{"outputType":{"type":"MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"xmpp_android-debug.aar","fullName":"debug","baseName":"debug"},"path":"../../library_manifest/debug/AndroidManifest.xml","properties":{"packageId":"org.mercury_im.messenger.xmpp_android","split":""}}]

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mercury_im.messenger.xmpp_android.test" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="28" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:functionalTest="false"
android:handleProfiling="false"
android:label="Tests for org.mercury_im.messenger.xmpp_android.test"
android:targetPackage="org.mercury_im.messenger.xmpp_android.test" />
<application
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
android:debuggable="true" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>

View file

@ -0,0 +1 @@
[{"outputType":{"type":"MERGED_MANIFESTS"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"xmpp_android-debug-androidTest.apk","fullName":"debugAndroidTest","baseName":"debug-androidTest"},"path":"AndroidManifest.xml","properties":{}}]

View file

@ -0,0 +1,37 @@
-- Merging decision tree log ---
manifest
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
package
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:2:5-52
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
android:versionName
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
android:versionCode
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:1-2:55
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
xmlns:android
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml:1:11-69
uses-sdk
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml reason: use-sdk injection requested
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
android:targetSdkVersion
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
android:minSdkVersion
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
ADDED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml
INJECTED from /home/vanitas/Programmierung/mercury/Messenger/xmpp_android/src/main/AndroidManifest.xml