add AccountRepository
This commit is contained in:
parent
359ef330df
commit
d25cc059c5
|
@ -29,27 +29,36 @@
|
|||
|
||||
package eu.siacs.conversations.ui.util;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PendingItem<T> {
|
||||
|
||||
private T item = null;
|
||||
private T item = null;
|
||||
|
||||
public synchronized void push(T item) {
|
||||
this.item = item;
|
||||
}
|
||||
public synchronized void push(T item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public synchronized T pop() {
|
||||
final T item = this.item;
|
||||
this.item = null;
|
||||
return item;
|
||||
}
|
||||
public synchronized T pop() {
|
||||
final T item = this.item;
|
||||
this.item = null;
|
||||
return item;
|
||||
}
|
||||
|
||||
public synchronized T peek() {
|
||||
return item;
|
||||
}
|
||||
public synchronized T peek() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public synchronized boolean clear() {
|
||||
boolean notNull = this.item != null;
|
||||
this.item = null;
|
||||
return notNull;
|
||||
}
|
||||
public synchronized T peekOrCreate(final Supplier<T> supplier) {
|
||||
if (this.item == null) {
|
||||
this.item = supplier.get();
|
||||
}
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public synchronized boolean clear() {
|
||||
boolean notNull = this.item != null;
|
||||
this.item = null;
|
||||
return notNull;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package im.conversations.android.repository;
|
||||
|
||||
import android.content.Context;
|
||||
import im.conversations.android.database.ConversationsDatabase;
|
||||
|
||||
public abstract class AbstractRepository {
|
||||
|
||||
protected final Context context;
|
||||
protected final ConversationsDatabase database;
|
||||
|
||||
protected AbstractRepository(final Context context) {
|
||||
this.context = context;
|
||||
this.database = ConversationsDatabase.getInstance(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package im.conversations.android.repository;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.common.base.Preconditions;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import im.conversations.android.IDs;
|
||||
import im.conversations.android.database.CredentialStore;
|
||||
import im.conversations.android.database.entity.AccountEntity;
|
||||
import im.conversations.android.database.model.Account;
|
||||
|
||||
public class AccountRepository extends AbstractRepository {
|
||||
|
||||
public AccountRepository(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public Account createAccount(@NonNull final Jid address, final String password) {
|
||||
Preconditions.checkArgument(
|
||||
address.isBareJid(), "Account should be specified without resource");
|
||||
Preconditions.checkArgument(password != null, "Missing password");
|
||||
final byte[] randomSeed = IDs.seed();
|
||||
final var entity = new AccountEntity();
|
||||
entity.address = address;
|
||||
entity.enabled = true;
|
||||
entity.randomSeed = randomSeed;
|
||||
final long id = database.accountDao().insert(entity);
|
||||
final var account = new Account(id, address, entity.randomSeed);
|
||||
try {
|
||||
CredentialStore.getInstance(context).setPassword(account, password);
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalStateException("Could not store password", e);
|
||||
}
|
||||
return account;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package im.conversations.android.xmpp;
|
||||
|
||||
public class ConnectionException extends Exception {
|
||||
|
||||
private final ConnectionState connectionState;
|
||||
|
||||
public ConnectionException(ConnectionState state) {
|
||||
this.connectionState = state;
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ import eu.siacs.conversations.persistance.FileBackend;
|
|||
import eu.siacs.conversations.services.MemorizingTrustManager;
|
||||
import eu.siacs.conversations.services.MessageArchiveService;
|
||||
import eu.siacs.conversations.services.NotificationService;
|
||||
import eu.siacs.conversations.ui.util.PendingItem;
|
||||
import eu.siacs.conversations.utils.Patterns;
|
||||
import eu.siacs.conversations.utils.PhoneHelper;
|
||||
import eu.siacs.conversations.utils.Resolver;
|
||||
|
@ -160,6 +161,7 @@ public class XmppConnection implements Runnable {
|
|||
private final Consumer<Jid> bindConsumer;
|
||||
private final ClassToInstanceMap<AbstractManager> managers;
|
||||
private Consumer<XmppConnection> statusListener = null;
|
||||
private PendingItem<SettableFuture<XmppConnection>> connectedFuture = new PendingItem<>();
|
||||
private SaslMechanism saslMechanism;
|
||||
private HashedToken.Mechanism hashTokenRequest;
|
||||
private HttpUrl redirectionUrl = null;
|
||||
|
@ -244,6 +246,16 @@ public class XmppConnection implements Runnable {
|
|||
if (nextStatus.isError() || nextStatus == ConnectionState.ONLINE) {
|
||||
this.recentErrorConnectionState = nextStatus;
|
||||
}
|
||||
if (nextStatus != ConnectionState.CONNECTING && nextStatus != ConnectionState.OFFLINE) {
|
||||
final var future = this.connectedFuture.pop();
|
||||
if (future != null) {
|
||||
if (nextStatus == ConnectionState.ONLINE) {
|
||||
future.set(this);
|
||||
} else {
|
||||
future.setException(new ConnectionException(nextStatus));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (statusListener != null) {
|
||||
statusListener.accept(this);
|
||||
|
@ -2225,6 +2237,15 @@ public class XmppConnection implements Runnable {
|
|||
this.statusListener = listener;
|
||||
}
|
||||
|
||||
public ListenableFuture<XmppConnection> asConnectedFuture() {
|
||||
synchronized (this) {
|
||||
if (this.connectionState == ConnectionState.ONLINE) {
|
||||
return Futures.immediateFuture(this);
|
||||
}
|
||||
return this.connectedFuture.peekOrCreate(SettableFuture::create);
|
||||
}
|
||||
}
|
||||
|
||||
private void forceCloseSocket() {
|
||||
FileBackend.close(this.socket);
|
||||
FileBackend.close(this.tagReader);
|
||||
|
|
Loading…
Reference in a new issue