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;
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);
}

View file

@ -27,10 +27,12 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
private final List<AccountModel> 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<AccountsRe
holder.jid.setText(account.getJid());
holder.avatar.setColorFilter(ColorUtil.consistentColor(account.getJid().toString()));
holder.enabled.setChecked(account.getEnabled());
holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> {
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

View file

@ -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<List<AccountModel>> 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();
}
}

View file

@ -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);

View file

@ -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<ConnectionState> state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED);
private BehaviorSubject<ConnectionState> 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<ConnectionState> getState() {
return mState;
}
}