aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/siacs')
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java30
-rw-r--r--src/eu/siacs/conversations/ui/ContactsActivity.java (renamed from src/eu/siacs/conversations/ui/NewConversationActivity.java)134
-rw-r--r--src/eu/siacs/conversations/ui/ConversationActivity.java17
-rw-r--r--src/eu/siacs/conversations/ui/ConversationFragment.java3
-rw-r--r--src/eu/siacs/conversations/ui/ManageAccountActivity.java2
-rw-r--r--src/eu/siacs/conversations/ui/MucDetailsActivity.java2
-rw-r--r--src/eu/siacs/conversations/utils/CryptoHelper.java22
-rw-r--r--src/eu/siacs/conversations/xmpp/XmppConnection.java10
8 files changed, 164 insertions, 56 deletions
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index f2233130..815e06af 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -72,7 +72,7 @@ public class XmppConnectionService extends Service {
private static final int PING_MAX_INTERVAL = 300;
private static final int PING_MIN_INTERVAL = 10;
- private static final int PING_TIMEOUT = 2;
+ private static final int PING_TIMEOUT = 5;
private static final int CONNECT_TIMEOUT = 60;
private List<Account> accounts;
@@ -160,7 +160,7 @@ public class XmppConnectionService extends Service {
}
} else {
- Log.d(LOGTAG, "unparsed message " + packet.toString());
+ //Log.d(LOGTAG, "unparsed message " + packet.toString());
}
}
if ((message == null)||(message.getBody() == null)) {
@@ -199,19 +199,6 @@ public class XmppConnectionService extends Service {
accountChangedListener.onAccountListChangedListener();
}
if (account.getStatus() == Account.STATUS_ONLINE) {
- if (account.getXmppConnection().hasFeatureRosterManagment()) {
- updateRoster(account, null);
- }
- connectMultiModeConversations(account);
- List<Conversation> conversations = getConversations();
- for (int i = 0; i < conversations.size(); ++i) {
- if (conversations.get(i).getAccount() == account) {
- sendUnsendMessages(conversations.get(i));
- }
- }
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
- }
scheduleWakeupCall(PING_MAX_INTERVAL, true);
} else if (account.getStatus() == Account.STATUS_OFFLINE) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
@@ -558,6 +545,19 @@ public class XmppConnectionService extends Service {
@Override
public void onBind(Account account) {
databaseBackend.clearPresences(account);
+ if (account.getXmppConnection().hasFeatureRosterManagment()) {
+ updateRoster(account, null);
+ }
+ connectMultiModeConversations(account);
+ List<Conversation> conversations = getConversations();
+ for (int i = 0; i < conversations.size(); ++i) {
+ if (conversations.get(i).getAccount() == account) {
+ sendUnsendMessages(conversations.get(i));
+ }
+ }
+ if (convChangedListener != null) {
+ convChangedListener.onConversationListChanged();
+ }
}
});
return connection;
diff --git a/src/eu/siacs/conversations/ui/NewConversationActivity.java b/src/eu/siacs/conversations/ui/ContactsActivity.java
index 9f8f23a4..1bd6e72f 100644
--- a/src/eu/siacs/conversations/ui/NewConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ContactsActivity.java
@@ -1,9 +1,7 @@
package eu.siacs.conversations.ui;
import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
import java.net.URLDecoder;
-import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -13,9 +11,11 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.Validator;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -37,14 +37,17 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ImageView;
+import android.widget.Toast;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
-public class NewConversationActivity extends XmppActivity {
+public class ContactsActivity extends XmppActivity {
protected List<Contact> rosterContacts = new ArrayList<Contact>();
protected List<Contact> aggregatedContacts = new ArrayList<Contact>();
@@ -56,7 +59,10 @@ public class NewConversationActivity extends XmppActivity {
private TextView contactsHeader;
private List<Account> accounts;
private List<Contact> selectedContacts = new ArrayList<Contact>();
+
+ private ContactsActivity activity = this;
+ private boolean useSubject = true;
private boolean isActionMode = false;
private boolean inviteIntent = false;
private ActionMode actionMode = null;
@@ -79,18 +85,22 @@ public class NewConversationActivity extends XmppActivity {
menu.findItem(R.id.action_start_conversation).setVisible(false);
menu.findItem(R.id.action_contact_details).setVisible(false);
menu.findItem(R.id.action_invite).setVisible(false);
- } else if ((selectedContacts.size() == 1)&&(!inviteIntent)) {
+ menu.findItem(R.id.action_invite_to_existing).setVisible(false);
+ } else if ((selectedContacts.size() == 1) && (!inviteIntent)) {
menu.findItem(R.id.action_start_conversation).setVisible(true);
menu.findItem(R.id.action_contact_details).setVisible(true);
menu.findItem(R.id.action_invite).setVisible(false);
- } else if (!inviteIntent){
+ menu.findItem(R.id.action_invite_to_existing).setVisible(true);
+ } else if (!inviteIntent) {
menu.findItem(R.id.action_start_conversation).setVisible(true);
menu.findItem(R.id.action_contact_details).setVisible(false);
menu.findItem(R.id.action_invite).setVisible(false);
+ menu.findItem(R.id.action_invite_to_existing).setVisible(true);
} else {
menu.findItem(R.id.action_invite).setVisible(true);
menu.findItem(R.id.action_start_conversation).setVisible(false);
menu.findItem(R.id.action_contact_details).setVisible(false);
+ menu.findItem(R.id.action_invite_to_existing).setVisible(false);
}
return true;
}
@@ -125,11 +135,42 @@ public class NewConversationActivity extends XmppActivity {
break;
case R.id.action_invite:
invite();
- break;
+ break;
+ case R.id.action_invite_to_existing:
+ final List<Conversation> mucs = new ArrayList<Conversation>();
+ for(Conversation conv : xmppConnectionService.getConversations()) {
+ if (conv.getMode() == Conversation.MODE_MULTI) {
+ mucs.add(conv);
+ }
+ }
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(getString(R.string.invite_contacts_to_existing));
+ if (mucs.size() >= 1) {
+ String[] options = new String[mucs.size()];
+ for(int i = 0; i < options.length; ++i) {
+ options[i] = mucs.get(i).getName(useSubject);
+ }
+ builder.setItems(options, new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Conversation conversation = mucs.get(which);
+ if (isOnline(conversation.getAccount())) {
+ xmppConnectionService.inviteToConference(conversation, selectedContacts);
+ Toast.makeText(activity, getString(R.string.invitation_sent), Toast.LENGTH_SHORT).show();
+ actionMode.finish();
+ }
+ }
+ });
+ } else {
+ builder.setMessage(getString(R.string.no_open_mucs));
+ }
+ builder.setNegativeButton(getString(R.string.cancel),null);
+ builder.create().show();
+ break;
default:
break;
}
- // TODO Auto-generated method stub
return false;
}
@@ -139,6 +180,20 @@ public class NewConversationActivity extends XmppActivity {
}
};
+ private boolean isOnline(Account account) {
+ if (account.getStatus() == Account.STATUS_ONLINE) {
+ return true;
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.account_offline));
+ builder.setMessage(getString(R.string.cant_invite_while_offline));
+ builder.setNegativeButton("OK", null);
+ builder.setIconAttribute(android.R.attr.alertDialogIcon);
+ builder.create().show();
+ return false;
+ }
+ }
+
private void invite() {
List<Conversation> conversations = xmppConnectionService
.getConversations();
@@ -151,45 +206,64 @@ public class NewConversationActivity extends XmppActivity {
}
}
if (conversation != null) {
- xmppConnectionService.inviteToConference(conversation, selectedContacts);
+ xmppConnectionService.inviteToConference(conversation,
+ selectedContacts);
}
finish();
}
-
+
private void startConference() {
if (accounts.size() > 1) {
getAccountChooser(new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- startConference(accounts.get(which), selectedContacts);
+ startConference(accounts.get(which));
}
}).show();
} else {
- startConference(accounts.get(0), selectedContacts);
+ startConference(accounts.get(0));
}
}
- private void startConference(Account account, List<Contact> contacts) {
- SecureRandom random = new SecureRandom();
- String mucName = new BigInteger(100, random).toString(32);
- String serverName = account.getXmppConnection().getMucServer();
- String jid = mucName + "@" + serverName;
- Conversation conversation = xmppConnectionService
- .findOrCreateConversation(account, jid, true);
- StringBuilder subject = new StringBuilder();
- for (int i = 0; i < selectedContacts.size(); ++i) {
- if (i + 1 != selectedContacts.size()) {
- subject.append(selectedContacts.get(i).getDisplayName() + ", ");
- } else {
- subject.append(selectedContacts.get(i).getDisplayName());
- }
+ private void startConference(final Account account) {
+ if (isOnline(account)) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.new_conference));
+ builder.setMessage(getString(R.string.new_conference_explained));
+ builder.setNegativeButton(getString(R.string.cancel), null);
+ builder.setPositiveButton(getString(R.string.create_invite),
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String mucName = CryptoHelper.randomMucName();
+ String serverName = account.getXmppConnection()
+ .getMucServer();
+ String jid = mucName + "@" + serverName;
+ Conversation conversation = xmppConnectionService
+ .findOrCreateConversation(account, jid, true);
+ StringBuilder subject = new StringBuilder();
+ subject.append(account.getUsername() + ", ");
+ for (int i = 0; i < selectedContacts.size(); ++i) {
+ if (i + 1 != selectedContacts.size()) {
+ subject.append(selectedContacts.get(i)
+ .getDisplayName() + ", ");
+ } else {
+ subject.append(selectedContacts.get(i)
+ .getDisplayName());
+ }
+ }
+ xmppConnectionService.sendConversationSubject(
+ conversation, subject.toString());
+ xmppConnectionService.inviteToConference(conversation,
+ selectedContacts);
+ switchToConversation(conversation, null);
+ }
+ });
+ builder.create().show();
}
- xmppConnectionService.sendConversationSubject(conversation,
- subject.toString());
- xmppConnectionService.inviteToConference(conversation, contacts);
- switchToConversation(conversation, null);
}
protected void updateAggregatedContacts() {
@@ -246,6 +320,8 @@ public class NewConversationActivity extends XmppActivity {
@Override
protected void onStart() {
super.onStart();
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
inviteIntent = "invite".equals(getIntent().getAction());
if (inviteIntent) {
contactsHeader.setVisibility(View.GONE);
diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java
index ad643c31..a08e0727 100644
--- a/src/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ConversationActivity.java
@@ -74,7 +74,7 @@ public class ConversationActivity extends XmppActivity {
if (conversationList.size() >= 1) {
swapConversationFragment();
} else {
- startActivity(new Intent(getApplicationContext(), NewConversationActivity.class));
+ startActivity(new Intent(getApplicationContext(), ContactsActivity.class));
finish();
}
}
@@ -249,12 +249,14 @@ public class ConversationActivity extends XmppActivity {
MenuItem menuArchive = (MenuItem) menu.findItem(R.id.action_archive);
MenuItem menuMucDetails = (MenuItem) menu.findItem(R.id.action_muc_details);
MenuItem menuContactDetails = (MenuItem) menu.findItem(R.id.action_contact_details);
+ MenuItem menuInviteContacts = (MenuItem) menu.findItem(R.id.action_invite);
if ((spl.isOpen()&&(spl.isSlideable()))) {
menuArchive.setVisible(false);
menuMucDetails.setVisible(false);
menuContactDetails.setVisible(false);
menuSecure.setVisible(false);
+ menuInviteContacts.setVisible(false);
} else {
((MenuItem) menu.findItem(R.id.action_add)).setVisible(!spl.isSlideable());
if (this.getSelectedConversation()!=null) {
@@ -263,9 +265,11 @@ public class ConversationActivity extends XmppActivity {
menuContactDetails.setVisible(false);
menuSecure.setVisible(false);
menuArchive.setTitle("Leave conference");
+ menuInviteContacts.setVisible(true);
} else {
menuContactDetails.setVisible(true);
menuMucDetails.setVisible(false);
+ menuInviteContacts.setVisible(false);
if (this.getSelectedConversation().getLatestMessage().getEncryption() != Message.ENCRYPTION_NONE) {
menuSecure.setIcon(R.drawable.ic_action_secure);
}
@@ -282,7 +286,7 @@ public class ConversationActivity extends XmppActivity {
spl.openPane();
break;
case R.id.action_add:
- startActivity(new Intent(this, NewConversationActivity.class));
+ startActivity(new Intent(this, ContactsActivity.class));
break;
case R.id.action_archive:
Conversation conv = getSelectedConversation();
@@ -319,6 +323,13 @@ public class ConversationActivity extends XmppActivity {
intent.putExtra("uuid", getSelectedConversation().getUuid());
startActivity(intent);
break;
+ case R.id.action_invite:
+ Intent inviteIntent = new Intent(getApplicationContext(),
+ ContactsActivity.class);
+ inviteIntent.setAction("invite");
+ inviteIntent.putExtra("uuid",selectedConversation.getUuid());
+ startActivity(inviteIntent);
+ break;
case R.id.action_security:
final Conversation selConv = getSelectedConversation();
View menuItemView = findViewById(R.id.action_security);
@@ -451,7 +462,7 @@ public class ConversationActivity extends XmppActivity {
finish();
} else if (conversationList.size() <= 0) {
//add no history
- startActivity(new Intent(this, NewConversationActivity.class));
+ startActivity(new Intent(this, ContactsActivity.class));
finish();
} else {
spl.openPane();
diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java
index d72dae8e..4ae85dc2 100644
--- a/src/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/eu/siacs/conversations/ui/ConversationFragment.java
@@ -326,7 +326,8 @@ public class ConversationFragment extends Fragment {
public void onStart() {
super.onStart();
ConversationActivity activity = (ConversationActivity) getActivity();
-
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
if (activity.xmppConnectionServiceBound) {
this.onBackendConnected();
}
diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java
index 8798a74c..b9ed4102 100644
--- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java
+++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java
@@ -200,7 +200,7 @@ public class ManageAccountActivity extends XmppActivity {
if ((account.getStatus() == Account.STATUS_OFFLINE)||(account.getStatus() == Account.STATUS_TLS_ERROR)) {
activity.xmppConnectionService.reconnectAccount(accountList.get(position),true);
} else if (account.getStatus() == Account.STATUS_ONLINE) {
- activity.startActivity(new Intent(activity.getApplicationContext(),NewConversationActivity.class));
+ activity.startActivity(new Intent(activity.getApplicationContext(),ContactsActivity.class));
} else if (account.isOptionSet(Account.OPTION_REGISTER)) {
editAccount(account);
}
diff --git a/src/eu/siacs/conversations/ui/MucDetailsActivity.java b/src/eu/siacs/conversations/ui/MucDetailsActivity.java
index 73c18240..8d90fd56 100644
--- a/src/eu/siacs/conversations/ui/MucDetailsActivity.java
+++ b/src/eu/siacs/conversations/ui/MucDetailsActivity.java
@@ -70,7 +70,7 @@ public class MucDetailsActivity extends XmppActivity {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),
- NewConversationActivity.class);
+ ContactsActivity.class);
intent.setAction("invite");
intent.putExtra("uuid",conversation.getUuid());
startActivity(intent);
diff --git a/src/eu/siacs/conversations/utils/CryptoHelper.java b/src/eu/siacs/conversations/utils/CryptoHelper.java
index ebbbd967..550639d2 100644
--- a/src/eu/siacs/conversations/utils/CryptoHelper.java
+++ b/src/eu/siacs/conversations/utils/CryptoHelper.java
@@ -1,9 +1,14 @@
package eu.siacs.conversations.utils;
+import java.security.SecureRandom;
+import java.util.Random;
+
import android.util.Base64;
public class CryptoHelper {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
+ final protected static char[] vowels = "aeiou".toCharArray();
+ final protected static char[] consonants ="bcdfghjklmnpqrstvwxyz".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
@@ -31,4 +36,21 @@ public class CryptoHelper {
return Base64.encodeToString(saslBytes, Base64.DEFAULT);
}
+
+ public static String randomMucName() {
+ Random random = new SecureRandom();
+ return randomWord(3,random)+"."+randomWord(7,random);
+ }
+
+ protected static String randomWord(int lenght,Random random) {
+ StringBuilder builder = new StringBuilder(lenght);
+ for(int i = 0; i < lenght; ++i) {
+ if (i % 2 == 0) {
+ builder.append(consonants[random.nextInt(consonants.length)]);
+ } else {
+ builder.append(vowels[random.nextInt(vowels.length)]);
+ }
+ }
+ return builder.toString();
+ }
}
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index dadd310a..0fbd6f77 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -220,6 +220,7 @@ public class XmppConnection implements Runnable {
tagWriter.writeStanzaAsync(r);
} else if (nextTag.isStart("resumed")) {
tagReader.readElement(nextTag);
+ sendPing();
changeStatus(Account.STATUS_ONLINE);
Log.d(LOGTAG,account.getJid()+": session resumed");
} else if (nextTag.isStart("r")) {
@@ -543,10 +544,6 @@ public class XmppConnection implements Runnable {
String resource = packet.findChild("bind").findChild("jid")
.getContent().split("/")[1];
account.setResource(resource);
- if (bindListener !=null) {
- bindListener.onBind(account);
- }
- account.setStatus(Account.STATUS_ONLINE);
if (streamFeatures.hasChild("sm")) {
EnablePacket enable = new EnablePacket();
tagWriter.writeStanzaAsync(enable);
@@ -554,9 +551,10 @@ public class XmppConnection implements Runnable {
sendInitialPresence();
sendServiceDiscoveryInfo();
sendServiceDiscoveryItems();
- if (statusListener != null) {
- statusListener.onStatusChanged(account);
+ if (bindListener !=null) {
+ bindListener.onBind(account);
}
+ account.setStatus(Account.STATUS_ONLINE);
}
});
}