aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/services
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/services')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java144
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/ContactChooserTargetService.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/MessageArchiveService.java16
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java25
5 files changed, 139 insertions, 53 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
index 6311d739..ed9c259f 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
@@ -31,14 +31,17 @@ import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.entities.MucOptions;
import de.thedevstack.conversationsplus.generator.IqGenerator;
import de.thedevstack.conversationsplus.persistance.DatabaseBackend;
+import de.thedevstack.conversationsplus.persistance.FileBackend;
import de.thedevstack.conversationsplus.ui.UiCallback;
import de.thedevstack.conversationsplus.utils.UIHelper;
import de.thedevstack.conversationsplus.xml.Element;
+import de.thedevstack.conversationsplus.xmpp.OnAdvancedStreamFeaturesLoaded;
import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
+import de.thedevstack.conversationsplus.xmpp.XmppConnection;
import de.thedevstack.conversationsplus.xmpp.pep.Avatar;
import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-public class AvatarService {
+public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private static final int FG_COLOR = 0xFFFAFAFA;
private static final int TRANSPARENT = 0x00000000;
@@ -408,6 +411,17 @@ public class AvatarService {
return true;
}
+ @Override
+ public void onAdvancedStreamFeaturesAvailable(Account account) {
+ XmppConnection.Features features = account.getXmppConnection().getFeatures();
+ if (features.pep() && !features.pepPersistent()) {
+ Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": has pep but is not persistent");
+ if (account.getAvatar() != null) {
+ republishAvatarIfNeeded(account);
+ }
+ }
+ }
+
public void publishAvatar(final Account account,
final Uri image,
final UiCallback<Avatar> callback) {
@@ -428,47 +442,79 @@ public class AvatarService {
callback.error(R.string.error_saving_avatar, avatar);
return;
}
- final IqPacket packet = AvatarPacketGenerator.generatePublishAvatarPacket(avatar);
- XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket result) {
- if (result.getType() == IqPacket.TYPE.RESULT) {
- final IqPacket packet = AvatarPacketGenerator.generatePublishAvatarMetadataPacket(avatar);
- XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account,
- IqPacket result) {
- if (result.getType() == IqPacket.TYPE.RESULT) {
- if (account.setAvatar(avatar.getFilename())) {
- AvatarService.getInstance().clear(account);
- DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateAccount(account);
- }
- callback.success(avatar);
- } else {
- callback.error(
- R.string.error_publish_avatar_server_reject,
- avatar);
- }
- }
- });
- } else {
+ sendAndReceiveIqPackages(avatar, account, callback);
+ } else {
+ callback.error(R.string.error_publish_avatar_converting, null);
+ }
+ }
+
+ public void publishAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
+ final IqPacket packet = AvatarPacketGenerator.generatePublishAvatarPacket(avatar);
+ XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket result) {
+ if (result.getType() == IqPacket.TYPE.RESULT) {
+ sendAndReceiveIqPackages(avatar, account, callback);
+ } else {
+ if (callback != null) {
callback.error(
R.string.error_publish_avatar_server_reject,
avatar);
}
}
- });
- } else {
- callback.error(R.string.error_publish_avatar_converting, null);
- }
+ }
+ });
}
private static String generateFetchKey(Account account, final Avatar avatar) {
return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum;
}
+ public void republishAvatarIfNeeded(Account account) {
+ if (account.getAxolotlService().isPepBroken()) {
+ Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": skipping republication of avatar because pep is broken");
+ return;
+ }
+ IqPacket packet = AvatarPacketGenerator.generateRetrieveAvatarMetadataPacket(null);
+ XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
+
+ private Avatar parseAvatar(IqPacket packet) {
+ Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub");
+ if (pubsub != null) {
+ Element items = pubsub.findChild("items");
+ if (items != null) {
+ return Avatar.parseMetadata(items);
+ }
+ }
+ return null;
+ }
+
+ private boolean errorIsItemNotFound(IqPacket packet) {
+ Element error = packet.findChild("error");
+ return packet.getType() == IqPacket.TYPE.ERROR
+ && error != null
+ && error.hasChild("item-not-found");
+ }
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ if (packet.getType() == IqPacket.TYPE.RESULT || errorIsItemNotFound(packet)) {
+ Avatar serverAvatar = parseAvatar(packet);
+ if (serverAvatar == null && account.getAvatar() != null) {
+ Avatar avatar = AvatarUtil.getStoredPepAvatar(account.getAvatar());
+ if (avatar != null) {
+ Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": avatar on server was null. republishing");
+ publishAvatar(account, AvatarUtil.getStoredPepAvatar(account.getAvatar()), null);
+ } else {
+ Logging.e(Config.LOGTAG, account.getJid().toBareJid()+": error rereading avatar");
+ }
+ }
+ }
+ }
+ });
+ }
+
public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
final String KEY = generateFetchKey(account, avatar);
synchronized(this.mInProgressAvatarFetches) {
@@ -624,4 +670,40 @@ public class AvatarService {
}
}
}
+
+ private void sendAndReceiveIqPackages(final Avatar avatar, final Account account, final UiCallback callback) {
+
+ final IqPacket packet = AvatarPacketGenerator.generatePublishAvatarPacket(avatar);
+ XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket result) {
+ if (result.getType() == IqPacket.TYPE.RESULT) {
+ final IqPacket packet = AvatarPacketGenerator.generatePublishAvatarMetadataPacket(avatar);
+ XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() {
+
+ @Override
+ public void onIqPacketReceived(Account account,
+ IqPacket result) {
+ if (result.getType() == IqPacket.TYPE.RESULT) {
+ if (account.setAvatar(avatar.getFilename())) {
+ AvatarService.getInstance().clear(account);
+ DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateAccount(account);
+ }
+ callback.success(avatar);
+ } else {
+ callback.error(
+ R.string.error_publish_avatar_server_reject,
+ avatar);
+ }
+ }
+ });
+ } else {
+ callback.error(
+ R.string.error_publish_avatar_server_reject,
+ avatar);
+ }
+ }
+ });
+ }
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/ContactChooserTargetService.java b/src/main/java/de/thedevstack/conversationsplus/services/ContactChooserTargetService.java
index 8d48d686..6256609c 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/ContactChooserTargetService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/ContactChooserTargetService.java
@@ -48,7 +48,7 @@ public class ContactChooserTargetService extends ChooserTargetService implements
final Conversation conversation = conversations.get(i);
final String name = conversation.getName();
final Icon icon = Icon.createWithBitmap(AvatarService.getInstance().get(conversation, pixel));
- final float score = (1.0f / MAX_TARGETS) * i;
+ final float score = 1 - (1.0f / MAX_TARGETS) * i;
final Bundle extras = new Bundle();
extras.putString("uuid", conversation.getUuid());
chooserTargets.add(new ChooserTarget(name, icon, score, componentName, extras));
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/MessageArchiveService.java b/src/main/java/de/thedevstack/conversationsplus/services/MessageArchiveService.java
index f2298d8c..cd55b42f 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/MessageArchiveService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/MessageArchiveService.java
@@ -45,8 +45,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
}
}
}
- long startCatchup = getLastMessageTransmitted(account);
+ Pair<Long,String> pair = mXmppConnectionService.databaseBackend.getLastMessageReceived(account);
+ long startCatchup = pair == null ? 0 : pair.first;
long endCatchup = account.getXmppConnection().getLastSessionEstablished();
+ final Query query;
if (startCatchup == 0) {
return;
} else if (endCatchup - startCatchup >= Config.MAM_MAX_CATCHUP) {
@@ -57,8 +59,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.query(conversation,startCatchup);
}
}
+ query = new Query(account, startCatchup, endCatchup);
+ } else {
+ query = new Query(account, startCatchup, endCatchup);
+ query.reference = pair.second;
}
- final Query query = new Query(account, startCatchup, endCatchup);
this.queries.add(query);
this.execute(query);
}
@@ -75,11 +80,6 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
}
}
- private long getLastMessageTransmitted(final Account account) {
- Pair<Long,String> pair = mXmppConnectionService.databaseBackend.getLastMessageReceived(account);
- return pair == null ? 0 : pair.first;
- }
-
public Query query(final Conversation conversation) {
if (conversation.getLastMessageTransmitted() < 0 && conversation.countMessages() == 0) {
return query(conversation,
@@ -292,7 +292,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.end = end;
this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
}
-
+
private Query page(String reference) {
Query query = new Query(this.account,this.start,this.end);
query.reference = reference;
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java b/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java
index 488a6075..a3142df4 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java
@@ -176,6 +176,7 @@ public class NotificationService {
final String ringtone = ConversationsPlusPreferences.notificationRingtone();
final boolean vibrate = ConversationsPlusPreferences.vibrateOnNotification();
+ final boolean led = ConversationsPlusPreferences.led();
if (notifications.size() == 0) {
notificationManager.cancel(NOTIFICATION_ID);
@@ -206,7 +207,9 @@ public class NotificationService {
mBuilder.setDefaults(0);
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setDeleteIntent(createDeleteIntent());
- mBuilder.setLights(Settings.LED_COLOR, 2000, 4000);
+ if (led) {
+ mBuilder.setLights(Settings.LED_COLOR, 2000, 4000);
+ }
final Notification notification = mBuilder.build();
notificationManager.notify(NOTIFICATION_ID, notification);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
index f9540bdc..b7b4db2c 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
@@ -455,7 +455,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
return START_STICKY;
case Intent.ACTION_SHUTDOWN:
- logoutAndSave();
+ logoutAndSave(true);
return START_NOT_STICKY;
case ACTION_CLEAR_NOTIFICATION:
mNotificationService.clear();
@@ -738,12 +738,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent);
if (!ConversationsPlusPreferences.keepForegroundService()) {
- this.logoutAndSave();
+ this.logoutAndSave(false);
}
}
- private void logoutAndSave() {
+ private void logoutAndSave(boolean stop) {
+ int activeAccounts = 0;
for (final Account account : accounts) {
+ if (account.getStatus() != Account.State.DISABLED) {
+ activeAccounts++;
+ }
databaseBackend.writeRoster(account.getRoster());
if (account.getXmppConnection() != null) {
new Thread(new Runnable() {
@@ -752,11 +756,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
disconnect(account, false);
}
}).start();
- cancelWakeUpCall(account.getUuid().hashCode());
}
}
- Logging.d(Config.LOGTAG, "good bye");
- stopSelf();
+ if (stop || activeAccounts == 0) {
+ Logging.d(Config.LOGTAG, "good bye");
+ stopSelf();
+ }
}
private void cancelWakeUpCall(int requestCode) {
@@ -789,6 +794,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
connection.setOnBindListener(this.mOnBindListener);
connection.setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener);
connection.addOnAdvancedStreamFeaturesAvailableListener(this.mMessageArchiveService);
+ connection.addOnAdvancedStreamFeaturesAvailableListener(AvatarService.getInstance());
AxolotlService axolotlService = account.getAxolotlService();
if (axolotlService != null) {
connection.addOnAdvancedStreamFeaturesAvailableListener(axolotlService);
@@ -2326,12 +2332,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
if (!force) {
disconnect(account, false);
- try {
- Logging.d(Config.LOGTAG, "wait for disconnect");
- Thread.sleep(500); //sleep wait for disconnect
- } catch (InterruptedException e) {
- //ignored
- }
}
Thread thread = new Thread(connection);
connection.setInteractive(interactive);
@@ -2342,6 +2342,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
disconnect(account, force);
account.getRoster().clearPresences();
connection.resetEverything();
+ account.getAxolotlService().resetBrokenness();
}
}
}