Crude account activate/deactivate functionality

This commit is contained in:
Paul Schaub 2019-09-30 02:54:05 +02:00
parent aa99bf1c2d
commit 8ab5633fcf
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
5 changed files with 105 additions and 76 deletions

View file

@ -62,7 +62,7 @@ public class AccountsFragment extends Fragment {
recyclerView = (RecyclerView) view; recyclerView = (RecyclerView) view;
Context context = view.getContext(); Context context = view.getContext();
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
this.adapter = new AccountsRecyclerViewAdapter(accountClickListener); this.adapter = new AccountsRecyclerViewAdapter(viewModel, accountClickListener);
viewModel.getAccounts().observe(this, roomAccountModels -> adapter.setValues(roomAccountModels)); viewModel.getAccounts().observe(this, roomAccountModels -> adapter.setValues(roomAccountModels));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }

View file

@ -27,10 +27,12 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
private final List<AccountModel> mValues; private final List<AccountModel> mValues;
private final OnAccountListItemClickListener mListener; private final OnAccountListItemClickListener mListener;
private final AccountsViewModel viewModel;
public AccountsRecyclerViewAdapter(OnAccountListItemClickListener listener) { public AccountsRecyclerViewAdapter(AccountsViewModel viewModel, OnAccountListItemClickListener listener) {
mValues = new ArrayList<>(); mValues = new ArrayList<>();
mListener = listener; mListener = listener;
this.viewModel = viewModel;
} }
@Override @Override
@ -46,12 +48,11 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
holder.jid.setText(account.getJid()); holder.jid.setText(account.getJid());
holder.avatar.setColorFilter(ColorUtil.consistentColor(account.getJid().toString())); holder.avatar.setColorFilter(ColorUtil.consistentColor(account.getJid().toString()));
holder.enabled.setChecked(account.getEnabled()); holder.enabled.setChecked(account.getEnabled());
holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> {
account.setEnabled(b);
});
holder.accountModel = account; holder.accountModel = account;
holder.status.setText(account.getState()); holder.status.setText(account.getState());
holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> {
viewModel.toggleAccountEnabled(account);
});
holder.mView.setOnClickListener(v -> { holder.mView.setOnClickListener(v -> {
if (null != mListener) { if (null != mListener) {
// Notify the active callbacks interface (the activity, if the // Notify the active callbacks interface (the activity, if the

View file

@ -1,16 +1,23 @@
package org.mercury_im.messenger.ui.login; 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.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer; import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import org.jivesoftware.smack.XMPPConnection;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.core.centers.ConnectionCenter; 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.model.AccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.persistence.repository.AccountRepository;
@ -18,7 +25,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
public class AccountsViewModel extends ViewModel { public class AccountsViewModel extends AndroidViewModel {
@Inject @Inject
AccountRepository repository; AccountRepository repository;
@ -30,8 +37,8 @@ public class AccountsViewModel extends ViewModel {
private final CompositeDisposable compositeDisposable = new CompositeDisposable(); private final CompositeDisposable compositeDisposable = new CompositeDisposable();
@Inject @Inject
public AccountsViewModel() { public AccountsViewModel(Application application) {
super(); super(application);
MercuryImApplication.getApplication().getAppComponent().inject(this); MercuryImApplication.getApplication().getAppComponent().inject(this);
compositeDisposable.add(repository.getAllAccounts() compositeDisposable.add(repository.getAllAccounts()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
@ -48,4 +55,17 @@ public class AccountsViewModel extends ViewModel {
public LiveData<List<AccountModel>> getAccounts() { public LiveData<List<AccountModel>> getAccounts() {
return accounts; 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();
}
} }

View file

@ -8,7 +8,6 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.caps.EntityCapsManager; import org.jivesoftware.smackx.caps.EntityCapsManager;
import org.jivesoftware.smackx.csi.ClientStateIndicationManager; import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
import org.jivesoftware.smackx.mam.MamManager; 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.stores.EntityCapsStore;
import org.mercury_im.messenger.core.connection.MercuryConfiguration; import org.mercury_im.messenger.core.connection.MercuryConfiguration;
import org.mercury_im.messenger.core.connection.MercuryConnection; import org.mercury_im.messenger.core.connection.MercuryConnection;
@ -107,25 +106,36 @@ public class ConnectionCenter {
// initialize new connection // initialize new connection
initializeConnection(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 // Remove unwanted connections from the map
for (long connectionId : connectionMap.keySet()) { for (long connectionId : connectionMap.keySet()) {
if (!accountIds.contains(connectionId)) { if (!accountIds.contains(connectionId)) {
LOGGER.log(Level.INFO, "Connection " + connectionId + " was deleted.");
AbstractXMPPConnection con = AbstractXMPPConnection con =
(AbstractXMPPConnection) connectionMap.get(connectionId).getConnection(); (AbstractXMPPConnection) connectionMap.get(connectionId).getConnection();
con.disconnect(); con.disconnect();
connectionMap.remove(connectionId); 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); disposable.add(allAccounts);

View file

@ -28,114 +28,112 @@ public class MercuryConnection {
private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName()); private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName());
protected final AbstractXMPPConnection connection; private final AbstractXMPPConnection mConnection;
protected final long accountId; private final long mAccountId;
protected final ReconnectionManager reconnectionManager; // Managers
protected final Roster roster; private final ReconnectionManager mReconnectionManager;
protected final ChatManager chatManager; private final Roster mRoster;
protected final CarbonManager carbonManager; private final ChatManager mChatManager;
protected final StableUniqueStanzaIdManager stanzaIdManager; private final CarbonManager mCarbonManager;
protected final ServiceDiscoveryManager serviceDiscoveryManager; private final StableUniqueStanzaIdManager mStanzaIdManager;
protected final MamManager mamManager; private final ServiceDiscoveryManager mServiceDiscoveryManager;
private final MamManager mMamManager;
private final VersionManager mVersionManager;
BehaviorSubject<ConnectionState> state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED); private BehaviorSubject<ConnectionState> mState = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED);
public MercuryConnection(AbstractXMPPConnection connection, long accountId) { public MercuryConnection(AbstractXMPPConnection connection, long accountId) {
this.connection = connection; mConnection = connection;
connection.addConnectionListener(connectionListener); mConnection.addConnectionListener(mConnectionListener);
this.accountId = accountId; mAccountId = accountId;
reconnectionManager = ReconnectionManager.getInstanceFor(connection); mReconnectionManager = ReconnectionManager.getInstanceFor(connection);
reconnectionManager.enableAutomaticReconnection(); mReconnectionManager.enableAutomaticReconnection();
mReconnectionManager.abortPossiblyRunningReconnection();
this.roster = Roster.getInstanceFor(connection); mRoster = Roster.getInstanceFor(connection);
roster.setRosterLoadedAtLogin(true); mRoster.setRosterLoadedAtLogin(true);
this.chatManager = ChatManager.getInstanceFor(connection);
this.carbonManager = CarbonManager.getInstanceFor(connection);
this.stanzaIdManager = StableUniqueStanzaIdManager.getInstanceFor(connection);
stanzaIdManager.enable();
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.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..."); LOGGER.log(Level.INFO, "Connecting...");
state.onNext(ConnectionState.CONNECTING); mState.onNext(ConnectionState.CONNECTING);
AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection(); AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection();
try {
con.connect().login(); con.connect().login();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
} }
public void disconnect() { public void disconnect() throws SmackException.NotConnectedException {
AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection(); AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection();
state.onNext(ConnectionState.DISCONNECTING); mState.onNext(ConnectionState.DISCONNECTING);
try {
con.disconnect(new Presence(Presence.Type.unavailable)); con.disconnect(new Presence(Presence.Type.unavailable));
} catch (SmackException.NotConnectedException e) {
e.printStackTrace(); mState.onNext(ConnectionState.DISCONNECTED);
}
state.onNext(ConnectionState.DISCONNECTED);
} }
public XMPPConnection getConnection() { public XMPPConnection getConnection() {
return connection; return mConnection;
} }
public long getAccountId() { public long getAccountId() {
return accountId; return mAccountId;
} }
public Roster getRoster() { public Roster getRoster() {
return roster; return mRoster;
} }
private final ConnectionListener connectionListener = new ConnectionListener() { private final ConnectionListener mConnectionListener = new ConnectionListener() {
@Override @Override
public void connected(XMPPConnection connection) { public void connected(XMPPConnection connection) {
state.onNext(ConnectionState.CONNECTED); mState.onNext(ConnectionState.CONNECTED);
} }
@Override @Override
public void authenticated(XMPPConnection connection, boolean resumed) { public void authenticated(XMPPConnection connection, boolean resumed) {
state.onNext(ConnectionState.AUTHENTICATED); mState.onNext(ConnectionState.AUTHENTICATED);
LOGGER.info("Connection " + getAccountId() + " authenticated (" + (resumed ? "resumed" : "initially") + ")"); LOGGER.info("Connection " + getAccountId() + " authenticated (" + (resumed ? "resumed" : "initially") + ")");
if (!resumed) { if (!resumed) {
LOGGER.info("Enabling carbons!"); LOGGER.info("Enabling carbons!");
carbonManager.enableCarbonsAsync(exception -> { mCarbonManager.enableCarbonsAsync(exception -> {
LOGGER.severe("Could not enable carbons for connection " + accountId + ": " + exception.getMessage()); LOGGER.severe("Could not enable carbons for connection " + mAccountId + ".");
exception.printStackTrace(); exception.printStackTrace();
}); });
} }
} }
@Override @Override
public void connectionClosed() { public void connectionClosed() {
state.onNext(ConnectionState.DISCONNECTED); mState.onNext(ConnectionState.DISCONNECTED);
} }
@Override @Override
public void connectionClosedOnError(Exception e) { public void connectionClosedOnError(Exception e) {
state.onNext(ConnectionState.DISCONNECTED); mState.onNext(ConnectionState.DISCONNECTED);
} }
}; };
public BehaviorSubject<ConnectionState> getState() {
return mState;
}
} }