Primitive XMPP connection
This commit is contained in:
parent
8e51695e69
commit
7bea4d5308
30 changed files with 575 additions and 40 deletions
BIN
.idea/caches/build_file_checksums.ser
Normal file
BIN
.idea/caches/build_file_checksums.ser
Normal file
Binary file not shown.
29
.idea/codeStyles/Project.xml
Normal file
29
.idea/codeStyles/Project.xml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
|
@ -24,7 +24,7 @@
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -8,12 +8,12 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
smackVersion="4.2.3-SNAPSHOT"
|
smackVersion="4.4.0-alpha2-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
#Mon Jan 22 17:04:57 CET 2018
|
#Wed Aug 01 11:38:19 CEST 2018
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
||||||
|
|
|
@ -29,18 +29,24 @@ dependencies {
|
||||||
implementation 'com.android.support:support-emoji:27.0.2'
|
implementation 'com.android.support:support-emoji:27.0.2'
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
|
||||||
|
// The holy ButterKnife \o/
|
||||||
|
compile 'com.jakewharton:butterknife:8.8.1'
|
||||||
|
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
// External UI
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
compile 'de.hdodenhof:circleimageview:2.0.0'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
|
||||||
|
|
||||||
|
// Smack
|
||||||
compile "org.igniterealtime.smack:smack-android-extensions:$smackVersion"
|
compile "org.igniterealtime.smack:smack-android-extensions:$smackVersion"
|
||||||
compile "org.igniterealtime.smack:smack-omemo-signal:$smackVersion"
|
compile "org.igniterealtime.smack:smack-omemo-signal:$smackVersion"
|
||||||
compile "org.igniterealtime.smack:smack-tcp:$smackVersion"
|
compile "org.igniterealtime.smack:smack-tcp:$smackVersion"
|
||||||
compile "org.igniterealtime.smack:smack-experimental:$smackVersion"
|
compile "org.igniterealtime.smack:smack-experimental:$smackVersion"
|
||||||
|
|
||||||
compile 'com.jakewharton:butterknife:8.8.1'
|
// SQLCipher
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
compile 'net.zetetic:android-database-sqlcipher:3.5.9@aar'
|
||||||
|
|
||||||
compile 'de.hdodenhof:circleimageview:2.0.0'
|
// Test stuff
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
||||||
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
android:resource="@xml/automotive_app_desc" />
|
android:resource="@xml/automotive_app_desc" />
|
||||||
|
|
||||||
<service android:name=".service.MyMessagingService"/>
|
<service android:name=".service.MyMessagingService"/>
|
||||||
|
<service android:name=".service.SlamXmppService" />
|
||||||
|
|
||||||
<receiver android:name=".receiver.MessageReadReceiver">
|
<receiver android:name=".receiver.MessageReadReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -18,14 +18,16 @@
|
||||||
package de.vanitasvitae.slam;
|
package de.vanitasvitae.slam;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
import de.vanitasvitae.slam.mvp.DummyPresenterFactory;
|
import de.vanitasvitae.slam.mvp.DummyPresenterFactory;
|
||||||
import de.vanitasvitae.slam.mvp.PresenterFactory;
|
import de.vanitasvitae.slam.mvp.PresenterFactory;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppService;
|
||||||
|
|
||||||
public class SlamApplication extends Application {
|
public class SlamApplication extends Application {
|
||||||
|
|
||||||
public SlamApplication() {
|
public SlamApplication() {
|
||||||
super();
|
super();
|
||||||
PresenterFactory.setInstance(new DummyPresenterFactory());
|
PresenterFactory.setInstance(new PresenterFactory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Paul Schaub
|
||||||
|
*
|
||||||
|
* This code 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package de.vanitasvitae.slam.mvp.contracts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Paul Schaub on 24.02.18.
|
||||||
|
*/
|
||||||
|
public interface BaseContract {
|
||||||
|
|
||||||
|
interface BaseView<T extends BasePresenter> {
|
||||||
|
void setPresenter(T presenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BasePresenter {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ import de.vanitasvitae.slam.xmpp.Resource;
|
||||||
*/
|
*/
|
||||||
public interface ContactDetailContract {
|
public interface ContactDetailContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void setContactAvatar();
|
void setContactAvatar();
|
||||||
void setNickname(String nickname);
|
void setNickname(String nickname);
|
||||||
void setResources(List<Resource> presences);
|
void setResources(List<Resource> presences);
|
||||||
|
@ -34,7 +34,7 @@ public interface ContactDetailContract {
|
||||||
void addFingerprints(List<?> fingerprints);
|
void addFingerprints(List<?> fingerprints);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void onAvatarClick();
|
void onAvatarClick();
|
||||||
void onSharedMediaClick();
|
void onSharedMediaClick();
|
||||||
void onAudioCallClick();
|
void onAudioCallClick();
|
||||||
|
|
|
@ -31,7 +31,7 @@ import de.vanitasvitae.slam.xmpp.Contact;
|
||||||
*/
|
*/
|
||||||
public interface ContactListContract {
|
public interface ContactListContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void addContactListItems(List<Contact> contacts);
|
void addContactListItems(List<Contact> contacts);
|
||||||
void clearContactListItems();
|
void clearContactListItems();
|
||||||
void onUpdateContactPresence();
|
void onUpdateContactPresence();
|
||||||
|
@ -41,7 +41,7 @@ public interface ContactListContract {
|
||||||
void navigateToContactDetail(BareJid contact);
|
void navigateToContactDetail(BareJid contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void onContactListItemClick();
|
void onContactListItemClick();
|
||||||
void onContactListItemLongClick();
|
void onContactListItemLongClick();
|
||||||
void addNewContact();
|
void addNewContact();
|
||||||
|
|
|
@ -30,14 +30,14 @@ import de.vanitasvitae.slam.xmpp.message.AbstractMessage;
|
||||||
*/
|
*/
|
||||||
public interface ConversationContract {
|
public interface ConversationContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void addMessageItems(List<AbstractMessage> messages, boolean end);
|
void addMessageItems(List<AbstractMessage> messages, boolean end);
|
||||||
void highlightMessageItem();
|
void highlightMessageItem();
|
||||||
void correctMessageItem();
|
void correctMessageItem();
|
||||||
void navigateToContactProfile();
|
void navigateToContactProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void setPeersJid(EntityBareJid jid);
|
void setPeersJid(EntityBareJid jid);
|
||||||
void onConversationScrolledToTop();
|
void onConversationScrolledToTop();
|
||||||
void onComposingMessageChanged(String composingMessage);
|
void onComposingMessageChanged(String composingMessage);
|
||||||
|
|
|
@ -29,13 +29,13 @@ import de.vanitasvitae.slam.xmpp.Conversation;
|
||||||
*/
|
*/
|
||||||
public interface ConversationListContract {
|
public interface ConversationListContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void populateConversationList(List<Conversation> conversations);
|
void populateConversationList(List<Conversation> conversations);
|
||||||
void navigateToConversation(BareJid contact);
|
void navigateToConversation(BareJid contact);
|
||||||
void navigateToContactDetail(BareJid contact);
|
void navigateToContactDetail(BareJid contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void onConversationClick();
|
void onConversationClick();
|
||||||
void onConversationLongClick();
|
void onConversationLongClick();
|
||||||
void load();
|
void load();
|
||||||
|
|
|
@ -17,13 +17,15 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.slam.mvp.contracts;
|
package de.vanitasvitae.slam.mvp.contracts;
|
||||||
|
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model-View-Presenter contract of the login screen.
|
* Model-View-Presenter contract of the login screen.
|
||||||
* Created by Paul Schaub on 01.02.18.
|
* Created by Paul Schaub on 01.02.18.
|
||||||
*/
|
*/
|
||||||
public interface LoginContract {
|
public interface LoginContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void showInvalidJidError();
|
void showInvalidJidError();
|
||||||
void hideInvalidJidError();
|
void hideInvalidJidError();
|
||||||
void showInvalidPasswordError();
|
void showInvalidPasswordError();
|
||||||
|
@ -33,11 +35,15 @@ public interface LoginContract {
|
||||||
void showProgressIndicator();
|
void showProgressIndicator();
|
||||||
void hideProgressIndicator();
|
void hideProgressIndicator();
|
||||||
void navigateToMainActivity();
|
void navigateToMainActivity();
|
||||||
|
void disableLoginButton();
|
||||||
|
void enableLoginButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void jidChanged(String jid);
|
void jidChanged(String jid);
|
||||||
void passwordChanged(String password);
|
void passwordChanged(String password);
|
||||||
void loginClicked();
|
void loginClicked();
|
||||||
|
void bindService(SlamXmppService service);
|
||||||
|
void unbindService();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface SearchContract {
|
public interface SearchContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void addSearchResults(List<?> results);
|
void addSearchResults(List<?> results);
|
||||||
void clearSearchResults();
|
void clearSearchResults();
|
||||||
void showLoadingIndicator();
|
void showLoadingIndicator();
|
||||||
|
@ -34,7 +34,7 @@ public interface SearchContract {
|
||||||
void hideEmptySearchResults();
|
void hideEmptySearchResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void onSearchQueryChanged(String query);
|
void onSearchQueryChanged(String query);
|
||||||
void onSearchResultClick();
|
void onSearchResultClick();
|
||||||
void onSearchScrolledToBottom();
|
void onSearchScrolledToBottom();
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.slam.mvp.contracts.message;
|
package de.vanitasvitae.slam.mvp.contracts.message;
|
||||||
|
|
||||||
|
import de.vanitasvitae.slam.mvp.contracts.BaseContract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model-View-Presenter contract for an abstract message.
|
* Model-View-Presenter contract for an abstract message.
|
||||||
*/
|
*/
|
||||||
public interface AbstractMessageContract {
|
public interface AbstractMessageContract {
|
||||||
|
|
||||||
interface View {
|
interface View extends BaseContract.BaseView<Presenter> {
|
||||||
void setDirection(Direction direction);
|
void setDirection(Direction direction);
|
||||||
void setStatusSending();
|
void setStatusSending();
|
||||||
void setStatusSendingFailed();
|
void setStatusSendingFailed();
|
||||||
|
@ -33,7 +35,7 @@ public interface AbstractMessageContract {
|
||||||
void displayErrorMessage();
|
void displayErrorMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Presenter {
|
interface Presenter extends BaseContract.BasePresenter {
|
||||||
void onDeleteMessage();
|
void onDeleteMessage();
|
||||||
void onReadMessage();
|
void onReadMessage();
|
||||||
void onMessageClick();
|
void onMessageClick();
|
||||||
|
|
|
@ -17,18 +17,38 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.slam.mvp.presenter;
|
package de.vanitasvitae.slam.mvp.presenter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.chat2.Chat;
|
||||||
|
import org.jivesoftware.smack.chat2.ChatManager;
|
||||||
|
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
|
||||||
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppConnection;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppService;
|
||||||
|
import de.vanitasvitae.slam.xmpp.Account;
|
||||||
|
|
||||||
public class LoginPresenter implements LoginContract.Presenter {
|
public class LoginPresenter implements LoginContract.Presenter {
|
||||||
|
|
||||||
|
private static final String TAG = "LoginPresenter";
|
||||||
private final LoginContract.View view;
|
private final LoginContract.View view;
|
||||||
|
|
||||||
private BareJid jid;
|
private BareJid jid;
|
||||||
private String password;
|
private String password;
|
||||||
|
private SlamXmppService service;
|
||||||
|
|
||||||
public LoginPresenter(LoginContract.View view) {
|
public LoginPresenter(LoginContract.View view) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
|
@ -39,19 +59,115 @@ public class LoginPresenter implements LoginContract.Presenter {
|
||||||
try {
|
try {
|
||||||
this.jid = JidCreate.entityBareFrom(jid);
|
this.jid = JidCreate.entityBareFrom(jid);
|
||||||
view.hideInvalidJidError();
|
view.hideInvalidJidError();
|
||||||
|
|
||||||
|
if (password != null && !password.isEmpty()) {
|
||||||
|
view.enableLoginButton();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (XmppStringprepException e) {
|
} catch (XmppStringprepException e) {
|
||||||
this.jid = null;
|
this.jid = null;
|
||||||
view.showInvalidJidError();
|
view.showInvalidJidError();
|
||||||
|
view.disableLoginButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void passwordChanged(String password) {
|
public void passwordChanged(String password) {
|
||||||
|
this.password = password;
|
||||||
|
if (password == null || password.isEmpty()) {
|
||||||
|
view.disableLoginButton();
|
||||||
|
} else if (jid != null) {
|
||||||
|
view.enableLoginButton();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loginClicked() {
|
public void loginClicked() {
|
||||||
|
if (jid == null) {
|
||||||
|
view.showInvalidJidError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password == null) {
|
||||||
|
view.showInvalidPasswordError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (service != null) {
|
||||||
|
view.disableLoginButton();
|
||||||
|
final Account account = new Account(jid);
|
||||||
|
|
||||||
|
Thread loginThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SlamXmppConnection connection = null;
|
||||||
|
try {
|
||||||
|
connection = new SlamXmppConnection(
|
||||||
|
jid.asEntityBareJidOrThrow(), password);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
((AppCompatActivity)view).runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText((Context)view, "Unknown host", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
service.addConnection(account, connection);
|
||||||
|
final SlamXmppConnection finalConnection = connection;
|
||||||
|
connection.login(new SlamXmppConnection.LoginCallback() {
|
||||||
|
@Override
|
||||||
|
public void success() {
|
||||||
|
((AppCompatActivity)view).runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
view.navigateToMainActivity();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ChatManager.getInstanceFor(finalConnection.getConnection())
|
||||||
|
.addIncomingListener(new IncomingChatMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void newIncomingMessage(final EntityBareJid from, final Message message, Chat chat) {
|
||||||
|
final AppCompatActivity activity = (AppCompatActivity) view;
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText(activity.getApplicationContext(), from.toString() + ": " + message.getBody(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failure(final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
((AppCompatActivity)view).runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText((Context)view, e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
view.enableLoginButton();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loginThread.start();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
view.showServerNotFoundError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindService(SlamXmppService service) {
|
||||||
|
Log.d(TAG, "bindService()");
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unbindService() {
|
||||||
|
Log.d(TAG, "unbindService()");
|
||||||
|
this.service = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,13 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.vanitasvitae.slam.mvp.contracts.ConversationContract;
|
import de.vanitasvitae.slam.mvp.contracts.ConversationContract;
|
||||||
|
import de.vanitasvitae.slam.xmpp.message.AbstractMessage;
|
||||||
|
|
||||||
public class DummyConversationPresenter implements ConversationContract.Presenter {
|
public class DummyConversationPresenter implements ConversationContract.Presenter {
|
||||||
|
|
||||||
private final ConversationContract.View view;
|
private final ConversationContract.View view;
|
||||||
|
|
||||||
private final List<Message> dummyMessages = new ArrayList<>();
|
private final List<AbstractMessage> dummyMessages = new ArrayList<>();
|
||||||
|
|
||||||
public DummyConversationPresenter(ConversationContract.View view) {
|
public DummyConversationPresenter(ConversationContract.View view) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
|
@ -41,6 +42,7 @@ public class DummyConversationPresenter implements ConversationContract.Presente
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateDummyMessages() {
|
private void populateDummyMessages() {
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
BareJid alice = JidCreate.bareFrom("alice@wonderland.lit");
|
BareJid alice = JidCreate.bareFrom("alice@wonderland.lit");
|
||||||
|
|
||||||
|
@ -66,6 +68,7 @@ public class DummyConversationPresenter implements ConversationContract.Presente
|
||||||
} catch (XmppStringprepException e) {
|
} catch (XmppStringprepException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dummy presenter, that has no model.
|
* Dummy presenter, that has no model.
|
||||||
|
@ -82,4 +83,14 @@ public class DummyLoginPresenter implements LoginContract.Presenter {
|
||||||
}
|
}
|
||||||
}, 250);
|
}, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindService(SlamXmppService service) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unbindService() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class ContactDetailActivity extends ThemedAppCompatActivity
|
||||||
|
|
||||||
public static final String TAG = "Slam!";
|
public static final String TAG = "Slam!";
|
||||||
|
|
||||||
private final ContactDetailContract.Presenter presenter;
|
private ContactDetailContract.Presenter presenter;
|
||||||
|
|
||||||
private final ContactDetailResourcesFragment resourcesFragment = new ContactDetailResourcesFragment();
|
private final ContactDetailResourcesFragment resourcesFragment = new ContactDetailResourcesFragment();
|
||||||
private final ContactDetailInfoFragment infoFragment = new ContactDetailInfoFragment();
|
private final ContactDetailInfoFragment infoFragment = new ContactDetailInfoFragment();
|
||||||
|
@ -71,7 +71,7 @@ public class ContactDetailActivity extends ThemedAppCompatActivity
|
||||||
private int animateProfileCirclePercent = 30;
|
private int animateProfileCirclePercent = 30;
|
||||||
|
|
||||||
public ContactDetailActivity() {
|
public ContactDetailActivity() {
|
||||||
this.presenter = PresenterFactory.getInstance().createContactDetailPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createContactDetailPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,6 +151,11 @@ public class ContactDetailActivity extends ThemedAppCompatActivity
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(ContactDetailContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
class DetailFragmentPagerAdapter extends FragmentPagerAdapter {
|
class DetailFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
public DetailFragmentPagerAdapter(FragmentManager fm) {
|
public DetailFragmentPagerAdapter(FragmentManager fm) {
|
||||||
|
|
|
@ -47,13 +47,13 @@ public class ContactListFragment extends Fragment implements ContactListContract
|
||||||
@BindView(R.id.recycler_list)
|
@BindView(R.id.recycler_list)
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
|
|
||||||
private final ContactListContract.Presenter presenter;
|
private ContactListContract.Presenter presenter;
|
||||||
|
|
||||||
private final List<Contact> contacts = new ArrayList<>();
|
private final List<Contact> contacts = new ArrayList<>();
|
||||||
|
|
||||||
public ContactListFragment() {
|
public ContactListFragment() {
|
||||||
super();
|
super();
|
||||||
this.presenter = PresenterFactory.getInstance().createContactListPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createContactListPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,4 +142,8 @@ public class ContactListFragment extends Fragment implements ContactListContract
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(ContactListContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class ConversationFragment extends Fragment implements ConversationContra
|
||||||
@BindView(R.id.recycler_chat)
|
@BindView(R.id.recycler_chat)
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
|
|
||||||
private final ConversationContract.Presenter presenter;
|
private ConversationContract.Presenter presenter;
|
||||||
|
|
||||||
Map<String, Integer> messageIdIndizes = new HashMap<>();
|
Map<String, Integer> messageIdIndizes = new HashMap<>();
|
||||||
List<AbstractMessage> messages = new ArrayList<>();
|
List<AbstractMessage> messages = new ArrayList<>();
|
||||||
|
@ -87,7 +87,7 @@ public class ConversationFragment extends Fragment implements ConversationContra
|
||||||
|
|
||||||
public ConversationFragment() {
|
public ConversationFragment() {
|
||||||
super();
|
super();
|
||||||
this.presenter = PresenterFactory.getInstance().createConversationPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createConversationPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -117,6 +117,11 @@ public class ConversationFragment extends Fragment implements ConversationContra
|
||||||
recyclerView.getAdapter().notifyDataSetChanged();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(ConversationContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMessageItems(List<AbstractMessage> messages, boolean end) {
|
public void addMessageItems(List<AbstractMessage> messages, boolean end) {
|
||||||
if (end) {
|
if (end) {
|
||||||
|
|
|
@ -49,12 +49,12 @@ public class ConversationListFragment extends Fragment implements ConversationLi
|
||||||
@BindView(R.id.recycler_list)
|
@BindView(R.id.recycler_list)
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
|
|
||||||
private final ConversationListContract.Presenter presenter;
|
private ConversationListContract.Presenter presenter;
|
||||||
private final List<Conversation> conversations = new ArrayList<>();
|
private final List<Conversation> conversations = new ArrayList<>();
|
||||||
|
|
||||||
public ConversationListFragment() {
|
public ConversationListFragment() {
|
||||||
super();
|
super();
|
||||||
this.presenter = PresenterFactory.getInstance().createConversationListPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createConversationListPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,6 +72,11 @@ public class ConversationListFragment extends Fragment implements ConversationLi
|
||||||
recyclerView.getAdapter().notifyDataSetChanged();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(ConversationListContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void populateConversationList(List<Conversation> conversations) {
|
public void populateConversationList(List<Conversation> conversations) {
|
||||||
this.conversations.clear();
|
this.conversations.clear();
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.slam.mvp.view;
|
package de.vanitasvitae.slam.mvp.view;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.support.design.widget.TextInputEditText;
|
import android.support.design.widget.TextInputEditText;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
@ -40,8 +44,9 @@ import de.vanitasvitae.slam.R;
|
||||||
import de.vanitasvitae.slam.mvp.PresenterFactory;
|
import de.vanitasvitae.slam.mvp.PresenterFactory;
|
||||||
import de.vanitasvitae.slam.mvp.view.abstr.ThemedAppCompatActivity;
|
import de.vanitasvitae.slam.mvp.view.abstr.ThemedAppCompatActivity;
|
||||||
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppService;
|
||||||
|
|
||||||
public class LoginActivity extends ThemedAppCompatActivity implements LoginContract.View {
|
public class LoginActivity extends ThemedAppCompatActivity implements LoginContract.View, ServiceConnection {
|
||||||
|
|
||||||
// Presenter of this view
|
// Presenter of this view
|
||||||
private LoginContract.Presenter presenter;
|
private LoginContract.Presenter presenter;
|
||||||
|
@ -67,9 +72,11 @@ public class LoginActivity extends ThemedAppCompatActivity implements LoginContr
|
||||||
@BindView(R.id.button_login)
|
@BindView(R.id.button_login)
|
||||||
Button buttonLogin;
|
Button buttonLogin;
|
||||||
|
|
||||||
|
private SlamXmppService slamService;
|
||||||
|
|
||||||
public LoginActivity() {
|
public LoginActivity() {
|
||||||
super();
|
super();
|
||||||
this.presenter = PresenterFactory.getInstance().createLoginPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createLoginPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,8 +110,29 @@ public class LoginActivity extends ThemedAppCompatActivity implements LoginContr
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
// Start xmpp service
|
||||||
|
Intent serviceIntent = new Intent(this, SlamXmppService.class);
|
||||||
|
bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
unbindService(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(LoginContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
@OnClick(R.id.button_login)
|
@OnClick(R.id.button_login)
|
||||||
void login() {
|
void login() {
|
||||||
|
Intent serviceIntent = new Intent(getApplicationContext(), SlamXmppService.class);
|
||||||
|
getApplicationContext().startService(serviceIntent);
|
||||||
presenter.loginClicked();
|
presenter.loginClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,5 +190,28 @@ public class LoginActivity extends ThemedAppCompatActivity implements LoginContr
|
||||||
startActivity(new Intent(this, MainActivity.class));
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableLoginButton() {
|
||||||
|
buttonLogin.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enableLoginButton() {
|
||||||
|
buttonLogin.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
SlamXmppService.SlamBinder binder = (SlamXmppService.SlamBinder) service;
|
||||||
|
slamService = binder.getService();
|
||||||
|
presenter.bindService(slamService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
slamService = null;
|
||||||
|
presenter.unbindService();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,10 @@ import de.vanitasvitae.slam.mvp.contracts.SearchContract;
|
||||||
*/
|
*/
|
||||||
public class SearchFragment extends Fragment implements SearchContract.View {
|
public class SearchFragment extends Fragment implements SearchContract.View {
|
||||||
|
|
||||||
private final SearchContract.Presenter presenter;
|
private SearchContract.Presenter presenter;
|
||||||
|
|
||||||
public SearchFragment() {
|
public SearchFragment() {
|
||||||
this.presenter = PresenterFactory.getInstance().createSearchPresenter(this);
|
setPresenter(PresenterFactory.getInstance().createSearchPresenter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,4 +66,9 @@ public class SearchFragment extends Fragment implements SearchContract.View {
|
||||||
public void hideEmptySearchResults() {
|
public void hideEmptySearchResults() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(SearchContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import de.vanitasvitae.slam.xmpp.message.AbstractMessage;
|
||||||
public abstract class MessageView<T extends AbstractMessage> extends RecyclerView.ViewHolder
|
public abstract class MessageView<T extends AbstractMessage> extends RecyclerView.ViewHolder
|
||||||
implements AbstractMessageContract.View {
|
implements AbstractMessageContract.View {
|
||||||
|
|
||||||
|
protected AbstractMessageContract.Presenter presenter;
|
||||||
|
|
||||||
public MessageView(View itemView) {
|
public MessageView(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
}
|
}
|
||||||
|
@ -83,4 +85,9 @@ public abstract class MessageView<T extends AbstractMessage> extends RecyclerVie
|
||||||
public void displayErrorMessage() {
|
public void displayErrorMessage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPresenter(AbstractMessageContract.Presenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Paul Schaub
|
||||||
|
*
|
||||||
|
* This code 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package de.vanitasvitae.slam.service;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
|
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||||
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Paul Schaub on 24.02.18.
|
||||||
|
*/
|
||||||
|
public class SlamXmppConnection {
|
||||||
|
|
||||||
|
private static final String TAG = "SlamConn";
|
||||||
|
|
||||||
|
private final EntityBareJid jid;
|
||||||
|
private final AbstractXMPPConnection connection;
|
||||||
|
private final Resourcepart resourcepart;
|
||||||
|
|
||||||
|
public SlamXmppConnection(EntityBareJid jid, String password) throws UnknownHostException {
|
||||||
|
this.jid = jid;
|
||||||
|
// Resource
|
||||||
|
String res = "Slam-" + StringUtils.randomString(12);
|
||||||
|
try {
|
||||||
|
this.resourcepart = Resourcepart.from(res);
|
||||||
|
} catch (XmppStringprepException e) {
|
||||||
|
throw new AssertionError("Resourcepart \"" + res + "\" appears to be invalid.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
|
||||||
|
.setHost(this.jid.getDomain().toString())
|
||||||
|
.setHostAddress(InetAddress.getByName(jid.getDomain().toString()))
|
||||||
|
.setXmppDomain(jid.asDomainBareJid())
|
||||||
|
.setUsernameAndPassword(jid.getLocalpart().toString(), password)
|
||||||
|
.setResource(resourcepart)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.connection = new XMPPTCPConnection(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractXMPPConnection getConnection() {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void login(final LoginCallback callback) {
|
||||||
|
try {
|
||||||
|
getConnection().connect().login();
|
||||||
|
Log.d(TAG, "Account " + jid.toString() + " logged in.");
|
||||||
|
callback.success();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "Account " + jid.toString() + " could not log in.");
|
||||||
|
e.printStackTrace();
|
||||||
|
callback.failure(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface LoginCallback {
|
||||||
|
void success();
|
||||||
|
void failure(Exception e);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Paul Schaub
|
||||||
|
*
|
||||||
|
* This code 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package de.vanitasvitae.slam.service;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import de.vanitasvitae.slam.xmpp.Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Paul Schaub on 24.02.18.
|
||||||
|
*/
|
||||||
|
public class SlamXmppService extends Service {
|
||||||
|
|
||||||
|
private static final String TAG = "SlamService";
|
||||||
|
|
||||||
|
private final IBinder binder = new SlamBinder();
|
||||||
|
private Account currentAccount;
|
||||||
|
private final HashMap<Account, SlamXmppConnection> connections = new HashMap<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return binder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
Log.d(TAG,"onStartCommand()");
|
||||||
|
return Service.START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addConnection(@NonNull Account account, SlamXmppConnection connection) {
|
||||||
|
Log.d(TAG, "Adding a new connection for " + account.getJid().toString());
|
||||||
|
this.connections.put(account, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
Log.d(TAG, "onDestroy()");
|
||||||
|
for (SlamXmppConnection c : connections.values()) {
|
||||||
|
c.getConnection().disconnect();
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlamXmppConnection getConnection(@NonNull Account account) {
|
||||||
|
return connections.get(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlamBinder extends Binder {
|
||||||
|
public SlamXmppService getService() {
|
||||||
|
return SlamXmppService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package de.vanitasvitae.slam.task;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import de.vanitasvitae.slam.mvp.contracts.LoginContract;
|
||||||
|
import de.vanitasvitae.slam.service.SlamXmppConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Paul Schaub on 26.02.18.
|
||||||
|
*/
|
||||||
|
public class LoginTask extends AsyncTask<LoginTask.Credentials, Void, SlamXmppConnection> {
|
||||||
|
|
||||||
|
private final LoginContract.View view;
|
||||||
|
private Exception exception;
|
||||||
|
|
||||||
|
public LoginTask(LoginContract.View view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SlamXmppConnection doInBackground(Credentials... credentials) {
|
||||||
|
if (credentials.length != 1) {
|
||||||
|
throw new IllegalArgumentException("Please only present one set of credentials at a time.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SlamXmppConnection connection;
|
||||||
|
try {
|
||||||
|
connection = new SlamXmppConnection(credentials[0].jid, credentials[0].password);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
exception = e;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(SlamXmppConnection result) {
|
||||||
|
if (exception == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception instanceof UnknownHostException) {
|
||||||
|
view.showServerNotFoundError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Credentials {
|
||||||
|
private final EntityBareJid jid;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
public Credentials(@NonNull EntityBareJid jid, @NonNull String password) {
|
||||||
|
this.jid = jid;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,20 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.slam.xmpp;
|
package de.vanitasvitae.slam.xmpp;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Paul Schaub on 24.02.18.
|
* Created by Paul Schaub on 24.02.18.
|
||||||
*/
|
*/
|
||||||
public class Account {
|
public class Account {
|
||||||
|
|
||||||
|
private final BareJid jid;
|
||||||
|
|
||||||
|
public Account(BareJid jid) {
|
||||||
|
this.jid = jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BareJid getJid() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue