diff --git a/res/menu/attachment_choices.xml b/res/menu/attachment_choices.xml index 7e3ebbea5..6a4f295a2 100644 --- a/res/menu/attachment_choices.xml +++ b/res/menu/attachment_choices.xml @@ -9,5 +9,6 @@ android:title="@string/attach_take_picture"/> + android:title="@string/attach_record_voice" + android:visible="false"/> \ No newline at end of file diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 883768420..292a81e81 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -164,5 +164,9 @@ Vorübergehend abschalten Anschalten Sprache aufzeichnen + Kontoeinstellungen + Speichern + Passwörter stimmen nicht überein + Ungültige Jabber ID \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 9841aa60c..2b5c25f27 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -164,5 +164,9 @@ Temporarily disable Enable Record voice + Account Settings + Save + Passwords do not match + This is not a valid Jabber ID \ No newline at end of file diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java index 35870aaae..3e7ad97f0 100644 --- a/src/eu/siacs/conversations/entities/Account.java +++ b/src/eu/siacs/conversations/entities/Account.java @@ -135,7 +135,7 @@ public class Account extends AbstractEntity{ } public boolean hasErrorStatus() { - return getStatus() > STATUS_NO_INTERNET; + return getStatus() > STATUS_NO_INTERNET && (getXmppConnection().getAttempt() >= 2); } public void setResource(String resource) { diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java index 33f7a8d49..950e349e0 100644 --- a/src/eu/siacs/conversations/entities/Message.java +++ b/src/eu/siacs/conversations/entities/Message.java @@ -29,6 +29,7 @@ public class Message extends AbstractEntity { public static final int TYPE_TEXT = 0; public static final int TYPE_IMAGE = 1; + public static final int TYPE_AUDIO = 2; public static String CONVERSATION = "conversationUuid"; public static String COUNTERPART = "counterpart"; diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 624dd219e..3a02b40eb 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -242,10 +242,17 @@ public class XmppConnectionService extends Service { } else if (account.getStatus() == Account.STATUS_REGISTRATION_SUCCESSFULL) { databaseBackend.updateAccount(account); reconnectAccount(account, true); - } else { - UIHelper.showErrorNotification(getApplicationContext(), - getAccounts()); + } else if (account.getStatus() != Account.STATUS_CONNECTING) { + int next = account.getXmppConnection().getTimeToNextAttempt(); + Log.d(LOGTAG, account.getJid() + + ": error connecting account. try again in " + next + + "s for the " + + (account.getXmppConnection().getAttempt() + 1) + + " time"); + scheduleWakeupCall(next, false); } + UIHelper.showErrorNotification(getApplicationContext(), + getAccounts()); } }; @@ -576,8 +583,6 @@ public class XmppConnectionService extends Service { statusListener.onStatusChanged(account); } } - - // TODO 3 remaining cases if (account.getStatus() == Account.STATUS_ONLINE) { long lastReceived = account.getXmppConnection().lastPaketReceived; long lastSent = account.getXmppConnection().lastPingSent; @@ -605,15 +610,9 @@ public class XmppConnectionService extends Service { + ": time out during connect reconnecting"); reconnectAccount(account, true); } else { - Log.d(LOGTAG, - "seconds since last connect:" - + ((SystemClock.elapsedRealtime() - account - .getXmppConnection().lastConnect) / 1000)); - Log.d(LOGTAG, - account.getJid() + ": status=" - + account.getStatus()); - // TODO notify user of ssl cert problem or auth problem - // or what ever + if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { + reconnectAccount(account, true); + } } // in any case. reschedule wakup call this.scheduleWakeupCall(PING_MAX_INTERVAL, true); @@ -676,7 +675,6 @@ public class XmppConnectionService extends Service { this.pingIntent, 0); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingPingIntent); - // Log.d(LOGTAG,"schedule ping in "+seconds+" seconds"); } else { long scheduledTime = this.pingIntent.getLongExtra("time", 0); if (scheduledTime < SystemClock.elapsedRealtime() @@ -687,7 +685,6 @@ public class XmppConnectionService extends Service { context, 0, this.pingIntent, 0); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingPingIntent); - // Log.d(LOGTAG,"reschedule old ping to ping in "+seconds+" seconds"); } } } else { @@ -729,11 +726,10 @@ public class XmppConnectionService extends Service { @Override public void onBind(Account account) { - databaseBackend.clearPresences(account); + databaseBackend.clearPresences(account); //contact presences account.clearPresences(); // self presences - if (account.getXmppConnection().hasFeatureRosterManagment()) { - updateRoster(account, null); - } + updateRoster(account, null); + sendPresence(account); connectMultiModeConversations(account); if (convChangedListener != null) { convChangedListener.onConversationListChanged(); @@ -829,16 +825,16 @@ public class XmppConnectionService extends Service { } } } - + private void resendMessage(Message message) { Account account = message.getConversation().getAccount(); MessagePacket packet = null; if (message.getEncryption() == Message.ENCRYPTION_NONE) { - packet = prepareMessagePacket(account, message,null); + packet = prepareMessagePacket(account, message, null); } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { packet = prepareMessagePacket(account, message, null); packet.setBody("This is an XEP-0027 encryted message"); - if (message.getEncryptedBody()==null) { + if (message.getEncryptedBody() == null) { markMessage(message, Message.STATUS_SEND_FAILED); return; } @@ -850,7 +846,7 @@ public class XmppConnectionService extends Service { packet.addChild("x", "jabber:x:encrypted").setContent( message.getBody()); } - if (packet!=null) { + if (packet != null) { account.getXmppConnection().sendMessagePacket(packet); markMessage(message, Message.STATUS_SEND); } @@ -1159,8 +1155,7 @@ public class XmppConnectionService extends Service { if (accountChangedListener != null) { accountChangedListener.onAccountListChangedListener(); } - UIHelper.showErrorNotification(getApplicationContext(), - getAccounts()); + UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); } public void deleteAccount(Account account) { @@ -1172,8 +1167,7 @@ public class XmppConnectionService extends Service { if (accountChangedListener != null) { accountChangedListener.onAccountListChangedListener(); } - UIHelper.showErrorNotification(getApplicationContext(), - getAccounts()); + UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); } public void setOnConversationListChangedListener( @@ -1394,16 +1388,15 @@ public class XmppConnectionService extends Service { contact.getAccount().getXmppConnection().sendPresencePacket(packet); } - public void sendPgpPresence(Account account, String signature) { + public void sendPresence(Account account) { PresencePacket packet = new PresencePacket(); packet.setAttribute("from", account.getFullJid()); - Element status = new Element("status"); - status.setContent("online"); - packet.addChild(status); - Element x = new Element("x"); - x.setAttribute("xmlns", "jabber:x:signed"); - x.setContent(signature); - packet.addChild(x); + String sig = account.getPgpSignature(); + if (sig!=null) { + packet.addChild("status").setContent("online"); + packet.addChild("x","jabber:x:signed").setContent(sig); + } + Log.d(LOGTAG,packet.toString()); account.getXmppConnection().sendPresencePacket(packet); } @@ -1427,7 +1420,6 @@ public class XmppConnectionService extends Service { this.tlsException = null; } - // TODO dont let thread sleep but schedule wake up public void reconnectAccount(final Account account, final boolean force) { new Thread(new Runnable() { @@ -1492,8 +1484,9 @@ public class XmppConnectionService extends Service { } return false; } - - public boolean markMessage(Conversation conversation, String uuid, int status) { + + public boolean markMessage(Conversation conversation, String uuid, + int status) { for (Message message : conversation.getMessages()) { if (message.getUuid().equals(uuid)) { markMessage(message, status); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 59c47fcf0..c3626ee11 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -722,12 +722,19 @@ public class ConversationActivity extends XmppActivity { encryptTextMessage(); } else if (requestCode == REQUEST_IMAGE_CAPTURE) { attachImageToConversation(getSelectedConversation(), null); + } else if (requestCode == REQUEST_RECORD_AUDIO) { + Log.d("xmppService",data.getData().toString()); + attachAudioToConversation(getSelectedConversation(),data.getData()); } else { Log.d(LOGTAG,"unknown result code:"+requestCode); } } } + private void attachAudioToConversation(Conversation conversation, Uri uri) { + + } + private void attachImageToConversation(Conversation conversation, Uri uri) { prepareImageToast = Toast.makeText(getApplicationContext(), getText(R.string.preparing_image), Toast.LENGTH_LONG); prepareImageToast.show(); diff --git a/src/eu/siacs/conversations/ui/EditAccount.java b/src/eu/siacs/conversations/ui/EditAccount.java index 8b1c0fa64..47930747b 100644 --- a/src/eu/siacs/conversations/ui/EditAccount.java +++ b/src/eu/siacs/conversations/ui/EditAccount.java @@ -51,27 +51,19 @@ public class EditAccount extends DialogFragment { final CheckBox registerAccount = (CheckBox) view .findViewById(R.id.edit_account_register_new); - final String okButtonDesc; - if (account != null) { jidText.setText(account.getJid()); password.setText(account.getPassword()); - Log.d("xmppService","mein debugger. account != null"); if (account.isOptionSet(Account.OPTION_REGISTER)) { registerAccount.setChecked(true); - builder.setTitle(getString(R.string.register_account)); - okButtonDesc = "Register"; passwordConfirm.setVisibility(View.VISIBLE); passwordConfirm.setText(account.getPassword()); } else { registerAccount.setVisibility(View.GONE); - builder.setTitle("Edit account"); - okButtonDesc = "Edit"; } - } else { - builder.setTitle("Add account"); - okButtonDesc = "Add"; } + builder.setTitle(R.string.account_settings); + registerAccount .setOnCheckedChangeListener(new OnCheckedChangeListener() { @@ -79,26 +71,19 @@ public class EditAccount extends DialogFragment { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - AlertDialog d = (AlertDialog) getDialog(); - Button positiveButton = (Button) d - .getButton(Dialog.BUTTON_POSITIVE); if (isChecked) { - d.setTitle(getString(R.string.register_account)); - positiveButton.setText("Register"); passwordConfirm.setVisibility(View.VISIBLE); confirmPwDesc.setVisibility(View.VISIBLE); } else { - d.setTitle("Add account"); passwordConfirm.setVisibility(View.GONE); - positiveButton.setText("Add"); confirmPwDesc.setVisibility(View.GONE); } } }); builder.setView(view); - builder.setNeutralButton("Cancel", null); - builder.setPositiveButton(okButtonDesc, null); + builder.setNeutralButton(R.string.cancel, null); + builder.setPositiveButton(R.string.save, null); return builder.create(); } @@ -114,7 +99,9 @@ public class EditAccount extends DialogFragment { String jid = jidEdit.getText().toString(); EditText passwordEdit = (EditText) d .findViewById(R.id.account_password); + EditText passwordConfirmEdit = (EditText) d.findViewById(R.id.account_password_confirm2); String password = passwordEdit.getText().toString(); + String passwordConfirm = passwordConfirmEdit.getText().toString(); CheckBox register = (CheckBox) d.findViewById(R.id.edit_account_register_new); String username; String server; @@ -123,9 +110,15 @@ public class EditAccount extends DialogFragment { username = parts[0]; server = parts[1]; } else { - jidEdit.setError("Invalid Jabber ID"); + jidEdit.setError(getString(R.string.invalid_jid)); return; } + if (register.isChecked()) { + if (!passwordConfirm.equals(password)) { + passwordConfirmEdit.setError(getString(R.string.passwords_do_not_match)); + return; + } + } if (account != null) { account.setPassword(password); account.setUsername(username); diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 1fe7cf131..02900ac8c 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -175,7 +175,7 @@ public abstract class XmppActivity extends Activity { @Override public void success() { xmppConnectionService.databaseBackend.updateAccount(account); - xmppConnectionService.sendPgpPresence(account, account.getPgpSignature()); + xmppConnectionService.sendPresence(account); if (conversation!=null) { conversation.setNextEncryption(Message.ENCRYPTION_PGP); } diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 6e55ebfec..58e110d6d 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -30,7 +30,6 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; -import org.json.JSONException; import org.xmlpull.v1.XmlPullParserException; import android.os.Bundle; @@ -88,6 +87,8 @@ public class XmppConnection implements Runnable { public long lastPingSent = 0; public long lastConnect = 0; public long lastSessionStarted = 0; + + private int attempt = 0; private static final int PACKET_IQ = 0; private static final int PACKET_MESSAGE = 1; @@ -113,6 +114,9 @@ public class XmppConnection implements Runnable { if ((nextStatus == Account.STATUS_OFFLINE)&&(account.getStatus() != Account.STATUS_CONNECTING)&&(account.getStatus() != Account.STATUS_ONLINE)&&(account.getStatus() != Account.STATUS_DISABLED)) { return; } + if (nextStatus == Account.STATUS_ONLINE) { + this.attempt = 0; + } account.setStatus(nextStatus); if (statusListener != null) { statusListener.onStatusChanged(account); @@ -123,6 +127,7 @@ public class XmppConnection implements Runnable { protected void connect() { Log.d(LOGTAG,account.getJid()+ ": connecting"); lastConnect = SystemClock.elapsedRealtime(); + this.attempt++; try { shouldAuthenticate = shouldBind = !account.isOptionSet(Account.OPTION_REGISTER); tagReader = new XmlReader(wakeLock); @@ -609,25 +614,10 @@ public class XmppConnection implements Runnable { }); } - private void sendInitialPresence() { - PresencePacket packet = new PresencePacket(); - packet.setAttribute("from", account.getFullJid()); - if (account.getKeys().has("pgp_signature")) { - try { - String signature = account.getKeys().getString("pgp_signature"); - packet.addChild("status").setContent("online"); - packet.addChild("x","jabber:x:signed").setContent(signature); - } catch (JSONException e) { - // - } - } - this.sendPresencePacket(packet); - } - private void sendBindRequest() throws IOException { IqPacket iq = new IqPacket(IqPacket.TYPE_SET); iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind").addChild("resource").setContent(account.getResource()); - this.sendIqPacket(iq, new OnIqPacketReceived() { + this.sendUnboundIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { String resource = packet.findChild("bind").findChild("jid") @@ -642,7 +632,6 @@ public class XmppConnection implements Runnable { EnablePacket enable = new EnablePacket(smVersion); tagWriter.writeStanzaAsync(enable); } - sendInitialPresence(); sendServiceDiscoveryInfo(account.getServer()); sendServiceDiscoveryItems(account.getServer()); if (bindListener !=null) { @@ -655,9 +644,8 @@ public class XmppConnection implements Runnable { if (this.streamFeatures.hasChild("session")) { Log.d(LOGTAG,account.getJid()+": sending deprecated session"); IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); - startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session"); //setContent("") - startSession.setId(nextRandomId()); - this.sendPacket(startSession, null); + startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session"); + this.sendUnboundIqPacket(startSession, null); } } @@ -757,6 +745,14 @@ public class XmppConnection implements Runnable { packet.setFrom(account.getFullJid()); this.sendPacket(packet, callback); } + + public void sendUnboundIqPacket(IqPacket packet, OnIqPacketReceived callback) { + if (packet.getId()==null) { + String id = nextRandomId(); + packet.setAttribute("id", id); + } + this.sendPacket(packet, callback); + } public void sendMessagePacket(MessagePacket packet) { this.sendPacket(packet, null); @@ -916,4 +912,14 @@ public class XmppConnection implements Runnable { Log.d(LOGTAG,"adding "+jid+" to pending subscriptions"); this.pendingSubscriptions.add(jid); } + + public int getTimeToNextAttempt() { + int interval = (int) (25 * Math.pow(1.5,attempt)); + int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000); + return interval - secondsSinceLast; + } + + public int getAttempt() { + return this.attempt; + } }