From 8ab5633fcfa5f4f5e759399d4e548ddcf323d632 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Mon, 30 Sep 2019 02:54:05 +0200 Subject: [PATCH] Crude account activate/deactivate functionality --- .../messenger/ui/login/AccountsFragment.java | 2 +- .../ui/login/AccountsRecyclerViewAdapter.java | 11 +- .../messenger/ui/login/AccountsViewModel.java | 26 +++- .../core/centers/ConnectionCenter.java | 28 +++-- .../core/connection/MercuryConnection.java | 114 +++++++++--------- 5 files changed, 105 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsFragment.java b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsFragment.java index a382a0f..fac53aa 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsFragment.java @@ -62,7 +62,7 @@ public class AccountsFragment extends Fragment { recyclerView = (RecyclerView) view; Context context = view.getContext(); recyclerView.setLayoutManager(new LinearLayoutManager(context)); - this.adapter = new AccountsRecyclerViewAdapter(accountClickListener); + this.adapter = new AccountsRecyclerViewAdapter(viewModel, accountClickListener); viewModel.getAccounts().observe(this, roomAccountModels -> adapter.setValues(roomAccountModels)); recyclerView.setAdapter(adapter); } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsRecyclerViewAdapter.java b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsRecyclerViewAdapter.java index 609d00e..ee0a9b0 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsRecyclerViewAdapter.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsRecyclerViewAdapter.java @@ -27,10 +27,12 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter mValues; private final OnAccountListItemClickListener mListener; + private final AccountsViewModel viewModel; - public AccountsRecyclerViewAdapter(OnAccountListItemClickListener listener) { + public AccountsRecyclerViewAdapter(AccountsViewModel viewModel, OnAccountListItemClickListener listener) { mValues = new ArrayList<>(); mListener = listener; + this.viewModel = viewModel; } @Override @@ -46,12 +48,11 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter { - account.setEnabled(b); - - }); holder.accountModel = account; holder.status.setText(account.getState()); + holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> { + viewModel.toggleAccountEnabled(account); + }); holder.mView.setOnClickListener(v -> { if (null != mListener) { // Notify the active callbacks interface (the activity, if the diff --git a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsViewModel.java b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsViewModel.java index 2384c36..902f353 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/login/AccountsViewModel.java @@ -1,16 +1,23 @@ package org.mercury_im.messenger.ui.login; +import android.app.Application; +import android.widget.Toast; + +import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import io.reactivex.Scheduler; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; +import org.jivesoftware.smack.XMPPConnection; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.core.centers.ConnectionCenter; +import org.mercury_im.messenger.core.connection.MercuryConnection; import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.repository.AccountRepository; @@ -18,7 +25,7 @@ import java.util.List; import javax.inject.Inject; -public class AccountsViewModel extends ViewModel { +public class AccountsViewModel extends AndroidViewModel { @Inject AccountRepository repository; @@ -30,8 +37,8 @@ public class AccountsViewModel extends ViewModel { private final CompositeDisposable compositeDisposable = new CompositeDisposable(); @Inject - public AccountsViewModel() { - super(); + public AccountsViewModel(Application application) { + super(application); MercuryImApplication.getApplication().getAppComponent().inject(this); compositeDisposable.add(repository.getAllAccounts() .subscribeOn(Schedulers.io()) @@ -48,4 +55,17 @@ public class AccountsViewModel extends ViewModel { public LiveData> getAccounts() { return accounts; } + + public void toggleAccountEnabled(AccountModel accountModel) { + MercuryConnection connection = connectionCenter.getConnection(accountModel); + if (connection == null) { + Toast.makeText(this.getApplication(), "MercuryConnection is null!", Toast.LENGTH_LONG).show(); + return; + } + + accountModel.setEnabled(!accountModel.getEnabled()); + repository.updateAccount(accountModel) + .subscribeOn(Schedulers.io()) + .subscribe(); + } } diff --git a/core/src/main/java/org/mercury_im/messenger/core/centers/ConnectionCenter.java b/core/src/main/java/org/mercury_im/messenger/core/centers/ConnectionCenter.java index 3307cad..1eb695c 100644 --- a/core/src/main/java/org/mercury_im/messenger/core/centers/ConnectionCenter.java +++ b/core/src/main/java/org/mercury_im/messenger/core/centers/ConnectionCenter.java @@ -8,7 +8,6 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jivesoftware.smackx.caps.EntityCapsManager; import org.jivesoftware.smackx.csi.ClientStateIndicationManager; import org.jivesoftware.smackx.mam.MamManager; -import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.core.stores.EntityCapsStore; import org.mercury_im.messenger.core.connection.MercuryConfiguration; import org.mercury_im.messenger.core.connection.MercuryConnection; @@ -107,25 +106,36 @@ public class ConnectionCenter { // initialize new connection initializeConnection(connection); - - if (account.getEnabled()) { - LOGGER.log(Level.INFO, "Connecting..."); - connection.connect(); - LOGGER.log(Level.INFO, "Connected!"); - } else { - LOGGER.log(Level.INFO, "Account not enabled. Skip."); - } } // Remove unwanted connections from the map for (long connectionId : connectionMap.keySet()) { if (!accountIds.contains(connectionId)) { + LOGGER.log(Level.INFO, "Connection " + connectionId + " was deleted."); AbstractXMPPConnection con = (AbstractXMPPConnection) connectionMap.get(connectionId).getConnection(); con.disconnect(); connectionMap.remove(connectionId); } } + + for (AccountModel account : accounts) { + MercuryConnection connection = connectionMap.get(account.getId()); + if (account.getEnabled()) { + if (connection.getConnection().isConnected()) { + continue; + } + LOGGER.log(Level.INFO, "Connecting connection " + account.getId() + " (" + account.getJid().toString() + ")"); + connection.connect(); + LOGGER.log(Level.INFO, "Connected!"); + } else { + if (!connection.getConnection().isConnected()) { + continue; + } + LOGGER.log(Level.INFO, "Account " + account.getJid() + " (" + account.getJid().toString() + ") not enabled. Disable."); + connection.disconnect(); + } + } }); disposable.add(allAccounts); diff --git a/core/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnection.java b/core/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnection.java index ed253f7..770c7e4 100644 --- a/core/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnection.java +++ b/core/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnection.java @@ -28,114 +28,112 @@ public class MercuryConnection { private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName()); - protected final AbstractXMPPConnection connection; - protected final long accountId; + private final AbstractXMPPConnection mConnection; + private final long mAccountId; - protected final ReconnectionManager reconnectionManager; - protected final Roster roster; - protected final ChatManager chatManager; - protected final CarbonManager carbonManager; - protected final StableUniqueStanzaIdManager stanzaIdManager; - protected final ServiceDiscoveryManager serviceDiscoveryManager; - protected final MamManager mamManager; + // Managers + private final ReconnectionManager mReconnectionManager; + private final Roster mRoster; + private final ChatManager mChatManager; + private final CarbonManager mCarbonManager; + private final StableUniqueStanzaIdManager mStanzaIdManager; + private final ServiceDiscoveryManager mServiceDiscoveryManager; + private final MamManager mMamManager; + private final VersionManager mVersionManager; - BehaviorSubject state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED); + private BehaviorSubject mState = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED); public MercuryConnection(AbstractXMPPConnection connection, long accountId) { - this.connection = connection; - connection.addConnectionListener(connectionListener); - this.accountId = accountId; + mConnection = connection; + mConnection.addConnectionListener(mConnectionListener); + mAccountId = accountId; - reconnectionManager = ReconnectionManager.getInstanceFor(connection); - reconnectionManager.enableAutomaticReconnection(); + mReconnectionManager = ReconnectionManager.getInstanceFor(connection); + mReconnectionManager.enableAutomaticReconnection(); + mReconnectionManager.abortPossiblyRunningReconnection(); - this.roster = Roster.getInstanceFor(connection); - roster.setRosterLoadedAtLogin(true); - this.chatManager = ChatManager.getInstanceFor(connection); - this.carbonManager = CarbonManager.getInstanceFor(connection); - this.stanzaIdManager = StableUniqueStanzaIdManager.getInstanceFor(connection); - stanzaIdManager.enable(); + mRoster = Roster.getInstanceFor(connection); + mRoster.setRosterLoadedAtLogin(true); - this.serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); + mChatManager = ChatManager.getInstanceFor(connection); + mCarbonManager = CarbonManager.getInstanceFor(connection); + + mStanzaIdManager = StableUniqueStanzaIdManager.getInstanceFor(connection); + mStanzaIdManager.enable(); + + mServiceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); + mServiceDiscoveryManager.setIdentity(new DiscoverInfo.Identity("client", "Mercury", "phone")); + + mVersionManager = VersionManager.getInstanceFor(connection); + mVersionManager.setVersion("Mercury", "0.0.1-stealth", "Android"); VersionManager.setAutoAppendSmackVersion(false); - VersionManager.getInstanceFor(connection).setVersion("Mercury", "0.0.1-stealth", "Android"); - serviceDiscoveryManager.setIdentity(new DiscoverInfo.Identity("client", "Mercury", "phone")); - mamManager = MamManager.getInstanceFor(connection); + mMamManager = MamManager.getInstanceFor(connection); } - public void connect() { + public void connect() throws InterruptedException, XMPPException, SmackException, IOException { LOGGER.log(Level.INFO, "Connecting..."); - state.onNext(ConnectionState.CONNECTING); + mState.onNext(ConnectionState.CONNECTING); AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection(); - try { - con.connect().login(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (SmackException e) { - e.printStackTrace(); - } catch (XMPPException e) { - e.printStackTrace(); - } + + con.connect().login(); } - public void disconnect() { + public void disconnect() throws SmackException.NotConnectedException { AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection(); - state.onNext(ConnectionState.DISCONNECTING); - try { - con.disconnect(new Presence(Presence.Type.unavailable)); - } catch (SmackException.NotConnectedException e) { - e.printStackTrace(); - } - state.onNext(ConnectionState.DISCONNECTED); + mState.onNext(ConnectionState.DISCONNECTING); + + con.disconnect(new Presence(Presence.Type.unavailable)); + + mState.onNext(ConnectionState.DISCONNECTED); } public XMPPConnection getConnection() { - return connection; + return mConnection; } public long getAccountId() { - return accountId; + return mAccountId; } public Roster getRoster() { - return roster; + return mRoster; } - private final ConnectionListener connectionListener = new ConnectionListener() { + private final ConnectionListener mConnectionListener = new ConnectionListener() { @Override public void connected(XMPPConnection connection) { - state.onNext(ConnectionState.CONNECTED); + mState.onNext(ConnectionState.CONNECTED); } @Override public void authenticated(XMPPConnection connection, boolean resumed) { - state.onNext(ConnectionState.AUTHENTICATED); + mState.onNext(ConnectionState.AUTHENTICATED); LOGGER.info("Connection " + getAccountId() + " authenticated (" + (resumed ? "resumed" : "initially") + ")"); if (!resumed) { LOGGER.info("Enabling carbons!"); - carbonManager.enableCarbonsAsync(exception -> { - LOGGER.severe("Could not enable carbons for connection " + accountId + ": " + exception.getMessage()); + mCarbonManager.enableCarbonsAsync(exception -> { + LOGGER.severe("Could not enable carbons for connection " + mAccountId + "."); exception.printStackTrace(); }); } - - } @Override public void connectionClosed() { - state.onNext(ConnectionState.DISCONNECTED); + mState.onNext(ConnectionState.DISCONNECTED); } @Override public void connectionClosedOnError(Exception e) { - state.onNext(ConnectionState.DISCONNECTED); + mState.onNext(ConnectionState.DISCONNECTED); } }; + + public BehaviorSubject getState() { + return mState; + } }