decrypt omemo messages
This commit is contained in:
parent
49b4f54285
commit
2abcb1b4e4
|
@ -54,7 +54,7 @@ public class MessageTransformationTest {
|
||||||
final long id = database.accountDao().insert(account);
|
final long id = database.accountDao().insert(account);
|
||||||
|
|
||||||
this.transformer =
|
this.transformer =
|
||||||
new Transformer(database, database.accountDao().getEnabledAccount(id).get());
|
new Transformer(database.accountDao().getEnabledAccount(id).get(), database);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -81,7 +81,10 @@
|
||||||
android:name=".service.ForegroundService"
|
android:name=".service.ForegroundService"
|
||||||
android:exported="false"/>
|
android:exported="false"/>
|
||||||
|
|
||||||
<service android:name=".service.RtpSessionService" android:exported="false" android:foregroundServiceType="phoneCall"/>
|
<service
|
||||||
|
android:name=".service.RtpSessionService"
|
||||||
|
android:exported="false"
|
||||||
|
android:foregroundServiceType="phoneCall" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receiver.EventReceiver"
|
android:name=".receiver.EventReceiver"
|
||||||
|
@ -95,16 +98,15 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="im.conversations.android.ui.activity.MainActivity"
|
android:name="im.conversations.android.ui.activity.MainActivity"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:exported="true"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:exported="true">
|
android:windowSoftInputMode="adjustResize">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity android:name="im.conversations.android.ui.activity.SettingsActivity" />
|
||||||
android:name="im.conversations.android.ui.activity.SettingsActivity" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name="im.conversations.android.ui.activity.SetupActivity"
|
android:name="im.conversations.android.ui.activity.SetupActivity"
|
||||||
android:windowSoftInputMode="adjustResize" />
|
android:windowSoftInputMode="adjustResize" />
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package im.conversations.android;
|
package im.conversations.android;
|
||||||
|
|
||||||
import android.content.Context;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
|
|
||||||
public abstract class AbstractAccountService {
|
public abstract class AbstractAccountService {
|
||||||
|
|
||||||
protected Context context;
|
|
||||||
protected Account account;
|
protected Account account;
|
||||||
|
protected ConversationsDatabase database;
|
||||||
|
|
||||||
protected AbstractAccountService(final Context context, final Account account) {
|
protected AbstractAccountService(final Account account, final ConversationsDatabase database) {
|
||||||
this.context = context;
|
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
this.database = database;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,8 @@ public class AxolotlPayload {
|
||||||
public String payloadAsString() {
|
public String payloadAsString() {
|
||||||
return new String(payload, StandardCharsets.UTF_8);
|
return new String(payload, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasPayload() {
|
||||||
|
return payload != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package im.conversations.android.axolotl;
|
package im.conversations.android.axolotl;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import eu.siacs.conversations.xmpp.jingle.OmemoVerification;
|
import eu.siacs.conversations.xmpp.jingle.OmemoVerification;
|
||||||
import im.conversations.android.AbstractAccountService;
|
import im.conversations.android.AbstractAccountService;
|
||||||
import im.conversations.android.database.AxolotlDatabaseStore;
|
import im.conversations.android.database.AxolotlDatabaseStore;
|
||||||
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.model.axolotl.Encrypted;
|
import im.conversations.android.xmpp.model.axolotl.Encrypted;
|
||||||
import im.conversations.android.xmpp.model.axolotl.Header;
|
import im.conversations.android.xmpp.model.axolotl.Header;
|
||||||
|
@ -22,6 +22,8 @@ import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.libsignal.DuplicateMessageException;
|
import org.whispersystems.libsignal.DuplicateMessageException;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
import org.whispersystems.libsignal.InvalidKeyException;
|
import org.whispersystems.libsignal.InvalidKeyException;
|
||||||
|
@ -38,6 +40,8 @@ import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||||
|
|
||||||
public class AxolotlService extends AbstractAccountService {
|
public class AxolotlService extends AbstractAccountService {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AxolotlService.class);
|
||||||
|
|
||||||
public static final String KEY_TYPE = "AES";
|
public static final String KEY_TYPE = "AES";
|
||||||
public static final String CIPHER_MODE = "AES/GCM/NoPadding";
|
public static final String CIPHER_MODE = "AES/GCM/NoPadding";
|
||||||
|
|
||||||
|
@ -45,9 +49,10 @@ public class AxolotlService extends AbstractAccountService {
|
||||||
|
|
||||||
private final SignalProtocolStore signalProtocolStore;
|
private final SignalProtocolStore signalProtocolStore;
|
||||||
|
|
||||||
public AxolotlService(final Context context, final Account account) {
|
public AxolotlService(
|
||||||
super(context, account);
|
final Account account, final ConversationsDatabase conversationsDatabase) {
|
||||||
this.signalProtocolStore = new AxolotlDatabaseStore(context, account);
|
super(account, conversationsDatabase);
|
||||||
|
this.signalProtocolStore = new AxolotlDatabaseStore(account, conversationsDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AxolotlSession buildReceivingSession(
|
private AxolotlSession buildReceivingSession(
|
||||||
|
@ -119,6 +124,10 @@ public class AxolotlService extends AbstractAccountService {
|
||||||
final Header header = encrypted.getHeader();
|
final Header header = encrypted.getHeader();
|
||||||
final Key ourKey = header.getKey(signalProtocolStore.getLocalRegistrationId());
|
final Key ourKey = header.getKey(signalProtocolStore.getLocalRegistrationId());
|
||||||
if (ourKey == null) {
|
if (ourKey == null) {
|
||||||
|
LOGGER.info(
|
||||||
|
"looking for {} in {}",
|
||||||
|
signalProtocolStore.getLocalRegistrationId(),
|
||||||
|
header.getKeys());
|
||||||
throw new NotEncryptedForThisDeviceException();
|
throw new NotEncryptedForThisDeviceException();
|
||||||
}
|
}
|
||||||
final byte[] keyWithAuthTag;
|
final byte[] keyWithAuthTag;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package im.conversations.android.database;
|
package im.conversations.android.database;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import im.conversations.android.AbstractAccountService;
|
import im.conversations.android.AbstractAccountService;
|
||||||
import im.conversations.android.axolotl.AxolotlAddress;
|
import im.conversations.android.axolotl.AxolotlAddress;
|
||||||
import im.conversations.android.database.dao.AxolotlDao;
|
import im.conversations.android.database.dao.AxolotlDao;
|
||||||
|
@ -17,12 +16,13 @@ import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
|
|
||||||
public class AxolotlDatabaseStore extends AbstractAccountService implements SignalProtocolStore {
|
public class AxolotlDatabaseStore extends AbstractAccountService implements SignalProtocolStore {
|
||||||
|
|
||||||
public AxolotlDatabaseStore(final Context context, final Account account) {
|
public AxolotlDatabaseStore(
|
||||||
super(context, account);
|
final Account account, final ConversationsDatabase conversationsDatabase) {
|
||||||
|
super(account, conversationsDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AxolotlDao axolotlDao() {
|
private AxolotlDao axolotlDao() {
|
||||||
return ConversationsDatabase.getInstance(context).axolotlDao();
|
return database.axolotlDao();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
package im.conversations.android.tls;
|
package im.conversations.android.tls;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import im.conversations.android.AbstractAccountService;
|
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
public class TrustManager extends AbstractAccountService implements X509TrustManager {
|
public class TrustManager implements X509TrustManager {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final Account account;
|
||||||
|
|
||||||
public TrustManager(final Context context, final Account account) {
|
public TrustManager(final Context context, final Account account) {
|
||||||
super(context, account);
|
this.context = context;
|
||||||
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import im.conversations.android.axolotl.AxolotlDecryptionException;
|
||||||
|
import im.conversations.android.axolotl.AxolotlService;
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.ChatIdentifier;
|
import im.conversations.android.database.model.ChatIdentifier;
|
||||||
|
@ -36,10 +38,20 @@ public class Transformer {
|
||||||
private final ConversationsDatabase database;
|
private final ConversationsDatabase database;
|
||||||
private final Account account;
|
private final Account account;
|
||||||
|
|
||||||
public Transformer(final ConversationsDatabase database, final Account account) {
|
private final AxolotlService axolotlService;
|
||||||
|
|
||||||
|
public Transformer(final Account account, final ConversationsDatabase conversationsDatabase) {
|
||||||
|
this(account, conversationsDatabase, new AxolotlService(account, conversationsDatabase));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transformer(
|
||||||
|
final Account account,
|
||||||
|
final ConversationsDatabase database,
|
||||||
|
final AxolotlService axolotlService) {
|
||||||
Preconditions.checkArgument(account != null, "Account must not be null");
|
Preconditions.checkArgument(account != null, "Account must not be null");
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
this.axolotlService = axolotlService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean transform(final MessageTransformation transformation) {
|
public boolean transform(final MessageTransformation transformation) {
|
||||||
|
@ -72,11 +84,30 @@ public class Transformer {
|
||||||
chat, transformation.messageId, MessageState.error(transformation));
|
chat, transformation.messageId, MessageState.error(transformation));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Replace messageCorrection = transformation.getExtension(Replace.class);
|
final Replace messageCorrection = transformation.getExtension(Replace.class);
|
||||||
final Reactions reactions = transformation.getExtension(Reactions.class);
|
final Reactions reactions = transformation.getExtension(Reactions.class);
|
||||||
final Retract retract = transformation.getExtension(Retract.class);
|
final Retract retract = transformation.getExtension(Retract.class);
|
||||||
// TODO we need to remove fallbacks for reactions, retractions and potentially other things
|
final Encrypted encrypted = transformation.getExtension(Encrypted.class);
|
||||||
final List<MessageContent> contents = parseContent(transformation);
|
final List<MessageContent> contents;
|
||||||
|
if (encrypted != null) {
|
||||||
|
try {
|
||||||
|
final var payload = axolotlService.decrypt(transformation.from, encrypted);
|
||||||
|
if (payload.hasPayload()) {
|
||||||
|
contents = ImmutableList.of(MessageContent.text(payload.payloadAsString(),null));
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (final AxolotlDecryptionException e) {
|
||||||
|
LOGGER.error("Could not decrypt message", e);
|
||||||
|
// TODO if message had payload create error message entry
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO we need to remove fallbacks for reactions, retractions and potentially other
|
||||||
|
// things
|
||||||
|
contents = parseContent(transformation);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean identifiableSender =
|
final boolean identifiableSender =
|
||||||
Arrays.asList(Message.Type.NORMAL, Message.Type.CHAT).contains(messageType)
|
Arrays.asList(Message.Type.NORMAL, Message.Type.CHAT).contains(messageType)
|
||||||
|
|
|
@ -17,7 +17,6 @@ import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import im.conversations.android.AbstractAccountService;
|
|
||||||
import im.conversations.android.BuildConfig;
|
import im.conversations.android.BuildConfig;
|
||||||
import im.conversations.android.Conversations;
|
import im.conversations.android.Conversations;
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
|
@ -106,13 +105,16 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
public class XmppConnection extends AbstractAccountService implements Runnable {
|
public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(XmppConnection.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(XmppConnection.class);
|
||||||
|
|
||||||
private static final boolean EXTENDED_SM_LOGGING = false;
|
private static final boolean EXTENDED_SM_LOGGING = false;
|
||||||
private static final int CONNECT_DISCO_TIMEOUT = 20;
|
private static final int CONNECT_DISCO_TIMEOUT = 20;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final Account account;
|
||||||
|
|
||||||
private final SparseArray<Stanza> mStanzaQueue = new SparseArray<>();
|
private final SparseArray<Stanza> mStanzaQueue = new SparseArray<>();
|
||||||
private final Hashtable<String, Pair<Iq, Consumer<Iq>>> packetCallbacks = new Hashtable<>();
|
private final Hashtable<String, Pair<Iq, Consumer<Iq>>> packetCallbacks = new Hashtable<>();
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
|
@ -155,7 +157,8 @@ public class XmppConnection extends AbstractAccountService implements Runnable {
|
||||||
private CountDownLatch mStreamCountDownLatch;
|
private CountDownLatch mStreamCountDownLatch;
|
||||||
|
|
||||||
public XmppConnection(final Context context, final Account account) {
|
public XmppConnection(final Context context, final Account account) {
|
||||||
super(context, account);
|
this.context = context;
|
||||||
|
this.account = account;
|
||||||
this.connectionAddress = account.address;
|
this.connectionAddress = account.address;
|
||||||
|
|
||||||
// these consumers are pure listeners; they don’t have public method except for accept|apply
|
// these consumers are pure listeners; they don’t have public method except for accept|apply
|
||||||
|
|
|
@ -22,6 +22,7 @@ import im.conversations.android.axolotl.AxolotlPayload;
|
||||||
import im.conversations.android.axolotl.AxolotlService;
|
import im.conversations.android.axolotl.AxolotlService;
|
||||||
import im.conversations.android.axolotl.AxolotlSession;
|
import im.conversations.android.axolotl.AxolotlSession;
|
||||||
import im.conversations.android.axolotl.EncryptionBuilder;
|
import im.conversations.android.axolotl.EncryptionBuilder;
|
||||||
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.xml.Element;
|
import im.conversations.android.xml.Element;
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.IqErrorException;
|
import im.conversations.android.xmpp.IqErrorException;
|
||||||
|
@ -60,7 +61,13 @@ public class AxolotlManager extends AbstractManager {
|
||||||
|
|
||||||
public AxolotlManager(Context context, XmppConnection connection) {
|
public AxolotlManager(Context context, XmppConnection connection) {
|
||||||
super(context, connection);
|
super(context, connection);
|
||||||
this.axolotlService = new AxolotlService(context, connection.getAccount());
|
this.axolotlService =
|
||||||
|
new AxolotlService(
|
||||||
|
connection.getAccount(), ConversationsDatabase.getInstance(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AxolotlService getAxolotlService() {
|
||||||
|
return this.axolotlService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleItems(final BareJid from, final Items items) {
|
public void handleItems(final BareJid from, final Items items) {
|
||||||
|
@ -286,8 +293,11 @@ public class AxolotlManager extends AbstractManager {
|
||||||
throw new IllegalStateException("No signed PreKeys have been created yet");
|
throw new IllegalStateException("No signed PreKeys have been created yet");
|
||||||
}
|
}
|
||||||
bundle.setSignedPreKey(
|
bundle.setSignedPreKey(
|
||||||
signedPreKeyRecord.getKeyPair().getPublicKey(), signedPreKeyRecord.getSignature());
|
signedPreKeyRecord.getId(),
|
||||||
bundle.setPreKeys(getDatabase().axolotlDao().getPreKeys(getAccount().id));
|
signedPreKeyRecord.getKeyPair().getPublicKey(),
|
||||||
|
signedPreKeyRecord.getSignature());
|
||||||
|
bundle.addPreKeys(getDatabase().axolotlDao().getPreKeys(getAccount().id));
|
||||||
|
LOGGER.info("bundle {}", bundle);
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,14 +40,16 @@ public class Bundle extends Extension {
|
||||||
identityKey.setContent(ecPublicKey);
|
identityKey.setContent(ecPublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSignedPreKey(final ECPublicKey ecPublicKey, final byte[] signature) {
|
public void setSignedPreKey(
|
||||||
|
final int id, final ECPublicKey ecPublicKey, final byte[] signature) {
|
||||||
final var signedPreKey = this.addExtension(new SignedPreKey());
|
final var signedPreKey = this.addExtension(new SignedPreKey());
|
||||||
|
signedPreKey.setId(id);
|
||||||
signedPreKey.setContent(ecPublicKey);
|
signedPreKey.setContent(ecPublicKey);
|
||||||
final var signedPreKeySignature = this.addExtension(new SignedPreKeySignature());
|
final var signedPreKeySignature = this.addExtension(new SignedPreKeySignature());
|
||||||
signedPreKeySignature.setContent(signature);
|
signedPreKeySignature.setContent(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreKeys(final List<PreKeyRecord> preKeyRecords) {
|
public void addPreKeys(final List<PreKeyRecord> preKeyRecords) {
|
||||||
final var preKeys = this.addExtension(new PreKeys());
|
final var preKeys = this.addExtension(new PreKeys());
|
||||||
for (final PreKeyRecord preKeyRecord : preKeyRecords) {
|
for (final PreKeyRecord preKeyRecord : preKeyRecords) {
|
||||||
final var preKey = preKeys.addExtension(new PreKey());
|
final var preKey = preKeys.addExtension(new PreKey());
|
||||||
|
|
|
@ -4,7 +4,7 @@ import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xmpp.model.ByteContent;
|
import im.conversations.android.xmpp.model.ByteContent;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement(name = "iv")
|
||||||
public class IV extends Extension implements ByteContent {
|
public class IV extends Extension implements ByteContent {
|
||||||
|
|
||||||
public IV() {
|
public IV() {
|
||||||
|
|
|
@ -16,6 +16,6 @@ public class PreKey extends Extension implements ECPublicKeyContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
public void setId(int id) {
|
||||||
this.setAttribute("id", id);
|
this.setAttribute("preKeyId", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,8 @@ public class SignedPreKey extends Extension implements ECPublicKeyContent {
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return Ints.saturatedCast(this.getLongAttribute("signedPreKeyId"));
|
return Ints.saturatedCast(this.getLongAttribute("signedPreKeyId"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setId(final int id) {
|
||||||
|
this.setAttribute("signedPreKeyId", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import im.conversations.android.annotation.XmlElement;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Active extends ChatStateNotification {
|
public class Active extends ChatStateNotification {
|
||||||
|
|
||||||
protected Active() {
|
public Active() {
|
||||||
super(Active.class);
|
super(Active.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import im.conversations.android.annotation.XmlElement;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Composing extends ChatStateNotification {
|
public class Composing extends ChatStateNotification {
|
||||||
|
|
||||||
protected Composing() {
|
public Composing() {
|
||||||
super(Composing.class);
|
super(Composing.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import im.conversations.android.annotation.XmlElement;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Gone extends ChatStateNotification {
|
public class Gone extends ChatStateNotification {
|
||||||
|
|
||||||
protected Gone() {
|
public Gone() {
|
||||||
super(Gone.class);
|
super(Gone.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import im.conversations.android.annotation.XmlElement;
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Inactive extends ChatStateNotification {
|
public class Inactive extends ChatStateNotification {
|
||||||
|
|
||||||
protected Inactive() {
|
public Inactive() {
|
||||||
super(Inactive.class);
|
super(Inactive.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import im.conversations.android.transformer.TransformationFactory;
|
||||||
import im.conversations.android.transformer.Transformer;
|
import im.conversations.android.transformer.Transformer;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.manager.ArchiveManager;
|
import im.conversations.android.xmpp.manager.ArchiveManager;
|
||||||
|
import im.conversations.android.xmpp.manager.AxolotlManager;
|
||||||
import im.conversations.android.xmpp.manager.CarbonsManager;
|
import im.conversations.android.xmpp.manager.CarbonsManager;
|
||||||
import im.conversations.android.xmpp.manager.ChatStateManager;
|
import im.conversations.android.xmpp.manager.ChatStateManager;
|
||||||
import im.conversations.android.xmpp.manager.JingleConnectionManager;
|
import im.conversations.android.xmpp.manager.JingleConnectionManager;
|
||||||
|
@ -83,7 +84,9 @@ public class MessageProcessor extends XmppConnection.Delegate implements Consume
|
||||||
final boolean sendReceipts;
|
final boolean sendReceipts;
|
||||||
if (transformation.isAnythingToTransform()) {
|
if (transformation.isAnythingToTransform()) {
|
||||||
final var database = ConversationsDatabase.getInstance(context);
|
final var database = ConversationsDatabase.getInstance(context);
|
||||||
final var transformer = new Transformer(database, getAccount());
|
final var axolotlService =
|
||||||
|
connection.getManager(AxolotlManager.class).getAxolotlService();
|
||||||
|
final var transformer = new Transformer(getAccount(), database, axolotlService);
|
||||||
sendReceipts = transformer.transform(transformation);
|
sendReceipts = transformer.transform(transformation);
|
||||||
} else {
|
} else {
|
||||||
sendReceipts = true;
|
sendReceipts = true;
|
||||||
|
@ -96,8 +99,6 @@ public class MessageProcessor extends XmppConnection.Delegate implements Consume
|
||||||
if (chatState != null) {
|
if (chatState != null) {
|
||||||
getManager(ChatStateManager.class).handle(from, chatState);
|
getManager(ChatStateManager.class).handle(from, chatState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO pass JMI to JingleManager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRoot() {
|
private boolean isRoot() {
|
||||||
|
|
Loading…
Reference in a new issue