From 2a731731767b341af2785532c17bfa9ed71710d0 Mon Sep 17 00:00:00 2001 From: Erkan Date: Sun, 22 Mar 2015 20:09:53 +0100 Subject: Update french translation --- src/main/res/values-fr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 69440362..47c28517 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -427,4 +427,8 @@ Aucune application trouvée pour afficher la position Position Position reçue + + %d contact séléctionné + %d contacts séléctionnés + -- cgit v1.2.3 From e64049c4fc0f4514dee011a1f616ea4bdff1f16a Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Wed, 1 Apr 2015 12:14:05 +0200 Subject: Add toggle account-state switch Add a switch to AccountAdapter that allows self-contained enabling/disabling of accounts without the need to bring up the context-menu --- .../conversations/ui/ManageAccountActivity.java | 8 ++++ .../conversations/ui/adapter/AccountAdapter.java | 45 ++++++++++++++-------- src/main/res/layout/account_row.xml | 8 ++++ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java index b2d5ddfd..c7db94af 100644 --- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -168,6 +168,14 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda } } + public void onClickTglAccountState(Account account) { + if (account.isOptionSet(Account.OPTION_DISABLED)) { + enableAccount(account); + } else { + disableAccount(account); + } + } + private void publishAvatar(Account account) { Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index 29730914..5209aa12 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -5,6 +5,7 @@ import java.util.List; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.ManageAccountActivity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -12,6 +13,7 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Switch; public class AccountAdapter extends ArrayAdapter { @@ -24,7 +26,7 @@ public class AccountAdapter extends ArrayAdapter { @Override public View getView(int position, View view, ViewGroup parent) { - Account account = getItem(position); + final Account account = getItem(position); if (view == null) { LayoutInflater inflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -34,21 +36,32 @@ public class AccountAdapter extends ArrayAdapter { jid.setText(account.getJid().toBareJid().toString()); TextView statusView = (TextView) view.findViewById(R.id.account_status); ImageView imageView = (ImageView) view.findViewById(R.id.account_image); - imageView.setImageBitmap(activity.avatarService().get(account, - activity.getPixel(48))); - statusView.setText(getContext().getString(account.getStatus().getReadableId())); - switch (account.getStatus()) { - case ONLINE: - statusView.setTextColor(activity.getOnlineColor()); - break; - case DISABLED: - case CONNECTING: - statusView.setTextColor(activity.getSecondaryTextColor()); - break; - default: - statusView.setTextColor(activity.getWarningTextColor()); - break; - } + imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); + statusView.setText(getContext().getString(account.getStatus().getReadableId())); + switch (account.getStatus()) { + case ONLINE: + statusView.setTextColor(activity.getOnlineColor()); + break; + case DISABLED: + case CONNECTING: + statusView.setTextColor(activity.getSecondaryTextColor()); + break; + default: + statusView.setTextColor(activity.getWarningTextColor()); + break; + } + final Switch tglAccountState = (Switch) view.findViewById(R.id.tgl_account_status); + boolean isDisabled = (account.getStatus() == Account.State.DISABLED) ? true : false; + tglAccountState.setChecked(!isDisabled); + tglAccountState.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (activity instanceof ManageAccountActivity) { + ((ManageAccountActivity) activity).onClickTglAccountState(account); + tglAccountState.toggle(); + } + } + }); return view; } } diff --git a/src/main/res/layout/account_row.xml b/src/main/res/layout/account_row.xml index 60b69090..1cd29d59 100644 --- a/src/main/res/layout/account_row.xml +++ b/src/main/res/layout/account_row.xml @@ -41,4 +41,12 @@ android:textStyle="bold" /> + + \ No newline at end of file -- cgit v1.2.3 From db74cb52c417a99005f86d49804fdb512ee5c99f Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Wed, 1 Apr 2015 12:22:18 +0200 Subject: Fix OTR-Error messages Send out OTR-Errors on unreadableMessageReceived() as well, not only on messageFromAnotherInstanceReceived --- .../eu/siacs/conversations/crypto/OtrEngine.java | 38 +++++++++++++--------- .../conversations/generator/MessageGenerator.java | 4 +-- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 20427d7b..263f6089 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -202,20 +202,7 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { @Override public void messageFromAnotherInstanceReceived(SessionID session) { - try { - Jid jid = Jid.fromSessionID(session); - Conversation conversation = mXmppConnectionService.find(account, jid); - String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId(); - if (id != null) { - MessagePacket packet = mXmppConnectionService.getMessageGenerator().generateOtrError(jid,id); - packet.setFrom(account.getJid()); - mXmppConnectionService.sendMessagePacket(account,packet); - Log.d(Config.LOGTAG,packet.toString()); - Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": unreadable OTR message in "+conversation.getName()); - } - } catch (InvalidJidException e) { - return; - } + sendOtrErrorMessage(session, "Message from another OTR-instance received"); } @Override @@ -267,9 +254,28 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { } @Override - public void unreadableMessageReceived(SessionID arg0) throws OtrException { + public void unreadableMessageReceived(SessionID session) throws OtrException { Log.d(Config.LOGTAG,"unreadable message received"); - throw new OtrException(new Exception("unreadable message received")); + sendOtrErrorMessage(session, "You sent me an unreadable OTR-encrypted message"); + } + + public void sendOtrErrorMessage(SessionID session, String errorText) { + try { + Jid jid = Jid.fromSessionID(session); + Conversation conversation = mXmppConnectionService.find(account, jid); + String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId(); + if (id != null) { + MessagePacket packet = mXmppConnectionService.getMessageGenerator() + .generateOtrError(jid, id, errorText); + packet.setFrom(account.getJid()); + mXmppConnectionService.sendMessagePacket(account,packet); + Log.d(Config.LOGTAG,packet.toString()); + Log.d(Config.LOGTAG,account.getJid().toBareJid().toString() + +": unreadable OTR message in "+conversation.getName()); + } + } catch (InvalidJidException e) { + return; + } } @Override diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 8f6a90b9..a60c5613 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -172,7 +172,7 @@ public class MessageGenerator extends AbstractGenerator { return receivedPacket; } - public MessagePacket generateOtrError(Jid to, String id) { + public MessagePacket generateOtrError(Jid to, String id, String errorText) { MessagePacket packet = new MessagePacket(); packet.setType(MessagePacket.TYPE_ERROR); packet.setAttribute("id",id); @@ -181,7 +181,7 @@ public class MessageGenerator extends AbstractGenerator { error.setAttribute("code","406"); error.setAttribute("type","modify"); error.addChild("not-acceptable","urn:ietf:params:xml:ns:xmpp-stanzas"); - error.addChild("text").setContent("unreadable OTR message received"); + error.addChild("text").setContent("?OTR Error:" + errorText); return packet; } } -- cgit v1.2.3 From 64d6a2970e687c4d1931fa6ccb4a9917a61ed1d5 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 1 Apr 2015 20:26:28 +0200 Subject: pulled translations from transifex --- src/main/res/values-de/strings.xml | 12 +- src/main/res/values-es/strings.xml | 4 + src/main/res/values-eu/strings.xml | 4 + src/main/res/values-ja/strings.xml | 433 +++++++++++++++++++++++++++++++++++++ src/main/res/values-sk/strings.xml | 5 + src/main/res/values-sr/strings.xml | 9 +- src/main/res/values-sv/strings.xml | 14 +- 7 files changed, 466 insertions(+), 15 deletions(-) create mode 100644 src/main/res/values-ja/strings.xml diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 0dd9f401..b8266182 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -121,13 +121,13 @@ Annehmen Ein unbekannter Fehler ist aufgetreten Online-Status - Erlaube neu hinzugefügten Kontakten deinen online-Status zu sehen und frage um Erlaubnis, ihren sehen zu dürfen + Erlaube neu hinzugefügten Kontakten meinen Online-Status zu sehen und frage um Erlaubnis, ihren sehen zu dürfen Abonnements Dein Konto Schlüssel - Anwesenheitsbenachrichtigungen senden - Empfange Anwesenheitsbenachrichtigungen - Frage um Erlaubnis, Anwesenheitsbenachrichtigungen sehen zu dürfen + Online-Status senden + Online-Status empfangen + Online-Status anfragen Bild auswählen Bild aufnehmen Erlaube Statusanfrage vorab @@ -255,12 +255,12 @@ Konferenz ist passwortgeschützt Passwort eingeben Fehlender Online-Status vom Kontakt - Bitte erst Anwesenheitsbenachrichtigungen vom Kontakt anfordern.\n\n + Bitte erst Online-Status vom Kontakt anfragen.\n\nDies wird verwendet, um festzustellen, welche Client(s) der Kontakt benutzt. Jetzt anfordern Fingerabdruck löschen Soll dieser Fingerabdruck gelöscht werden? Ignorieren - Achtung: Es kann zu unerwarteten Problemen führen, dies ohne gegenseitige Anwesenheitsbenachrichtigungen abzusenden.\n\nBitte die Online-Status-Abonnements in den Kontaktdetails prüfen. + Achtung: Ohne gegenseitig den Online-Status zu kennen, kann es zu unerwarteten Problemen kommen.\n\nBitte die Einstellungen in den Kontakt-Details prüfen. Verschlüsselungs-Einstellungen Ende-zu-Ende-Verschlüsselung erzwingen Nachrichten immer verschlüsseln (außer für Konferenzen) diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 639eddfa..44d8abb2 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -427,4 +427,8 @@ No se ha encontrado ninguna aplicación para mostrar la ubicación Ubicación Ubicación recibida + + Seleccionado %d contacto + Seleccionados %d contactos + diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 4d81c1bf..b6d1fa3c 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -427,4 +427,8 @@ Kokapena erakutsi dezakeen aplikaziorik ez da aurkitu Kokapena Kokapena jaso da + + Hautatu kontaktu %d + Hautatu %d kontaktu + diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml new file mode 100644 index 00000000..baffa088 --- /dev/null +++ b/src/main/res/values-ja/strings.xml @@ -0,0 +1,433 @@ + + + 設定 + 新しい会話 + アカウントの管理 + この会話を終了 + 連絡先の詳細 + 会議の詳細 + 安全に会話 + アカウントを追加 + 名前の編集 + 電話帳に追加 + 名簿から削除 + 連絡先をブロック + 連絡先のブロックを解除 + ドメインをブロック + ドメインのブロックを解除 + アカウントの管理 + 設定 + 会議の詳細 + 連絡先の詳細 + 会話で共有 + 会話の開始 + 連絡先の選択 + ブロックリスト + ちょうど今 + 1 分前 + %d 分前 + 未読の会話 + 送信中… + メッセージを復号しています。しばらくお待ちください… + ニックネームは既に使用されています + 管理者 + オーナー + モデレーター + 参加者 + ビジター + あなたの名簿から %s を削除しますか? この連絡先と関連した会話は削除されません。 + %s からあなたに送信されるメッセージをブロックしますか? + %s のブロックを解除し、あなたにメッセージを送信できるようにしますか? + %s からの連絡をすべてブロックしますか? + %s からの連絡をすべてブロック解除しますか? + 連絡先をブロックしました + ブックマークとして %s を削除しますか? このブックマークに関連した会話は削除されません。 + サーバーに新しいアカウントを登録 + サーバーのパスワードを変更 + …で共有 + 会話を開始 + 連絡先を招待 + 連絡先 + キャンセル + 設定 + 追加 + 編集 + 削除 + ブロック + ブロックを解除 + 保存 + OK + Conversations がクラッシュしました + Conversations の継続的な開発を支援するために、スタックトレースをお送りください。\n警告: あなたのXMPPアカウントを使用して、開発者にスタックトレースを送信します。 + 今すぐ送信 + 今後表示しない + アカウントに接続できません + 複数のアカウントに接続できません + ここをタッチして、アカウントの管理 + 添付ファイル + 連絡先が名簿にありません。追加しますか? + 連絡先を追加 + 配信に失敗しました + 拒否されました + 転送用画像の準備中 + 履歴をクリア + 会話履歴をクリア + この会話のすべてのメッセージを削除しますか?\n\n警告: これは、他のデバイスやサーバーに保存されているメッセージには影響しません。 + メッセージを削除 + その後、この会話を終了 + 連絡する参加を選択 + プレーンテキストを送信 + OTR 暗号化メッセージを送信 + OpenPGP 暗号化メッセージを送信 + あなたのニックネームが変更されました + 画像のダウンロード + 暗号化されていない送信 + 復号化に失敗しました。おそらく秘密鍵が正しくないようです。 + OpenKeychain + Conversations は OpenKeychain と呼ばれるサードパーティのアプリを利用して、メッセージの暗号化および復号化、そしてあなたの公開鍵を管理します。\n\nOpenKeychain は GPLv3 ライセンスの下で、F-Droid および Google Play から利用可能です。\n\n(後で Conversations を再起動してください。) + 再起動 + インストール + 依頼中… + 待機中… + OpenPGP の鍵はありません + 連絡先が公開鍵を通知しないため、Conversations はあなたのメッセージを暗号化することができません。\n\n連絡先に OpenPGP をセットアップするように依頼してください。 + OpenPGP の鍵はありません + 連絡先が公開鍵を通知しないため、Conversations はあなたのメッセージを暗号化することができません。\n\n連絡先に OpenPGP をセットアップするように依頼してください。 + 暗号化されたメッセージを受信しました。タッチすると、表示および復号化します。 + 全般 + XMPP リソース + 自分自身を識別するこのクライアントの名前 + ファイルを受取 + 自動的に小さいファイルを受取… + 通知設定 + 通知 + 新しいメッセージが到着したときに通知します + 振動 + 新しいメッセージが到着したときに振動もします + サウンド + 通知で着信音を再生します + 会議通知 + 新しい会議メッセージが到着したとき、ハイライト表示ではなく、常に通知します + 通知猶予期間 + カーボンコピーを受信した後、短時間、通知を無効にします + 詳細オプション + クラッシュレポートを送信しない + スタックトレースを送信することで、あなたは Conversations の継続的な開発を支援しています + メッセージの確認 + あなたがメッセージを受け取って読んだことを、連絡先に知らせます + UI オプション + OpenKeychain がエラーを報告しました + ファイルの復号化中に I/O エラー + 受付 + エラーが発生しました + 参加アップデートの権限を付与 + 事前に、作成した連絡先に対して権限を付与して、参加のサブスクリプションを求めます + サブスクリプション + あなたのアカウント + + 参加アップデートを送信 + 参加アップデートを受信 + 参加アップデートを問合せ + 写真の選択 + 写真の撮影 + 事前にサブスクリプション要求を許可する + 選択したファイルは画像ではありません + 画像ファイルの変換中にエラー + ファイルが見つかりません + 一般的な I/O エラー。おそらく空き容量がなくなっていませんか? + 選択した画像ファイルは、読み取りに必要なアクセス権がありません。\n\n別のファイルマネージャを使用して、画像を選択してください。 + 不明 + 一時的に無効 + オンライン + 接続中\u2026 + オフライン + 許可されていません + サーバーが見つかりません + 接続エラー + 登録に失敗しました + ユーザー名はすでに使用されています + 登録が完了しました + サーバーが登録をサポートしていません + セキュリティ エラー + 互換性のないサーバー + プレーンテキスト + OTR + OpenPGP + アカウントの編集 + アカウントを削除 + 一時的に無効にする + アバターを公開 + OpenPGP 公開鍵を公開 + アカウントを有効にする + よろしいですか? + アカウントを削除するとあなたの会話履歴がすべて失われます + 音声を録音 + Jabber ID + パスワード + username@example.com + パスワードを確認 + パスワード + パスワードを確認 + パスワードが一致しません + これは有効な Jabber ID ではありません + メモリ不足です。画像が大きすぎます + 電話の連絡先リストに %s を追加しますか? + オンライン + 自由にチャットできます + 離席中 + 長時間離席中 + じゃましないで + オフライン + 会議 + 他のメンバー + サーバー情報 + XEP-0313: メッセージ アーカイブ管理 + XEP-0280: メッセージ カーボン + XEP-0352: クライアント状態表示 + XEP-0191: ブロッキング コマンド + XEP-0237: 名簿バージョニング + XEP-0198: ストリーム管理 + XEP-0163: 個人イベントプロトコル (アバター) + 利用可能 + 利用不可 + 公開鍵の通知がありません + ちょうど今会いました + 1 分前に会いました + %d 分前に会いました + 1 時間前に会いました + %d 時間前に会いました + 1 日前に会いました + %d 日前に会いました + 会ったことはありません + 暗号化されたメッセージ。復号化するには OpenKeychain をインストールしてください。 + 不明な OTR フィンガープリント + OpenPGP 暗号化されたメッセージが見つかりました + 受信に失敗しました + あなたのフィンガープリント + OTR フィンガープリント + 検証 + 復号化 + 会議 + 検索 + 連絡先を作成 + 会議に参加 + 連絡先を削除 + 連絡先の詳細を表示 + 連絡先をブロック + 連絡先のブロックを解除 + 作成 + 連絡先はすでに存在します + 参加 + 会議アドレス + room@conference.example.com + ブックマークとして保存 + ブックマークを削除 + このブックマークはすでに存在します + あなた + 会議の件名を編集 + 会議が見つかりません + 退出 + 連絡先があなたを連絡先リストに追加しました + 戻りを追加 + %s はここまで読みました + 公開 + アバターをタッチしてギャラリーから画像を選択します + ご注意ください: あなたの参加アップデートを登録している人は、誰でもこの絵を見ることができます。 + 公開中… + サーバーがあなたの公開を拒否しました + 写真の変換中に、何か問題が発生しました + ディスクにアバターを保存できませんでした + (または長押しするとデフォルトに戻します) + ご利用のサーバーは、アバターの公開をサポートしていません + ささやいた + %s に + プライベートメッセージを %s に送信 + 接続 + このアカウントはすでに存在します + 次へ + 現在のセッションが確立 + 追加情報 + スキップ + 通知を無効にする + この会話の通知を無効にします + 通知を無効にしました + 有効 + 会議はパスワードが必要です + パスワードを入力してください + 連絡先からの参加アップデートがありません + 最初に連絡先から参加アップデートを要求してください。\n\nこれは、連絡先が何のクライアントを使用しているかを決めるために使用されます。 + 今すぐ要求 + フィンガープリントを削除 + このフィンガープリントを削除してもよろしいですか? + 無視 + 警告: 相互の参加アップデートなしにこれを送信すると、予期しない問題が発生する可能性があります。\n\nあなたの参加サブスクリプションを検証するために、連絡先の詳細に移動します。 + 暗号化設定 + 強制的にエンドツーエンド暗号化を使用する + 常に暗号化されたメッセージを送信します (会議を除く) + 暗号化されたメッセージを保存しない + 警告: これはメッセージの損失につながる可能性があります + 上級者オプション + ご利用は注意してください + Conversations について + ビルドおよびライセンス情報 + 消音時間 + 開始時間 + 終了時間 + 消音時間を有効にする + 消音時間の間、通知は無音になります + フォントサイズを拡大 + アプリ全体にわたって大きなフォントサイズを使用します + 送信ボタンにステータスを示す + 要求メッセージの受信 + サポートされている場合、受信したメッセージに緑色のチェックマークが付きます + 送信ボタンに連絡先ステータスを示す色が付きます + その他 + 会議名 + 会議を識別するために JID の代わりにルームのテーマを使用します + OTR フィンガープリントをクリップボードにコピーしました! + あなたはこの会議から禁止されています + この会議はメンバーのみです + あなたはこの会議からキックされました + アカウント %s を使用 + HTTP ホストの画像を確認中 + 画像ファイルは削除されました + 接続されていません。後でもう一度お試しください + 画像ファイルのサイズを確認 + メッセージオプション + テキストをコピー + 元の URL をコピー + 再送 + 画像 URL + メッセージテキスト + URL をクリップボードにコピーしました + メッセージをクリップボードにコピーしました + 画像の転送に失敗しました + QR コードをスキャン + QR コードを表示 + ブロックリストを表示 + アカウントの詳細 + OTR を検証 + リモート フィンガープリント + スキャン + (または電話をタッチ) + ソーシャリスト ミリオネア プロトコル + ヒントまたは質問 + 共有の秘密 + 確認 + 実行中 + 応答 + 失敗しました + 秘密が一致しません + 再度実行してください + 完了 + 検証しました! + 連絡先が SMP 検証を要求しました + 有効な OTR セッションが見つかりません! + Conversations + サービスをフォアグラウンドに保持 + オペレーティングシステムが接続を切断するのを防止します + ファイルの選択 + %1$s 受信中 (%2$d%% 完了) + %s のダウンロード + ファイル + %s を開く + 送信中 (%1$d%% 完了) + 転送用ファイルの準備中 + %s ダウンロード依頼中 + 転送をキャンセル + ファイル転送に失敗しました + ファイルを削除しました + ファイルを開くアプリケーションが見つかりません + フィンガープリントを検証できません + 手動で検証 + 連絡先の OTR フィンガープリントを検証してもよろしいですか? + ダイナミック タグを表示 + 連絡先の下に、読み取り専用タグを表示します + 通知を有効にする + …と会議を作成 + 会議サーバーが見つかりません + 会議の作成に失敗しました! + 会議を作成しました! + 秘密を受取ました! + リセット + アカウント アバター + OTR フィンガープリントをクリップボードにコピーしました + サーバーから履歴を取得中 + サーバーにこれ以上履歴はありません + アップデート中… + パスワードを変更しました! + パスワードを変更できません + メッセージを送信して、暗号化されたチャットを開始します + 質問をたずねる + あなたと連絡先が、(内輪の冗談や、最後に会って食べた昼食などの) 他の誰も知らない共通の秘密を持っている場合、お互いのフィンガープリントを検証するために、その秘密を使用することができます。\n\nあなたはヒントまたは質問を提供して、連絡先は大文字と小文字を区別した答えで応答します。 + 連絡先は共有の秘密であなたにチャレンジして、あなたのフィンガープリントを検証したいと思います。連絡先は秘密に対して、次のヒントまたは質問を提供しました。 + あなたのヒントは空にできません。 + あなたの共有の秘密は空にできません。 + 慎重に、連絡先のフィンガープリントと、以下に表示されるフィンガープリントを比較してください。\nこれを交換するためには、暗号化されたメールや、電話のような信頼できる形式の通信を使用することができます。 + パスワードの変更 + 現在のパスワード + 新しいパスワード + パスワードは空にできません + すべてのアカウントを有効にする + すべてのアカウントを無効にする + アクションを実行... + 所属なし + 役割なし + 追放 + メンバー + 詳細モード + メンバーシップを付与 + メンバーシップを取消 + 管理者権限を付与 + 管理者権限を取消 + 会議から削除 + %s の所属を変更できません + 会議から禁止 + 公開の会議から %s を削除しようとしています。そのための唯一の方法は、永久にそのユーザーを禁止することです。 + 今すぐ禁止 + %s の役割を変更できません + 公開アクセス可能な会議 + プライベート、メンバーのみの会議 + 会議オプション + プライベート (メンバーのみ) + 匿名でない + 会議オプションを変更しました! + 会議オプションを変更できません + なし + 30 分 + 1 時間 + 2 時間 + 8 時間 + 通知があるまで + 入力オプション + Enter は送信 + Enter キーをメッセージの送信に使用します + Enter キーを表示 + 絵文字キーを Enter キーに変更 + オーディオ + ビデオ + 画像 + PDF 文書 + Android アプリ + 連絡先 + %s を受信しました + フォアグラウンド サービスを無効にする + タッチして Conversations を開く + アバターを公開しました! + %s の送信中 + %s の依頼中 + オフラインを非表示にする + アカウントを無効にする + %s は入力中... + %s は入力を停止しました + 入力中通知 + あなたが新しいメッセージを書いている時に、連絡先に知らせます + 位置を送信 + 位置を表示 + 位置を表示するアプリケーションが見つかりません + 位置 + 位置を受信しました + + %d 連絡先を選択 + + diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index bca8d3d2..cb45b4aa 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -422,4 +422,9 @@ %s prestal písať Upozornenia pri písaní Upozorniť kontakt, keď píšete novú správu + Poslať polohu + Zobraziť polohu + Nenašla sa aplikácia na zobrazenie polohy + Poloha + Prijatá poloha diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 479889b7..052463c8 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -302,8 +302,8 @@ УРЛ је копиран на клипборд Порука је копирана на клипборд Пренос слике није успео - Очитај бар-код - Прикажи бар-код + Очитај бар-кôд + Прикажи бар-кôд Прикажи списак блокираних Детаљи налога Овери ОТР @@ -427,4 +427,9 @@ Нема апликације за приказ локације Локација Примљена локација + + Изабери %d контакт + Изабери %d контакта + Изабери %d контаката + diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index 69a66808..874de244 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -36,10 +36,10 @@ Deltagare Besökare Vill du ta bort %s från din kontaktlista? Konversationer associerade med denna kontakt kommer inte tas bort. - Vill du blockera %s från att skicka dig meddelanden + Vill du blockera %s från att skicka dig meddelanden? Vill du avblockera %s och tillåta denne att skicka dig meddelanden? - Blockera alla kontakter från %s - Avblockera alla kontakter från %s + Blockera alla kontakter från %s? + Avblockera alla kontakter från %s? Kontakt blockerad Vill du ta bort %s som bokmärke? Konversationer associerade med detta bokmärke kommer inte tas bort. Registrera nytt konto på servern @@ -74,7 +74,7 @@ Rensa konversationshistorik Vill du ta bort alla meddelanden i denna konversation?\n\nVarning: Detta kommer inte påverka meddelanden lagrade på andra enheter eller servrar. Ta bort meddelanden - Avsluta denna konversation efter + Avsluta sedan denna konversation Välj tillgänglighet till kontakt Skicka meddelande i klartext Skicka OTR-krypterat meddelande @@ -82,9 +82,9 @@ Ditt nick har ändrats Ladda ner bild Skicka okrypterat - Avkryptering gick fel. Du kanske inte har rätt privat nyckel. + Avkryptering misslyckades. Du har kanske kanske inte rätt privat nyckel. OpenKeychain - Conversations använder en tredjeparts applikation som heter OpenKeychain för att kryptera och avkryptera meddelanden och hantera dina publika nycklar.\n\nOpenKeychain är licensierat under GPLv3 och tillgängligt på F-Droid och Google Play.\n\n(Starta om Conversations efter.) + Conversations använder en tredjeparts-applikation som heter OpenKeychain för att kryptera och avkryptera meddelanden och hantera dina publika nycklar.\n\nOpenKeychain är licensierad under GPLv3 och tillgänglig på F-Droid och Google Play.\n\n(Starta om Conversations efter installation.) Starta om Installera erbjuder… @@ -229,7 +229,7 @@ Lämna Kontakten lade till dig i sin kontaktlista Addera tillbaka - %s har läst fram hit + %s har läst hit Publicera Tryck på avatarbild för att välja en bild från bildgalleriet Notera: Alla som kan se dina tillgänglighetsuppdateringar kommer se denna bild. -- cgit v1.2.3 From b7b87e1a8d3c17f49eb9f9d5434224d38afabb24 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 1 Apr 2015 23:45:46 +0200 Subject: do not overlap account title and switch --- src/main/res/layout/account_row.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/res/layout/account_row.xml b/src/main/res/layout/account_row.xml index 1cd29d59..94c59111 100644 --- a/src/main/res/layout/account_row.xml +++ b/src/main/res/layout/account_row.xml @@ -20,7 +20,10 @@ android:layout_centerVertical="true" android:layout_toRightOf="@+id/account_image" android:orientation="vertical" - android:paddingLeft="8dp" > + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:layout_toLeftOf="@+id/tgl_account_status" + android:layout_toStartOf="@+id/tgl_account_status"> Date: Fri, 3 Apr 2015 00:06:37 +0200 Subject: Enable end-conversation by swipe gesture Add EnhancedListView library de.timroes.android:EnhancedListView:0.3.4 to enable swipe-out for ListViews Re-enable selectableItemBackground Dont end selectedConversation on swipe Call mConversationFragment.reinit() instead. Add separate undo string for swipe MUC. Add blacklistedConversation for undo swipe Update title_undo_swipe_* strings Fix undo(), rename blacklistedConversation Fix discardUndo(); re-init selectedConversation maintain scroll position after undo clear notification when dismissing a conversation modified / simplified maintain scroll position code simplify handling of selectedConversation change undo_muc string, remove notifyDataSetChanged() --- build.gradle | 1 + .../services/XmppConnectionService.java | 1 + .../conversations/ui/ConversationActivity.java | 103 +++++++++++++-- .../fragment_conversations_overview.xml | 2 +- src/main/res/layout/conversation_list_row.xml | 138 ++++++++++++--------- .../res/layout/fragment_conversations_overview.xml | 2 +- src/main/res/values-de/strings.xml | 2 + src/main/res/values-v21/dimens.xml | 4 + src/main/res/values/strings.xml | 3 + 9 files changed, 185 insertions(+), 71 deletions(-) create mode 100644 src/main/res/values-v21/dimens.xml diff --git a/build.gradle b/build.gradle index 8f7bb914..cdbb5a98 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,7 @@ dependencies { compile 'com.google.zxing:core:3.1.0' compile 'com.google.zxing:android-integration:3.1.0' compile 'de.measite.minidns:minidns:0.1.3' + compile 'de.timroes.android:EnhancedListView:0.3.4' } android { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ca182867..9badbbd8 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1129,6 +1129,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void archiveConversation(Conversation conversation) { + getNotificationService().clear(conversation); conversation.setStatus(Conversation.STATUS_ARCHIVED); conversation.setNextEncryption(-1); synchronized (this.conversations) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 82afda07..29308cc5 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -22,12 +22,12 @@ import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.CheckBox; -import android.widget.ListView; import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.Toast; import net.java.otr4j.session.SessionStatus; +import de.timroes.android.listview.EnhancedListView; import java.util.ArrayList; import java.util.List; @@ -76,8 +76,9 @@ public class ConversationActivity extends XmppActivity private View mContentView; private List conversationList = new ArrayList<>(); + private Conversation swipedConversation = null; private Conversation mSelectedConversation = null; - private ListView listView; + private EnhancedListView listView; private ConversationFragment mConversationFragment; private ArrayAdapter listAdapter; @@ -156,7 +157,7 @@ public class ConversationActivity extends XmppActivity transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation"); transaction.commit(); - listView = (ListView) findViewById(R.id.list); + listView = (EnhancedListView) findViewById(R.id.list); this.listAdapter = new ConversationAdapter(this, conversationList); listView.setAdapter(this.listAdapter); @@ -178,6 +179,73 @@ public class ConversationActivity extends XmppActivity openConversation(); } }); + + listView.setDismissCallback(new EnhancedListView.OnDismissCallback() { + + @Override + public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) { + + final int index = listView.getFirstVisiblePosition(); + View v = listView.getChildAt(0); + final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop()); + + swipedConversation = listAdapter.getItem(position); + listAdapter.remove(swipedConversation); + swipedConversation.markRead(); + xmppConnectionService.getNotificationService().clear(swipedConversation); + + final boolean formerlySelected = (getSelectedConversation() == swipedConversation); + if (position == 0 && listAdapter.getCount() == 0) { + endConversation(swipedConversation, false, true); + return null; + } else if (formerlySelected) { + setSelectedConversation(listAdapter.getItem(0)); + ConversationActivity.this.mConversationFragment + .reInit(getSelectedConversation()); + } + + return new EnhancedListView.Undoable() { + + @Override + public void undo() { + listAdapter.insert(swipedConversation, position); + if (formerlySelected) { + setSelectedConversation(swipedConversation); + ConversationActivity.this.mConversationFragment + .reInit(getSelectedConversation()); + } + swipedConversation = null; + listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top); + } + + @Override + public void discard() { + if (!swipedConversation.isRead() + && swipedConversation.getMode() == Conversation.MODE_SINGLE) { + swipedConversation = null; + return; + } + endConversation(swipedConversation, false, false); + swipedConversation = null; + } + + @Override + public String getTitle() { + if (swipedConversation.getMode() == Conversation.MODE_MULTI) { + return getResources().getString(R.string.title_undo_swipe_out_muc); + } else { + return getResources().getString(R.string.title_undo_swipe_out_conversation); + } + } + }; + } + }); + listView.enableSwipeToDismiss(); + listView.setSwipingLayout(R.id.swipeable_item); + listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP); + listView.setUndoHideDelay(3000); + listView.setRequireTouchBeforeDismiss(false); + mContentView = findViewById(R.id.content_view_spl); if (mContentView == null) { mContentView = findViewById(R.id.content_view_ll); @@ -204,6 +272,7 @@ public class ConversationActivity extends XmppActivity @Override public void onPanelClosed(View arg0) { + listView.discardUndo(); openConversation(); } @@ -485,13 +554,21 @@ public class ConversationActivity extends XmppActivity } public void endConversation(Conversation conversation) { - showConversationsOverview(); + endConversation(conversation, true, true); + } + + public void endConversation(Conversation conversation, boolean showOverview, boolean reinit) { + if (showOverview) { + showConversationsOverview(); + } xmppConnectionService.archiveConversation(conversation); - if (conversationList.size() > 0) { - setSelectedConversation(conversationList.get(0)); - this.mConversationFragment.reInit(getSelectedConversation()); - } else { - setSelectedConversation(null); + if (reinit) { + if (conversationList.size() > 0) { + setSelectedConversation(conversationList.get(0)); + this.mConversationFragment.reInit(getSelectedConversation()); + } else { + setSelectedConversation(null); + } } } @@ -744,6 +821,7 @@ public class ConversationActivity extends XmppActivity @Override public void onPause() { + listView.discardUndo(); super.onPause(); this.mActivityPaused = true; if (this.xmppConnectionServiceBound) { @@ -1013,6 +1091,13 @@ public class ConversationActivity extends XmppActivity public void updateConversationList() { xmppConnectionService .populateWithOrderedConversations(conversationList); + if (swipedConversation != null) { + if (swipedConversation.isRead()) { + conversationList.remove(swipedConversation); + } else { + listView.discardUndo(); + } + } listAdapter.notifyDataSetChanged(); } diff --git a/src/main/res/layout-w960dp/fragment_conversations_overview.xml b/src/main/res/layout-w960dp/fragment_conversations_overview.xml index 2744f38e..50039c03 100644 --- a/src/main/res/layout-w960dp/fragment_conversations_overview.xml +++ b/src/main/res/layout-w960dp/fragment_conversations_overview.xml @@ -12,7 +12,7 @@ android:background="@color/primarybackground" android:orientation="vertical" > - + - + - + - + - + - + - - + - - + - \ No newline at end of file + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_conversations_overview.xml b/src/main/res/layout/fragment_conversations_overview.xml index 69570028..24c653ae 100644 --- a/src/main/res/layout/fragment_conversations_overview.xml +++ b/src/main/res/layout/fragment_conversations_overview.xml @@ -10,7 +10,7 @@ android:background="@color/primarybackground" android:orientation="vertical" > - Keine App für die Standort-Anzeige gefunden Standort Standort empfangen + Unterhaltung beendet + Konferenz verlassen %d Kontakt ausgewählt %d Kontakte ausgewählt diff --git a/src/main/res/values-v21/dimens.xml b/src/main/res/values-v21/dimens.xml new file mode 100644 index 00000000..8bc8f3f7 --- /dev/null +++ b/src/main/res/values-v21/dimens.xml @@ -0,0 +1,4 @@ + + + 63dp + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index af56c014..50e9d9e4 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -296,6 +296,7 @@ \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) \n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0) \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) + \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0) Quiet Hours Start time @@ -454,6 +455,8 @@ No application found to display location Location Received location + Conversation closed + Left conference Select %d contact Select %d contacts -- cgit v1.2.3 From 332fe0fd194a80501cf935f22faed645f3032b57 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 9 Apr 2015 12:46:54 +0200 Subject: don't resume old session when changing resource --- src/main/java/eu/siacs/conversations/entities/Account.java | 14 ++++++++++---- .../siacs/conversations/generator/PresenceGenerator.java | 7 +++++++ .../conversations/services/XmppConnectionService.java | 5 +++++ .../java/eu/siacs/conversations/ui/SettingsActivity.java | 12 +++++++++--- .../java/eu/siacs/conversations/xmpp/XmppConnection.java | 4 ++++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 2bc2c954..fe103094 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -229,11 +229,17 @@ public class Account extends AbstractEntity { return jid.getResourcepart(); } - public void setResource(final String resource) { - try { - jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource); - } catch (final InvalidJidException ignored) { + public boolean setResource(final String resource) { + final String oldResource = jid.getResourcepart(); + if (oldResource == null || !oldResource.equals(resource)) { + try { + jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource); + return true; + } catch (final InvalidJidException ignored) { + return true; + } } + return false; } public Jid getJid() { diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java index 1e896724..526005f3 100644 --- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java @@ -54,4 +54,11 @@ public class PresenceGenerator extends AbstractGenerator { } return packet; } + + public PresencePacket sendOfflinePresence(Account account) { + PresencePacket packet = new PresencePacket(); + packet.setFrom(account.getJid()); + packet.setAttribute("type","unavailable"); + return packet; + } } \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9badbbd8..669ad62c 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1701,6 +1701,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } } + sendOfflinePresence(account); } account.getXmppConnection().disconnect(force); } @@ -2261,6 +2262,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa sendPresencePacket(account, mPresenceGenerator.sendPresence(account)); } + public void sendOfflinePresence(final Account account) { + sendPresencePacket(account, mPresenceGenerator.sendOfflinePresence(account)); + } + public MessageGenerator getMessageGenerator() { return this.mMessageGenerator; } diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 39e215f2..e3cb2ee7 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.Locale; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.xmpp.XmppConnection; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; @@ -63,9 +64,14 @@ public class SettingsActivity extends XmppActivity implements .toLowerCase(Locale.US); if (xmppConnectionServiceBound) { for (Account account : xmppConnectionService.getAccounts()) { - account.setResource(resource); - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - xmppConnectionService.reconnectAccountInBackground(account); + if (account.setResource(resource)) { + if (!account.isOptionSet(Account.OPTION_DISABLED)) { + XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.resetStreamId(); + } + xmppConnectionService.reconnectAccountInBackground(account); + } } } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 48dc2150..25db8ecc 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -981,6 +981,10 @@ public class XmppConnection implements Runnable { } } + public void resetStreamId() { + this.streamId = null; + } + public List findDiscoItemsByFeature(final String feature) { final List items = new ArrayList<>(); for (final Entry> cursor : disco.entrySet()) { -- cgit v1.2.3 From 37d08276a866aa943bfb6022732618e9fc37653b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 11 Apr 2015 14:53:10 +0200 Subject: allow sharing multiple images at once. fixes #1090 --- src/main/AndroidManifest.xml | 7 ++ .../conversations/ui/ConversationActivity.java | 109 +++++++++++++-------- .../siacs/conversations/ui/ShareWithActivity.java | 54 ++++++---- 3 files changed, 111 insertions(+), 59 deletions(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index e4e91d80..9fe37017 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -122,6 +122,13 @@ + + + + + + + mPendingImageUris = new ArrayList<>(); + final private List mPendingFileUris = new ArrayList<>(); private Uri mPendingGeoUri = null; private View mContentView; @@ -141,13 +143,14 @@ public class ConversationActivity extends XmppActivity @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (savedInstanceState != null) {mOpenConverstaion = savedInstanceState.getString( - STATE_OPEN_CONVERSATION, null); - mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true); - String pending = savedInstanceState.getString(STATE_PENDING_URI, null); - if (pending != null) { - mPendingImageUri = Uri.parse(pending); - } + if (savedInstanceState != null) { + mOpenConverstaion = savedInstanceState.getString(STATE_OPEN_CONVERSATION, null); + mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true); + String pending = savedInstanceState.getString(STATE_PENDING_URI, null); + if (pending != null) { + mPendingImageUris.clear(); + mPendingImageUris.add(Uri.parse(pending)); + } } setContentView(R.layout.fragment_conversations_overview); @@ -409,13 +412,18 @@ public class ConversationActivity extends XmppActivity switch (attachmentChoice) { case ATTACHMENT_CHOICE_CHOOSE_IMAGE: intent.setAction(Intent.ACTION_GET_CONTENT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); + } intent.setType("image/*"); chooser = true; break; case ATTACHMENT_CHOICE_TAKE_PHOTO: - mPendingImageUri = xmppConnectionService.getFileBackend().getTakePhotoUri(); + Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri(); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, mPendingImageUri); + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mPendingImageUris.clear(); + mPendingImageUris.add(uri); break; case ATTACHMENT_CHOICE_CHOOSE_FILE: chooser = true; @@ -857,8 +865,8 @@ public class ConversationActivity extends XmppActivity } savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable()); - if (this.mPendingImageUri != null) { - savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUri.toString()); + if (this.mPendingImageUris.size() >= 1) { + savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUris.get(0).toString()); } super.onSaveInstanceState(savedInstanceState); } @@ -897,21 +905,23 @@ public class ConversationActivity extends XmppActivity this.mConversationFragment.reInit(getSelectedConversation()); } else { showConversationsOverview(); - mPendingImageUri = null; - mPendingFileUri = null; + mPendingImageUris.clear(); + mPendingFileUris.clear(); mPendingGeoUri = null; setSelectedConversation(conversationList.get(0)); this.mConversationFragment.reInit(getSelectedConversation()); } - if (mPendingImageUri != null) { - attachImageToConversation(getSelectedConversation(),mPendingImageUri); - mPendingImageUri = null; - } else if (mPendingFileUri != null) { - attachFileToConversation(getSelectedConversation(),mPendingFileUri); - mPendingFileUri = null; - } else if (mPendingGeoUri != null) { - attachLocationToConversation(getSelectedConversation(),mPendingGeoUri); + for(Iterator i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) { + attachImageToConversation(getSelectedConversation(),i.next()); + } + + for(Iterator i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) { + attachFileToConversation(getSelectedConversation(),i.next()); + } + + if (mPendingGeoUri != null) { + attachLocationToConversation(getSelectedConversation(), mPendingGeoUri); mPendingGeoUri = null; } ExceptionHelper.checkForCrash(this, this.xmppConnectionService); @@ -963,6 +973,20 @@ public class ConversationActivity extends XmppActivity xmppConnectionService.getNotificationService().setOpenConversation(null); } + private static List extractUriFromIntent(final Intent intent) { + List uris = new ArrayList<>(); + Uri uri = intent.getData(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && uri == null) { + ClipData clipData = intent.getClipData(); + for(int i = 0; i < clipData.getItemCount(); ++i) { + uris.add(clipData.getItemAt(i).getUri()); + } + } else { + uris.add(uri); + } + return uris; + } + @Override protected void onActivityResult(int requestCode, int resultCode, final Intent data) { @@ -972,25 +996,34 @@ public class ConversationActivity extends XmppActivity mConversationFragment.hideSnackbar(); mConversationFragment.updateMessages(); } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) { - mPendingImageUri = data.getData(); + mPendingImageUris.clear(); + mPendingImageUris.addAll(extractUriFromIntent(data)); if (xmppConnectionServiceBound) { - attachImageToConversation(getSelectedConversation(),mPendingImageUri); - mPendingImageUri = null; + for(Iterator i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) { + attachImageToConversation(getSelectedConversation(),i.next()); + } } } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_FILE || requestCode == ATTACHMENT_CHOICE_RECORD_VOICE) { - mPendingFileUri = data.getData(); + mPendingFileUris.clear(); + mPendingFileUris.addAll(extractUriFromIntent(data)); if (xmppConnectionServiceBound) { - attachFileToConversation(getSelectedConversation(),mPendingFileUri); - mPendingFileUri = null; + for(Iterator i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) { + attachFileToConversation(getSelectedConversation(), i.next()); + } } - } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO && mPendingImageUri != null) { - if (xmppConnectionServiceBound) { - attachImageToConversation(getSelectedConversation(),mPendingImageUri); - mPendingImageUri = null; + } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) { + if (mPendingImageUris.size() == 1) { + Uri uri = mPendingImageUris.get(0); + if (xmppConnectionServiceBound) { + attachImageToConversation(getSelectedConversation(), uri); + mPendingImageUris.clear(); + } + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(uri); + sendBroadcast(intent); + } else { + mPendingImageUris.clear(); } - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(mPendingImageUri); - sendBroadcast(intent); } else if (requestCode == ATTACHMENT_CHOICE_LOCATION) { double latitude = data.getDoubleExtra("latitude",0); double longitude = data.getDoubleExtra("longitude",0); @@ -1000,10 +1033,6 @@ public class ConversationActivity extends XmppActivity this.mPendingGeoUri = null; } } - } else { - if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) { - mPendingImageUri = null; - } } } diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 6be238dc..200a577e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -18,6 +18,7 @@ import java.net.URLConnection; import java.net.URLDecoder; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import eu.siacs.conversations.Config; @@ -32,7 +33,7 @@ import eu.siacs.conversations.xmpp.jid.Jid; public class ShareWithActivity extends XmppActivity { private class Share { - public Uri uri; + public List uris = new ArrayList<>(); public boolean image; public String account; public String contact; @@ -104,7 +105,7 @@ public class ShareWithActivity extends XmppActivity { int position, long arg3) { Conversation conversation = mConversations.get(position); if (conversation.getMode() == Conversation.MODE_SINGLE - || share.uri == null) { + || share.uris.size() == 0) { share(mConversations.get(position)); } } @@ -133,18 +134,32 @@ public class ShareWithActivity extends XmppActivity { @Override public void onStart() { - final String type = getIntent().getType(); - final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); - if (type != null && uri != null && !type.equalsIgnoreCase("text/plain")) { - this.share.uri = uri; - this.share.image = type.startsWith("image/") || isImage(uri); - } else { - this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT); + super.onStart(); + Intent intent = getIntent(); + if (intent == null) { + return; + } + final String type = intent.getType(); + if (Intent.ACTION_SEND.equals(intent.getAction())) { + final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); + if (type != null && uri != null && !type.equalsIgnoreCase("text/plain")) { + this.share.uris.add(uri); + this.share.image = type.startsWith("image/") || isImage(uri); + } else { + this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT); + } + } else if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) { + this.share.image = type != null && type.startsWith("image/"); + if (!this.share.image) { + return; + } + + this.share.uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); } if (xmppConnectionServiceBound) { - xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uri == null); + xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.image); } - super.onStart(); + } protected boolean isImage(Uri uri) { @@ -164,7 +179,7 @@ public class ShareWithActivity extends XmppActivity { return; } xmppConnectionService.populateWithOrderedConversations(mConversations, - this.share != null && this.share.uri == null); + this.share != null && this.share.uris.size() == 0); } private void share() { @@ -188,7 +203,7 @@ public class ShareWithActivity extends XmppActivity { } private void share(final Conversation conversation) { - if (share.uri != null) { + if (share.uris.size() != 0) { selectPresence(conversation, new OnPresenceSelected() { @Override public void onPresenceSelected() { @@ -196,22 +211,23 @@ public class ShareWithActivity extends XmppActivity { Toast.makeText(getApplicationContext(), getText(R.string.preparing_image), Toast.LENGTH_LONG).show(); - ShareWithActivity.this.xmppConnectionService - .attachImageToConversation(conversation, share.uri, - attachFileCallback); + for (Iterator i = share.uris.iterator(); i.hasNext(); i.remove()) { + ShareWithActivity.this.xmppConnectionService + .attachImageToConversation(conversation, i.next(), + attachFileCallback); + } } else { Toast.makeText(getApplicationContext(), getText(R.string.preparing_file), Toast.LENGTH_LONG).show(); ShareWithActivity.this.xmppConnectionService - .attachFileToConversation(conversation, share.uri, - attachFileCallback); + .attachFileToConversation(conversation, share.uris.get(0), + attachFileCallback); } switchToConversation(conversation, null, true); finish(); } }); - } else { switchToConversation(conversation, this.share.text, true); finish(); -- cgit v1.2.3 From 878066ca99c1170479fb217d68ecdb9cf5498975 Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Thu, 2 Apr 2015 13:35:42 +0200 Subject: Add option to use MTM without default TrustManager Add a new "Don't trust system CAs" preference under advanced options that will change the behaviour of the MemorizingTrustManager. All formerly unknown certificates will raise a warning if checked. --- .../conversations/services/XmppConnectionService.java | 19 ++++++++++++++++--- .../eu/siacs/conversations/ui/SettingsActivity.java | 3 ++- src/main/res/values-de/strings.xml | 2 ++ src/main/res/values/strings.xml | 2 ++ src/main/res/xml/preferences.xml | 5 +++++ 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ca182867..f94e715e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -532,9 +532,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa ExceptionHelper.init(getApplicationContext()); PRNGFixes.apply(); this.mRandom = new SecureRandom(); - this.mMemorizingTrustManager = new MemorizingTrustManager( - getApplicationContext()); - + updateMemorizingTrustmanager(); final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int cacheSize = maxMemory / 8; this.mBitmapCache = new LruCache(cacheSize) { @@ -2185,6 +2183,21 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return this.mMemorizingTrustManager; } + public void setMemorizingTrustManager(MemorizingTrustManager trustManager) { + this.mMemorizingTrustManager = trustManager; + } + + public void updateMemorizingTrustmanager() { + final MemorizingTrustManager tm; + final boolean dontTrustSystemCAs = getPreferences().getBoolean("dont_trust_system_cas", false); + if (dontTrustSystemCAs) { + tm = new MemorizingTrustManager(getApplicationContext(), null); + } else { + tm = new MemorizingTrustManager(getApplicationContext()); + } + setMemorizingTrustManager(tm); + } + public PowerManager getPowerManager() { return this.pm; } diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 39e215f2..1bc59b13 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -79,7 +79,8 @@ public class SettingsActivity extends XmppActivity implements } } } + } else if (name.equals("dont_trust_system_cas")) { + xmppConnectionService.updateMemorizingTrustmanager(); } } - } diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 0dd9f401..d5533061 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -427,6 +427,8 @@ Keine App für die Standort-Anzeige gefunden Standort Standort empfangen + Misstraue Zertifizierungsstellen + Alle Zertifikate müssen manuell bestätigt werden %d Kontakt ausgewählt %d Kontakte ausgewählt diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index af56c014..28bb71e9 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -454,6 +454,8 @@ No application found to display location Location Received location + Don\'t trust system CAs + All certificates must be manually approved Select %d contact Select %d contacts diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 8bf6eb87..d48124a6 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -147,6 +147,11 @@ android:key="keep_foreground_service" android:title="@string/pref_keep_foreground_service" android:summary="@string/pref_keep_foreground_service_summary" /> + -- cgit v1.2.3 From 845b39cdcc4d20d916bdee5b661c31a19f6cbdac Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 13 Apr 2015 15:59:18 +0200 Subject: fixed regression where the selected conversation wasn't highlighted anymore on tabled layout --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 8 +++++++- .../conversations/ui/adapter/ConversationAdapter.java | 15 ++++----------- src/main/res/layout/conversation_list_row.xml | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 7eaec10c..392e57a7 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -90,6 +90,7 @@ public abstract class XmppActivity extends Activity { protected int mPrimaryTextColor; protected int mSecondaryTextColor; + protected int mPrimaryBackgroundColor; protected int mSecondaryBackgroundColor; protected int mColorRed; protected int mColorOrange; @@ -331,6 +332,7 @@ public abstract class XmppActivity extends Activity { mColorOrange = getResources().getColor(R.color.orange); mColorGreen = getResources().getColor(R.color.green); mPrimaryColor = getResources().getColor(R.color.primary); + mPrimaryBackgroundColor = getResources().getColor(R.color.primarybackground); mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); this.mTheme = findTheme(); setTheme(this.mTheme); @@ -740,7 +742,11 @@ public abstract class XmppActivity extends Activity { public int getOnlineColor() { return this.mColorGreen; } - + + public int getPrimaryBackgroundColor() { + return this.mPrimaryBackgroundColor; + } + public int getSecondaryBackgroundColor() { return this.mSecondaryBackgroundColor; } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index a48f6ae4..d5b7e4c0 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -46,17 +46,10 @@ public class ConversationAdapter extends ArrayAdapter { } Conversation conversation = getItem(position); if (this.activity instanceof ConversationActivity) { - ConversationActivity activity = (ConversationActivity) this.activity; - if (!activity.isConversationsOverviewHideable()) { - if (conversation == activity.getSelectedConversation()) { - view.setBackgroundColor(activity - .getSecondaryBackgroundColor()); - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } + View swipeableItem = view.findViewById(R.id.swipeable_item); + ConversationActivity a = (ConversationActivity) this.activity; + int c = !a.isConversationsOverviewHideable() && conversation == a.getSelectedConversation() ? a.getSecondaryBackgroundColor() : a.getPrimaryBackgroundColor(); + swipeableItem.setBackgroundColor(c); } TextView convName = (TextView) view.findViewById(R.id.conversation_name); if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) { diff --git a/src/main/res/layout/conversation_list_row.xml b/src/main/res/layout/conversation_list_row.xml index de04780f..69abb225 100644 --- a/src/main/res/layout/conversation_list_row.xml +++ b/src/main/res/layout/conversation_list_row.xml @@ -6,7 +6,7 @@ + android:background="@color/primary"/> Date: Mon, 13 Apr 2015 16:00:04 +0200 Subject: Maintain private chat on MUC. fixes #1097 --- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index d5f20e41..a3a02b27 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -268,7 +268,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getNextCounterpart() != null) { message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_PRIVATE); - conversation.setNextCounterpart(null); } } if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) { -- cgit v1.2.3 From 6da77bdf3b38fab3daa0de8776082038d8d62a78 Mon Sep 17 00:00:00 2001 From: lookshe Date: Mon, 13 Apr 2015 10:57:30 +0200 Subject: Bugfix for issue #1121 check with lowercase to also match JPEG, JPeg ... changed image url in comment --- .../eu/siacs/conversations/entities/Message.java | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 8015eead..21aa7779 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -430,23 +430,31 @@ public class Message extends AbstractEntity { } public boolean bodyContainsDownloadable() { + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ + if (body.contains(" ")) { + return false; + } try { - URL url = new URL(this.getBody()); + URL url = new URL(body); if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { return false; } - if (url.getPath() == null) { - return false; - } - String[] pathParts = url.getPath().split("/"); - String filename; - if (pathParts.length > 0) { - filename = pathParts[pathParts.length - 1].toLowerCase(); - } else { + + String sUrlPath = url.getPath(); + if (sUrlPath == null || sUrlPath.isEmpty()) { return false; } - String[] extensionParts = filename.split("\\."); + + int iSlashIndex = sUrlPath.lastIndexOf('/') + 1; + + String sLastUrlPath = sUrlPath.substring(iSlashIndex).toLowerCase(); + + String[] extensionParts = sLastUrlPath.split("\\."); if (extensionParts.length == 2 && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( extensionParts[extensionParts.length - 1])) { -- cgit v1.2.3 From 4bf09bc10b05844f2d1407b1ff72080cc6acb72b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 13 Apr 2015 17:35:20 +0200 Subject: shut up linter --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 9533ffc7..c8a1e6df 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -973,6 +973,7 @@ public class ConversationActivity extends XmppActivity xmppConnectionService.getNotificationService().setOpenConversation(null); } + @SuppressLint("NewApi") private static List extractUriFromIntent(final Intent intent) { List uris = new ArrayList<>(); Uri uri = intent.getData(); -- cgit v1.2.3 From 62faa163f0d5fc2d8d53067cc328f1905d1df370 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 13 Apr 2015 18:18:25 +0200 Subject: fixed typos --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 21aa7779..7ea3d60b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -432,7 +432,7 @@ public class Message extends AbstractEntity { public boolean bodyContainsDownloadable() { /** * there are a few cases where spaces result in an unwanted behavior, e.g. - * "http://example.com/image.jpg" text that will not be shown /abc.png" + * "http://example.com/image.jpg text that will not be shown /abc.png" * or more than one image link in one message. */ if (body.contains(" ")) { diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index f7dda936..b31b9018 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -20,7 +20,7 @@ public class GeoHelper { } public static ArrayList createGeoIntentsFromMessage(Message message) { - final ArrayList intents = new ArrayList(); + final ArrayList intents = new ArrayList<>(); Matcher matcher = GEO_URI.matcher(message.getBody()); if (!matcher.matches()) { return intents; -- cgit v1.2.3 From 2f24b093093296ca6f4f90fbcf664b050a8b03fc Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 13 Apr 2015 18:19:40 +0200 Subject: fixed disable account when sliding and not clicking the toggle --- .../eu/siacs/conversations/ui/ManageAccountActivity.java | 4 ++-- .../eu/siacs/conversations/ui/adapter/AccountAdapter.java | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java index c7db94af..56dbc55e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -168,8 +168,8 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda } } - public void onClickTglAccountState(Account account) { - if (account.isOptionSet(Account.OPTION_DISABLED)) { + public void onClickTglAccountState(Account account, boolean enable) { + if (enable) { enableAccount(account); } else { disableAccount(account); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index 5209aa12..95c0524d 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -11,6 +11,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Switch; @@ -51,14 +52,14 @@ public class AccountAdapter extends ArrayAdapter { break; } final Switch tglAccountState = (Switch) view.findViewById(R.id.tgl_account_status); - boolean isDisabled = (account.getStatus() == Account.State.DISABLED) ? true : false; + final boolean isDisabled = (account.getStatus() == Account.State.DISABLED) ? true : false; + tglAccountState.setOnCheckedChangeListener(null); tglAccountState.setChecked(!isDisabled); - tglAccountState.setOnClickListener(new View.OnClickListener() { + tglAccountState.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override - public void onClick(View v) { - if (activity instanceof ManageAccountActivity) { - ((ManageAccountActivity) activity).onClickTglAccountState(account); - tglAccountState.toggle(); + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b == isDisabled && activity instanceof ManageAccountActivity) { + ((ManageAccountActivity) activity).onClickTglAccountState(account,b); } } }); -- cgit v1.2.3 From 261b505f066b90ef346c529afea50f8285ddfd7d Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 14 Apr 2015 15:00:49 +0200 Subject: always show save button when account info was modified. fixes #918 --- .../eu/siacs/conversations/ui/EditAccountActivity.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 27dfc492..dbad9e00 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -67,7 +67,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate @Override public void onClick(final View v) { - if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED) { + if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED && !accountInfoEdited()) { mAccount.setOption(Account.OPTION_DISABLED, false); xmppConnectionService.updateAccount(mAccount); return; @@ -237,7 +237,11 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } protected void updateSaveButton() { - if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) { + if (accountInfoEdited() && jidToEdit != null) { + this.mSaveButton.setText(R.string.save); + this.mSaveButton.setEnabled(true); + this.mSaveButton.setTextColor(getPrimaryTextColor()); + } else if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) { this.mSaveButton.setEnabled(false); this.mSaveButton.setTextColor(getSecondaryTextColor()); this.mSaveButton.setText(R.string.account_status_connecting); @@ -265,9 +269,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } protected boolean accountInfoEdited() { - return (!this.mAccount.getJid().toBareJid().toString().equals( - this.mAccountJid.getText().toString())) - || (!this.mAccount.getPassword().equals( + return this.mAccount != null && (!this.mAccount.getJid().toBareJid().toString().equals( + this.mAccountJid.getText().toString()) + || !this.mAccount.getPassword().equals( this.mPassword.getText().toString())); } -- cgit v1.2.3 From f99e234b886d043968267323ccb4995f20ee4fa4 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 14 Apr 2015 15:53:50 +0200 Subject: maintain state when rotating settings activity --- .../siacs/conversations/ui/SettingsActivity.java | 30 ++++++++++++---------- src/main/res/xml/preferences.xml | 14 +++++++--- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index d24cb52b..f91bc953 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -7,6 +7,8 @@ import java.util.Locale; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.xmpp.XmppConnection; +import android.app.Fragment; +import android.app.FragmentManager; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Build; @@ -21,9 +23,12 @@ public class SettingsActivity extends XmppActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mSettingsFragment = new SettingsFragment(); - getFragmentManager().beginTransaction() - .replace(android.R.id.content, mSettingsFragment).commit(); + FragmentManager fm = getFragmentManager(); + mSettingsFragment = (SettingsFragment) fm.findFragmentById(android.R.id.content); + if (mSettingsFragment == null || !mSettingsFragment.getClass().equals(SettingsFragment.class)) { + mSettingsFragment = new SettingsFragment(); + fm.beginTransaction().replace(android.R.id.content, mSettingsFragment).commit(); + } } @Override @@ -34,18 +39,15 @@ public class SettingsActivity extends XmppActivity implements @Override public void onStart() { super.onStart(); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(this); - ListPreference resources = (ListPreference) mSettingsFragment - .findPreference("resource"); + PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); + ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource"); if (resources != null) { - ArrayList entries = new ArrayList( - Arrays.asList(resources.getEntries())); - entries.add(0, Build.MODEL); - resources.setEntries(entries.toArray(new CharSequence[entries - .size()])); - resources.setEntryValues(entries.toArray(new CharSequence[entries - .size()])); + ArrayList entries = new ArrayList<>(Arrays.asList(resources.getEntries())); + if (!entries.contains(Build.MODEL)) { + entries.add(0, Build.MODEL); + resources.setEntries(entries.toArray(new CharSequence[entries.size()])); + resources.setEntryValues(entries.toArray(new CharSequence[entries.size()])); + } } } diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index d48124a6..9cf0100f 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -36,7 +36,9 @@ android:title="@string/pref_chat_states" /> - + + android:title="@string/title_pref_quiet_hours" + android:key="quiet_hours"> - + + android:title="@string/pref_expert_options" + android:key="expert"> Date: Wed, 15 Apr 2015 15:36:16 +0200 Subject: some bug fixes concerning 0byte files. fixes #1126 --- src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 2 +- .../java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 2d949e21..68eadbc6 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -317,7 +317,7 @@ public class JingleConnection implements Downloadable { message.setBody(Long.toString(size)); conversation.add(message); mXmppConnectionService.updateConversationUi(); - if (size <= this.mJingleConnectionManager + if (size < this.mJingleConnectionManager .getAutoAcceptFileSize()) { Log.d(Config.LOGTAG, "auto accepting file from " + packet.getFrom()); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 174f70fa..3677bf4f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -207,6 +207,7 @@ public class JingleInbandTransport extends JingleTransport { if (!established) { established = true; connected = true; + this.receiveNextBlock(""); this.account.getXmppConnection().sendIqPacket( packet.generateResponse(IqPacket.TYPE.RESULT), null); } else { -- cgit v1.2.3 From 584ffbd0009ec57bcbe413857e3d16ff10f376de Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 15 Apr 2015 16:28:44 +0200 Subject: bumped version to 1.3.0-alpha --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index cdbb5a98..1664fa57 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 56 - versionName "1.2.0" + versionCode 57 + versionName "1.3.0-alpha" } compileOptions { -- cgit v1.2.3 From c4daa08170f0e468c0407d9db91a0de0415b6bf2 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 16 Apr 2015 21:55:52 +0200 Subject: fixed a bug in DNS helper code. fixes #1130 --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 2 +- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index bcb2ca44..42dd1c95 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -121,7 +121,7 @@ public class DNSHelper { while (p > 0) { p -= s.get(i++).getPriority(); } - i--; + if (i>0) i--; // remove is expensive, but we have only a few entries // anyway SRV srv = s.remove(i); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 25db8ecc..1351226b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -204,7 +204,7 @@ public class XmppConnection implements Runnable { && "nosrv".equals(result.getString("error", null))) { socket = new Socket(account.getServer().getDomainpart(), 5222); } else { - throw new IOException("timeout in dns"); + throw new IOException("unhandled exception in DNS resolver"); } final OutputStream out = socket.getOutputStream(); tagWriter.setOutputStream(out); -- cgit v1.2.3 From dbe170bd353562c64d1d495e10a4d5ed80dfd233 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 16 Apr 2015 21:55:52 +0200 Subject: fixed a bug in DNS helper code. fixes #1130 --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 2 +- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index bcb2ca44..42dd1c95 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -121,7 +121,7 @@ public class DNSHelper { while (p > 0) { p -= s.get(i++).getPriority(); } - i--; + if (i>0) i--; // remove is expensive, but we have only a few entries // anyway SRV srv = s.remove(i); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 48dc2150..b8e25d4b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -204,7 +204,7 @@ public class XmppConnection implements Runnable { && "nosrv".equals(result.getString("error", null))) { socket = new Socket(account.getServer().getDomainpart(), 5222); } else { - throw new IOException("timeout in dns"); + throw new IOException("unhandled exception in DNS resolver"); } final OutputStream out = socket.getOutputStream(); tagWriter.setOutputStream(out); -- cgit v1.2.3 From 570a22206dd1588ac2bff0e950a48befa0daef82 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 17 Apr 2015 20:01:09 +0200 Subject: increased undo delay --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index c8a1e6df..a44311b4 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -246,7 +246,7 @@ public class ConversationActivity extends XmppActivity listView.enableSwipeToDismiss(); listView.setSwipingLayout(R.id.swipeable_item); listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP); - listView.setUndoHideDelay(3000); + listView.setUndoHideDelay(8000); listView.setRequireTouchBeforeDismiss(false); mContentView = findViewById(R.id.content_view_spl); -- cgit v1.2.3 From da367dd752b6c92a3d0dbc558c80ebc71ef7b1fe Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Sun, 19 Apr 2015 18:08:13 +0200 Subject: Add option to remove manually approved certificates - "Remove certificates" option brings up a dialog that allows to delete certificates from MemorizingTrustManager's keystore - Reconnect active accounts when certificate-settings are changed - new preference category "Certificate options" --- .../siacs/conversations/ui/SettingsActivity.java | 91 ++++++++++++++++++++++ src/main/res/values-de/strings.xml | 11 +++ src/main/res/values/strings.xml | 11 +++ src/main/res/xml/preferences.xml | 16 ++-- 4 files changed, 124 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index f91bc953..eb5d9b2e 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -1,20 +1,29 @@ package eu.siacs.conversations.ui; +import java.security.KeyStoreException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Locale; +import de.duenndns.ssl.MemorizingTrustManager; + +import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.xmpp.XmppConnection; +import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentManager; +import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Build; import android.os.Bundle; import android.preference.ListPreference; +import android.preference.Preference; import android.preference.PreferenceManager; +import android.widget.Toast; public class SettingsActivity extends XmppActivity implements OnSharedPreferenceChangeListener { @@ -49,6 +58,68 @@ public class SettingsActivity extends XmppActivity implements resources.setEntryValues(entries.toArray(new CharSequence[entries.size()])); } } + + final Preference removeCertsPreference = mSettingsFragment.findPreference("remove_trusted_certificates"); + removeCertsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final MemorizingTrustManager mtm = xmppConnectionService.getMemorizingTrustManager(); + final ArrayList aliases = Collections.list(mtm.getCertificates()); + if (aliases.size() == 0) { + displayToast(getString(R.string.toast_no_trusted_certs)); + return true; + } + final ArrayList selectedItems = new ArrayList(); + final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SettingsActivity.this); + dialogBuilder.setTitle(getResources().getString(R.string.dialog_manage_certs_title)); + dialogBuilder.setMultiChoiceItems(aliases.toArray(new CharSequence[aliases.size()]), null, + new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int indexSelected, + boolean isChecked) { + if (isChecked) { + selectedItems.add(indexSelected); + } else if (selectedItems.contains(indexSelected)) { + selectedItems.remove(Integer.valueOf(indexSelected)); + } + if (selectedItems.size() > 0) + ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true); + else { + ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false); + } + } + }); + + dialogBuilder.setPositiveButton( + getResources().getString(R.string.dialog_manage_certs_positivebutton), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int count = selectedItems.size(); + if (count > 0) { + for (int i = 0; i < count; i++) { + try { + Integer item = Integer.valueOf(selectedItems.get(i).toString()); + String alias = aliases.get(item); + mtm.deleteCertificate(alias); + } catch (KeyStoreException e) { + e.printStackTrace(); + displayToast("Error: " + e.getLocalizedMessage()); + } + } + if (xmppConnectionServiceBound) { + reconnectAccounts(); + } + displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count)); + } + } + }); + dialogBuilder.setNegativeButton(getResources().getString(R.string.dialog_manage_certs_negativebutton), null); + AlertDialog removeCertsDialog = dialogBuilder.create(); + removeCertsDialog.show(); + removeCertsDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); + return true; + } + }); } @Override @@ -89,6 +160,26 @@ public class SettingsActivity extends XmppActivity implements } } else if (name.equals("dont_trust_system_cas")) { xmppConnectionService.updateMemorizingTrustmanager(); + reconnectAccounts(); + } + + } + + private void displayToast(final String msg) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show(); + } + }); + } + + private void reconnectAccounts() { + for (Account account : xmppConnectionService.getAccounts()) { + if (!account.isOptionSet(Account.OPTION_DISABLED)) { + xmppConnectionService.reconnectAccountInBackground(account); + } } } + } diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index addc55de..d5f550a3 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -429,8 +429,19 @@ Standort empfangen Unterhaltung beendet Konferenz verlassen + Zertifikats-Optionen Misstraue Zertifizierungsstellen Alle Zertifikate müssen manuell bestätigt werden + Zertifikate löschen + Als vertrauenswürdig bestätigte Zertifikate löschen + Keine manuell bestätigten Zertifikate + Zertifikate löschen + Auswahl löschen + Abbrechen + + %d Zertifikat gelöscht + %d Zertifikate gelöscht + %d Kontakt ausgewählt %d Kontakte ausgewählt diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 4a36163c..cc7727d2 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -457,8 +457,19 @@ Received location Conversation closed Left conference + Certificate options Don’t trust system CAs All certificates must be manually approved + Remove certificates + Delete manually approved certificates + No manually approved certificates + Remove certificates + Delete selection + Cancel + + %d certificate deleted + %d certificates deleted + Select %d contact Select %d contacts diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 9cf0100f..417e60a4 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -142,6 +142,17 @@ android:title="@string/pref_display_enter_key" android:summary="@string/pref_display_enter_key_summary" /> + + + + - -- cgit v1.2.3 From 9e20a4936e3bea938e20e15421985ea1a928bf63 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 19 Apr 2015 19:11:32 +0200 Subject: =?UTF-8?q?some=20code=20clean=20up=20to=20fix=20some=20rare=20NPE?= =?UTF-8?q?=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 8 ++++---- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a44311b4..e5389dd6 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -929,10 +929,10 @@ public class ConversationActivity extends XmppActivity } private void handleViewConversationIntent(final Intent intent) { - final String uuid = (String) intent.getExtras().get(CONVERSATION); - final String downloadUuid = (String) intent.getExtras().get(MESSAGE); - final String text = intent.getExtras().getString(TEXT, ""); - final String nick = intent.getExtras().getString(NICK, null); + final String uuid = intent.getStringExtra(CONVERSATION); + final String downloadUuid = intent.getStringExtra(MESSAGE); + final String text = intent.getStringExtra(TEXT); + final String nick = intent.getStringExtra(NICK); if (selectConversationByUuid(uuid)) { this.mConversationFragment.reInit(getSelectedConversation()); if (nick != null) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index a3a02b27..bb349348 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1019,6 +1019,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } public void appendText(String text) { + if (text == null) { + return; + } String previous = this.mEditMessage.getText().toString(); if (previous.length() != 0 && !previous.endsWith(" ")) { text = " " + text; -- cgit v1.2.3 From d2c9bf31cd2a6b39f22ac3426015ecea73403315 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 11:39:38 +0200 Subject: fixed weird touch on snackbar switched conversation bug when touching the border of the snackbar or more precisely the space between the input field and the snackbar Conversations would switch into a random conversation for yet unknown reasons. --- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index bb349348..748fa168 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -8,7 +8,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; -import android.net.Uri; import android.os.Bundle; import android.text.InputType; import android.view.ContextMenu; @@ -315,8 +314,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.fragment_conversation, - container, false); + final View view = inflater.inflate(R.layout.fragment_conversation,container, false); + view.setOnClickListener(null); mEditMessage = (EditMessage) view.findViewById(R.id.textinput); setupIme(); mEditMessage.setOnClickListener(new OnClickListener() { -- cgit v1.2.3 From 127b7866f027b6c1df67973769f5964fa2441c8e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 11:49:44 +0200 Subject: removed some dead code --- .../siacs/conversations/ui/ConversationFragment.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 748fa168..3d94f871 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -718,21 +718,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final ConversationActivity activity = (ConversationActivity) getActivity(); if (this.conversation != null) { updateSnackBar(this.conversation); - final Contact contact = this.conversation.getContact(); - if (this.conversation.isBlocked()) { - - } else if (!contact.showInRoster() - && contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - - } else if (conversation.getMode() == Conversation.MODE_SINGLE) { - makeFingerprintWarning(); - } else if (!conversation.getMucOptions().online() - && conversation.getAccount().getStatus() == Account.State.ONLINE) { - - } else if (this.conversation.isMuted()) { - - } conversation.populateWithMessages(ConversationFragment.this.messageList); for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP @@ -878,10 +863,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } } - protected void makeFingerprintWarning() { - - } - protected void showSnackbar(final int message, final int action, final OnClickListener clickListener) { snackbar.setVisibility(View.VISIBLE); -- cgit v1.2.3 From 5d7e1159f521482eec9bd17ca7f291b8ade3233f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 12:13:47 +0200 Subject: always hide pgp snackbar after decrypting a message. fixes #1075 --- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 3d94f871..5b1e9b4d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -764,6 +764,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } catch (final NoSuchElementException ignored) { } + askForPassphraseIntent = null; activity.xmppConnectionService.updateMessage(message); } -- cgit v1.2.3 From 895a28ab9ddcffcac47fad1f5e1a4a02c70f2105 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 16:13:43 +0200 Subject: added amazon app store link (us store) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac075fd3..c491b3c5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Conversations: the very last word in instant messaging -[![Google Play](http://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=eu.siacs.conversations) +[![Google Play](http://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=eu.siacs.conversations) [![Amazon App Store](https://images-na.ssl-images-amazon.com/images/G/01/AmazonMobileApps/amazon-apps-store-us-black.png)](http://www.amazon.com/dp/B00WD35AAC/) ![screenshots](https://raw.githubusercontent.com/siacs/Conversations/master/screenshots.png) -- cgit v1.2.3 From 69b43556525a3a2a1565dbbe3289399d51cc642f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 16:41:24 +0200 Subject: added reference to the location plugin to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c491b3c5..5519e47f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Conversations: the very last word in instant messaging ## Features * End-to-end encryption with either [OTR](https://otr.cypherpunks.ca/) or [OpenPGP](http://www.openpgp.org/about_openpgp/) -* Sending and receiving images +* Send and receive images as well as other kind of files +* Share your location via an external [plug-in](https://play.google.com/store/apps/details?id=eu.siacs.conversations.sharelocation) * Indication when your contact has read your message * Intuitive UI that follows Android Design guidelines * Pictures / Avatars for your Contacts -- cgit v1.2.3 From e7972d3d112065f37b1b4d99584ecc8f1ca8fd32 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 20 Apr 2015 20:32:50 +0200 Subject: pulled latest translations from transifex --- src/main/res/values-cs/strings.xml | 4 + src/main/res/values-el/strings.xml | 10 +- src/main/res/values-id/strings.xml | 343 +++++++++++++++++++++++++++++++++++++ src/main/res/values-nl/strings.xml | 4 + src/main/res/values-pl/strings.xml | 333 ++++++++++++++++++++++++++++++++++- src/main/res/values-ru/strings.xml | 36 +++- 6 files changed, 727 insertions(+), 3 deletions(-) create mode 100644 src/main/res/values-id/strings.xml diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml index 0c08fa7a..192df52f 100644 --- a/src/main/res/values-cs/strings.xml +++ b/src/main/res/values-cs/strings.xml @@ -427,6 +427,10 @@ Nebyla nalezena aplikace pro zobrazení pozice Pozice Přijmout pozici + Conversation zavřena + Opustil(a) konferenci + Nedůvěřovat systémovým CA + Všechny certifikáty musí být schváleny ručně Vybrat %d kontakt Vybrat %d kontakty diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index 48dc4034..ec1da08c 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -359,7 +359,7 @@ Δεν ήταν δυνατή η αλλαγή του συνθηματικού Αποστολή μηνύματος για την έναρξη κρυπτογραφημένης συνομιλίας Ερώτηση - Αν εσείς και η επαφή σας έχετε ένα κοινό μυστικό που κανείς άλλος δεν γνωρίζει (κάτι σαν δικό σας αστείο ή απλώς τι φάγατε την τελευταία φορά που συναντηθήκατε) μπορείτε να χρησιμοποιήσετε αυτό το μυστικό για νε επαληθεύσετε τα αποτυπώματά σας.\n\nΠροσφέρετε έναν υπαινιγμό ή μια ερώτηση για την επαφή σας, που θα απαντήσει με μια φράση στην οποία έχουν διαφοροποίηση τα πεζά από τα κεφαλαία. + Αν εσείς και η επαφή σας έχετε ένα κοινό μυστικό που κανείς άλλος δεν γνωρίζει (κάτι σαν δικό σας αστείο ή απλώς τι φάγατε την τελευταία φορά που συναντηθήκατε) μπορείτε να χρησιμοποιήσετε αυτό το μυστικό για να επαληθεύσετε τα αποτυπώματά σας.\n\nΠροσφέρετε έναν υπαινιγμό ή μια ερώτηση για την επαφή σας, που θα απαντήσει με μια φράση στην οποία έχουν διαφοροποίηση τα πεζά από τα κεφαλαία. Η επαφή σας θα ήθελε να επαληθεύσει το αποτύπωμά σας χρησιμοποιώντας ένα κοινό μυστικό. Η επαφή σας προμήθευση τον παρακάτω υπαινιγμό ή ερώτηση για το μυστικό αυτό. Ο υπαινιγμός σας δεν μπορεί να είναι κενός Το κοινό μυστικό σας δεν μπορεί να είναι κενό @@ -427,4 +427,12 @@ Δεν βρέθηκε εφαρμογή για την απεικόνιση τοποθεσίας Τοποθεσία Ελήφθη τοποθεσία + Η συζήτηση έκλεισε + Έφυγε από την συνδιάσκεψη + Μη έμπιστες αρχές πιστοποίησης συστήματος + Όλα τα πιστοποιητικά πρέπει να εγκριθούν χειροκίνητα + + Επιλογή %d επαφής + Επιλογή %d επαφών + diff --git a/src/main/res/values-id/strings.xml b/src/main/res/values-id/strings.xml new file mode 100644 index 00000000..6c2dedb6 --- /dev/null +++ b/src/main/res/values-id/strings.xml @@ -0,0 +1,343 @@ + + + Pengaturan + Percakapan Baru + Pengaturan Akun + Akhiri Percakapan + Detil Kontak + Detil conference + Amankan Percakapan + Tambah Akun + Ubah Nama + Tambah ke buku telepon + Hapus dari roster + Blokir kontak + Batal blokir kontak + Blokir domain + Batal blokir domain + Pengaturan Akun + Pengaturan + Conference Detil + Kontak Detil + Bagikan dengan Conversation + Mulai Percakapan + Pilih kontak + Daftar blokir + sekarang + 1 min lalu + %d min lalu + Percakapan belum dibaca + mengirim... + Menerjemahkan pesan. Tunggu sebentar... + Nick ini sudah digunakan + Administrator + Pemilik + Moderator + Peserta + Pengunjung + Apakah Anda ingin menghapus %s dari roster Anda? Percakapan yang terkait dengan kontak ini tidak akan dihapus. + Apakah Anda ingin memblokir pesan dari %s? + Apakah Anda ingin membuka blokir %s dan membolehkannya untuk mengirim pesan? + Blokir semua kontak dari %s? + Batalkan blokir semua kontak dari %s? + Kontak terblokir + Apakah Anda ingin menghapus %s dari bookmark? Percakapan yang terkait dengan bookmark ini tidak akan dihapus. + Daftarkan akun baru di server + Ganti password di server + Bagikan dengan... + Mulai Percakapan + Undang Kontak + Kontak + Batal + Atur + Tambah + Ubah + Hapus + Blokir + Batalkan blokir + Simpan + YA + Percakapan terhenti + Dengan mengirimkan laporan kesalahan Anda membantu pengembangan Conversations\n<b>Perhatian:</>Conversations akan menggunakan akun XMPP Anda untuk mengirim laporan kesalahan untuk pengembang. + Kirim sekarang + Jangan tanya lagi + Tidak terhubung ke akun + Tidak bisa terhubung ke banyak akun + Sentuh untuk mengatur akun + Sisipkan berkas + Kontak tidak ada dalam roster Anda. Ingin menambahkannya? + Tambah kontak + pengiriman gagal + ditolak + Mempersiapkan gambar untuk transmisi + Bersihkan riwayat + Hapus Riwayat Percakapan + Apakah Anda ingin menghapus semua pesan dalam Percakapan ini\n\nPeringatan:ini tidak akan mempengaruhi pesan yang disimpan pada perangkat atau server lain. + Hapus pesan + Pilih kehadiran untuk kontak + Kirim pesan teks biasa + Kirim pesan terenskripsi OTR + Kirim pesan terenskripsi OpenPGP + Nick kamu telah dirubah + Unduh Gambar + Kirim tidak terenkripsi + Dekripsi gagal. Mungkin Anda tidak memiliki kunci pribadi yang tepat. + OpenKeychain + Mulai ulang + Pasang + menawarkan... + menunggu... + Tidak ada kunci OpenPGP ditemukan + Tidak ada kunci OpenPGP ditemukan + Percakapan tidak dapat mengenkripsi pesan Anda karena kontak tidak mengumumkan kunci publik mereka.\n\nSilakan meminta kontak Anda untuk setup OpenPGP. + Pesan terenkripsi diterima. Sentuh untuk membongkar dan melihatnya. + Umum + XMPP resource + Identifikasi nama klien ini dengan + Terima berkas + Otomatis menerima berkas lebih kecil dari... + Pengaturan Notifikasi + Notifikasi + Notifikasikan jika pesan baru tiba + Getar + Juga aktifkan getaran bila pesan baru tiba + Suara + mainkan suara saat menerima notifikasi + Notifikasi Conference + Selalu memberitahukan bila pesan conference baru diterima daripada hanya dicetak tebal + Tenggang waktu pemberitahuan + Nonaktifkan pemberitahuan untuk waktu yang singkat setelah salinan diterima + Opsi Lanjutan + Jangan kirim laporan kerusakan + Dengan mengirimkan kesalahan Anda membantu pengembangan Aplikasi Conversations + Konfirmasi Pesan + Biarkan kontak Anda tahu kapan Anda telah menerima dan membaca pesan + Opsi Tampilan + OpenKeychain melaporkan kesalahan + I/O Error menerjemahkan berkas + Menerima + Sebuah kesalahan terjadi + Memberikan perubahan kehadiran + Terlebih dahulu meminta dan berlangganan kehadiran untuk kontak Anda buat + Langganan + Akun anda + Kunci + Kirim pembaruan kehadiran + Terima pembaruan kehadiran + Tanya untuk pembaruan kehadiran + Pilih gambar + Ambil gambar + Ijinkan permintaan berlangganan + Berkas yang anda pilih bukan gambar + Terjadi kesalahan saat mengubah berkas gambar + Berkas tidak ditemukan + Kesalahan Umum I/O. Mungkin Anda kehabisan ruang penyimpanan? + Aplikasi yang digunakan untuk memilih gambar tidak memberikan izin untuk membaca file.\n\n Gunakan file manager yang berbeda untuk memilih gambar + Tidak diketahui + Sementara dimatikan + Online + Menghubungkan\u2026 + Offline + Tidak mendapat izin + Server tidak ditemukan + Tidak ada koneksi + Registrasi gagal + Username telah digunakan + Registrasi berhasil + Server tidak mendukung pendaftaran akun. + Kesalahan keamanan + Server tidak cocok + Teks biasa + OTR + OpenPGP + Ubah akun + Hapus akun + Sementara dimatikan + Publikasikan avatar + terlihat %d hari lalu + tidak pernah terlihat + Penerimaan gagal + Fingerprint Anda + OTR fingerprint + Verifikasi + Deskripsi + Conferences + Cari + Buat Kontak + Gabung Conference + Hapus Kontak + Lihat detil kontak + Blokir kontak + Lepas blokir kontak + Buat + Kontak ini sudah ada + Gabung + Alamat conference + room@conference.example.com + Simpan sebagai bookmark + Hapus bookmark + Anda + Conference tidak ditemukan + Tambah kembali + Kirim pesan pribadi ke %s + Hubungkan + Akun ini sudah ada + Selanjutnya + Informasi tambahan + Lewati + Nonaktifkan notifikasi + Nonaktifkan notifikasi untuk percakapan ini + Notifikasi telah dimatikan + Aktifkan + Conference membutuhkan password + Masukan password + Abaikan + Pengaturan enskripsi + Paksa enskripsi end-to-end + Selalu mengirim pesan terenkripsi (kecuali untuk conferences) + jangan simpan pesan terenskripsi + Peringatan: Hal ini bisa mengakibatkan hilangnya pesan + Pengaturan lanjutan + Harap berhati-hati dengan ini + Tentang Conversations + Build dan informasi lisensi + Waktu sunyi + Waktu mulai + Waktu selesai + Aktifkan waktu sunyi + Perbesar ukuran huruf + Tombol kirim menunjukan statusnya + Lainnya + menggunakan akun %s + Mengecek gambar di host HTTP + Berkas gambar telah dihapus + Anda tidak terhubung. Coba lagi nanti + Cek ukuran berkas gambar + Opsi pesan + Salin teks + Salin URL asli + Kirim lagi + URL gambar + Pesan teks + URL disalin ke clipboard + Pesan disalin ke clipboard + pengiriman gambar gagal + Pindai kode QR + Tampilkan kode QR + Tampilkan daftar blokir + Detil akun + Sedang diproses + Gagal + Coba lagi + Selesai + Terverifikasi! + Percakapan + Jaga layanan di latar depan + Cegah sistem operasi mematikan koneksi + Pilih berkas + Menerima %1$s (%2$d%% terselesaikan) + Mengunduh %s + berkas + Buka %s + mengirim (%1$d%% terselesaikan) + Menyiapkan berkas untuk transmisi + %s ditawarkan untuk mengunduh + batalkan pengiriman + pengiriman berkas gagal + Berkas sudah dihapus + Tidak ditemukan aplikasi untuk membuka berkas + Tidak dapat verifikasi fingerprint + Verifikasi secara manual + Yakin untuk memferifikasi OTR fingerprint kontak Anda? + Tampilkan tag dinamis + Tampilan read-only tag di bawah kontak + Aktifkan notifikasi + Buat conference dengan... + Tidak ada server conference ditemukan + Pembuatan conference gagal! + Conference dibuat! + Rahasia disetujui! + Ulang + Avatar akun + Salin OTR fingerprint ke clipboard + Mengambil data dari server + Tidak ada data lagi di server + Merubah... + Password diganti! + Tidak dapat mengubah password + Kirim pesan untuk memulai obrolan dienkripsi + Bertanya + Petunjuk Anda tidak boleh kosong + Rahasia bersama Anda tidak boleh kosong + Hati-hati membandingkan sidik jari yang ditunjukkan di bawah dengan sidik jari kontak Anda.\nAnda dapat mengunakan layanan komunikasi terpercaya seperti e-mail terenskripsi atau panggilan telepon untuk menukarkannya. + Ubah password + Password sekarang + Password baru + Password tidak boleh kosong + Aktifkan semua akun + Menonaktifkan semua account + Lakukan aksi dengan + Tidak ada afiliasi + Tidak ada peran + Orang buangan + Member + Mode lanjut + Memberikan keanggotaan + Cabut keanggotaan + Memberikan hak istimewa admin + Mencabut hak istimewa admin + Hapus dari conference + Tidak bisa mengubah afiliasi %s + Tendang dari conference + Anda mencoba untuk menghapus %s dari sebuah conference publik. Satu-satunya cara untuk melakukannya adalah untuk menendang pengguna ini selamanya. + Tendang sekarang + Tidak dapat merumah role %s + Conference umum + Rahasia, hanya member conference + Opsi conference + Rahasia (Hanya member) + Non Anonymous + Opsi conference dimodifikasi! + Tidak dapat merubah pengaturan conference + Tidak pernah + 30 menit + 1 jam + 2 jam + 8 jam + Sampai pemberitahuan selanjutnya + Opsi input + Enter untuk mengirim + Gunakan enter untuk mengrim pesan + Tampilkan masukan kunci + Mengubah kunci emoji untuk memasukan kunci + audio + video + Gambar + Berkas PDF + Apl Android + Kontak + Diterima %s + Nonaktifkan layanan latar belakang + Sentuh untuk membuka Conversations + Avatar telah diterbitkan! + Mengirim %s + Menawarkan %s + Sembunyikan Offline + Nonaktifkan Akun + %s sedang mengetik... + %s telah berhenti mengetik + Notifikasi ketik pesan + Biarkan kontak Anda tahu ketika Anda sedang menulis pesan baru + Kirim lokasi + Tampilkan lokasi + Tidak ada aplikasi ditemukan untuk menampilkan lokasi + Lokasi + Lokasi yang diterima + Percakapan tertutup + Tinggalkan conference + Jangan percaya sistem CA + Semua sertifikat harus disetujui secara manual + + Pilih %d kontak + + diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 2b8c5501..650e18c4 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -427,6 +427,10 @@ Geen applicatie gevonden om locatie weer te geven Locatie Locatie ontvangen + Gesprek gesloten + Groepsgesprek verlaten + Vertrouw geen systeem-CA\'s. + Alle certificaten moeten handmatig goedgekeurd worden Selecteer %d contact Selecteer %d contacten diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 58dea13b..3c58c485 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -5,8 +5,11 @@ Zarządzaj kontami Zakończ konwersację Szczegóły kontaktu - Szczególy konferencji + Szczegóły konferencji + Konwersacja szyfrowana Dodaj konto + Edytuj nazwę + Dodaj do książki telefonicznej Usuń z rostera Zablokuj kontakt Odblokuj kontakt @@ -16,6 +19,7 @@ Ustawienia Szczegóły konferencji Szczegóły kontaktu + Udostępnij przez Conversation Rozpocznij konwersację Wybierz kontakt Czarna lista @@ -25,6 +29,7 @@ nieprzeczytanych konwersacji wysyłanie... Deszyfrowanie wiadomości. Proszę czekać... + Nazwa jest już w użyciu Admin Właściciel Moderator @@ -36,12 +41,15 @@ Zablokować wszystkie kontakty z %s? Odblokować wszystkie kontakty z %s? Kontakt zablokowany + Czy usunąć zakładkę %s? Konwersacja powiązana z zakładką nie zostanie usunięta. Zarejestruj nowe konto na serwerze Zmień hasło na serwerze + Udostępnij... Rozpocznij konwersację Zaproś kontakt Kontakty Anuluj + Ustaw Dodaj Edytuj Usuń @@ -50,6 +58,7 @@ Zapisz Ok Conversations uległo awarii + Wysyłając ślady stosu pomagasz rozwijać Conversations\nUwaga: Ślad stosu zostanie przesłany deweloperowi przy użyciu twojego konta XMPP. Wyślij teraz Nie pytaj ponownie Nie można połączyć się z kontem @@ -60,30 +69,352 @@ Dodaj kontakt wysyłanie nie powiodło się odrzucono + Przygotowywanie obrazu do wysłania Wyczyść historię Wyczyść historię konwersacji + Czy na pewno usunąć wszystkie wiadomości powiązane z konwersacją?\n\nUwaga: Działanie nie wpływa na wiadomości przechowywane na innych urządzeniach lub serwerach. Usuń wiadomości + Zakończ konwersację po usunięciu historii + Wybierz widoczność dla kontaktu + Wyślij wiadomość jawną + Wyślij zaszyfrowaną wiadomość (OTR) + Wyślij zaszyfrowaną wiadomość (OpenPGP) + Twoja nazwa została zmieniona + Pobierz obraz + Wyślij bez szyfrowania + Nie można odszyfrować. Sprawdź poprawność klucza prywatnego. + OpenKeychain + Conversations używa zewnętrznej aplikacji OpenKeychain do szyfrowania wiadomości i zarządzania kluczami publicznymi.\n\nOpenKeychain rozpowszechniany jest na licencji GPLv3 przez F-Droid lub Google Play.\n\n(Zrestartuj Conversations po instalacji). + Zrestartuj + Zainstaluj + oferowanie... + oczekiwanie... + Nie znaleziono klucza OpenPGP + Conversations nie może zaszyfrować wiadomości, ponieważ kontakt nie udostępnia klucza publicznego.\n\nZasugeruj rozmówcy instalację OpenPGP. + Nie znaleziono kluczy OpenPGP + Conversations nie może zaszyfrować wiadomości, ponieważ kontakty nie udostępniają kluczy publicznych.\n\nZasugeruj rozmówcom instalację OpenPGP. + Otrzymano zaszyfrowaną wiadomość. Dotknij, aby odszyfrować i wyświetlić. + Główne + Zasób XMPP + Nazwa identyfikująca urządzenie + Akceptuj pliki + Automatycznie akceptuj pliki mniejsze niż... + Ustawienia powiadamiania + Powiadomienia + Powiadamiaj, gdy nadejdzie wiadomość + Wibracje + Wibruj, gdy nadejdzie wiadomość + Dźwięk + Odtwórz dźwięk z powiadomieniem + Powiadomienia konferencji + Zawsze powiadamiaj o nowej wiadomości w konferencji + Opóźnienie powiadomień + Wyłącz powiadomienia przez krótki czas po otrzymaniu kopii wiadomości + Opcje zaawansowane + Nie wysyłaj raportów awarii + Wysyłając ślady stosu pomagasz rozwijać Conversations + Potwierdzenia wiadomości + Powiadamiaj kontakty o otrzymaniu lub przeczytaniu wiadomości + Ustawienia interfejsu + Wystąpił błąd OpenKeychain + Błąd podczas deszyfrowania pliku + Akceptuj + Wystąpił błąd + Zezwól na powiadomienia obecności + Automatycznie zezwalaj i pytaj o powiadomienia obecności, kiedy utworzysz kontakt + Subskrypcje + Twoje konto + Klucze + Wysyłaj powiadomienia obecności + Otrzymuj powiadomienia obecności + Poproś o powiadomienia obecności + Wybierz obraz + Zrób zdjęcie + Automatyczne powiadomienia obecności + Wybrany plik nie jest obrazem + Błąd kompresji obrazu + Nie odnaleziono pliku + Ogólny błąd wejścia/wyjścia + Aplikacja użyta do wyboru obrazu nie zezwoliła na odczyt pliku.\n\nWybierz obraz przy użyciu innego menedżera plików + nieznany + Tymczasowo wyłączono + Połączono + Łączenie... + Rozłączono + Błąd uwierzytelnienia + Nie odnaleziono serwera + Brak połączenia + Błąd rejestracji + Nazwa jest już w użyciu + Zarejestrowano pomyślnie + Serwer nie umożliwia rejestracji + Błąd zabezpieczeń + Serwer niekompatybilny + Tekst jawny + OTR + OpenPGP + Edytuj konto + Usuń konto + Wyłącz tymczasowo + Publikuj awatar + Udostępnij klucz publiczny OpenPGP + Włącz konto + Czy na pewno? + Wraz z kontem zostanie nieodwracalnie usunięta powiązana historia konwersacji. + Nagraj głos + Jabber ID + Hasło + username@example.com + Potwierdź hasło + Hasło + Potwierdź hasło + Hasła są niezgodne + Wprowadzono niepoprawny Jabber ID + Brak pamięci, obraz jest za duży + Czy chcesz dodać kontakt %s do książki telefonicznej? + dostępny + chętny do rozmowy + zaraz wracam + będę później + nie przeszkadzać + niedostępny + Konferencja + Pozostali uczestnicy + Informacje o serwerze + XEP-0313: MAM + XEP-0280: Kopie wiadomości + dostępny + niedostępny + Brak informacji o kluczu publicznym + widziany chwilę temu + widziany minutę temu + widziany %d minut(y) temu + widziany godzinę temu + widziany %d godzin(y) temu + widziany wczoraj + widziany %d dni temu + nigdy nie widziany + Wiadomość zaszyfrowana. Zainstaluj OpenKeychain, żeby odszyfrować. + Nieznany odcisk klucza OTR + Znaleziono wiadomości zaszyfrowane przez OpenPGP + Twój odcisk klucza + Odcisk klucza OTR + Weryfikuj + Odszyfruj + Konferencje + Szukaj + Utwórz kontakt + Dołącz do konferencji + Usuń kontakt + Szczegóły kontaktu + Zablokuj kontakt + Odblokuj kontakt + Utwórz + Kontakt już istnieje + Dołącz + Adres konferencji + room@conference.example.com + Dodaj jako zakładkę + Usuń zakładkę + Zakładka już istnieje + Ty + Edytuj temat konferencji + Nie znaleziono konferencji + Opuść pokój + Kontakt został dodany do listy + Dodaj ponownie + %s przeczytał do tego miejsca + Publikuj + Naciśnij awatar, żeby wybrać obraz z galerii + Uwaga: Obraz będzie widoczny dla wszystkich kontaktów, którym udostępniasz powiadomienia o obecności. + Publikowanie... + Serwer odrzucił żądanie publikacji + Wystąpił błąd podczas konwersji obrazu + Nie udało się zapisać obrazu w pamięci urządzenia + Serwer nie udostępnia możliwości publikacji awatarów + do %s + Wyślij prywatną wiadomość do %s + Połącz + Konto już istnieje + Dalej + Połączono + Dodatkowe informacje + Pomiń + Wyłącz powiadomienia + Wyłącz powiadomienia tej konwersacji + Powiadomienia są wyłączone + Włącz + Konferencja jest zabezpieczona hasłem + Wprowadź hasło + Kontakt nie udostępnia powiadomień o obecności + Zażądaj teraz + Usuń odcisk klucza + Czy na pewno chcesz usunąć odcisk klucza? + Ignoruj + Ustawienia szyfrowania + Wymuszaj szyfrowanie typu end-to-end + Szyfruj wszystkie wiadomości (poza konferencjami) + Nie zapisuj zaszyfrowanych wiadomości + Uwaga: Może powodować utratę wiadomości + Ustawienia zaawansowane + Modyfikuj ustawienia ostrożnie + O Conversations + Informacje o kompilacji i licencji + Godziny ciszy + Początek + Koniec + Włącz godziny ciszy + Powiadomienia będą wyciszone w wybranym przedziale czasu + Większy rozmiar czcionki + Używaj większego rozmiaru czcionki w aplikacji + Przycisk wysyłania wskazuje status + Raporty dostarczenia + Jeżeli to możliwe, oznaczaj dostarczone wiadomości zielonym haczykiem + Koloruj przycisk wysyłania w zależności od statusu kontaktu + Inne opcje + Nazwa konferencji + Nazywaj konferencję tematem zamiast Jabber ID + Odcisk klucza OTR został skopiowany do schowka + Zbanowano cię w konferencji + To jest zamknięty pokój + Wyrzucono cię z konferencji + Sprawdzanie obrazka na hoście HTTP + Obraz został usunięty + Brak połączenia. Spróbuj ponownie później + Sprawdź rozmiar pliku + Opcje wiadomości + Skopiuj tekst + Skopiuj oryginalny URL + Wyślij ponownie + URL obrazu + Treść wiadomości + URL obrazu został skopiowany do schowka + Wiadomość została skopiowana do schowka + Błąd podczas przesyłania obrazu + Zeskanuj kod QR + Pokaż kod QR + Wyświetl listę banów + Szczegóły konta + Weryfikuj OTR + Zdalny odcisk klucza + (lub zetknij telefony) + Protokół socialist millionaire + Podpowiedź lub pytanie + Wspólny sekret + Potwierdź + W toku + Odpowiedz + Sekrety są niezgodne + Spróbuj ponownie + Zakończ + Weryfikacja udana! + Kontakt zażądał weryfikacji SMP + Brak ważnej sesji OTR! + Conversations + Usługa na pierwszym planie + Uniemożliwia systemowi przerwanie połączenia + Wybierz plik + Odbieranie %1$s (ukończono %2$d%%) + Pobierz %s + plik + Otwórz %s + Wysyłanie (ukończono %1$d%%) + Przygotowywanie pliku do wysłania + Zaproponowano pobranie pliku %s + Anuluj przesyłanie + Przesyłanie pliku nie powiodło się + Plik został usunięty + Nie odnaleziono aplikacji skojarzonej z typem pliku + Weryfikacja odcisku klucza nieudana + Weryfikuj ręcznie + Czy na pewno chcesz zweryfikować odcisk klucza OTR kontaktu? + Etykiety kontaktów + Wyświetlaj etykiety pod kontaktami + Włącz powiadomienia + Utwórz konferencję... + Nie odnaleziono serwera konferencji + Nie udało się utworzyć konferencji! + Konferencja została utworzona! + Sekret został zaakceptowany! + Resetuj + Awatar konta + Skopiuj odcisk klucza OTR do schowka + Pobieranie historii z serwera + Koniec historii na serwerze + Aktualizowanie... + Hasło zostało zmienione! + Nie udało się zmienić hasła + Wyślij wiadomość, żeby rozpocząć szyfrowaną rozmowę + Zadaj pytanie + Jeśli ty i twój kontakt macie jakiś wspólny sekret, którego nie zna nikt inny (żart znany tylko wam lub po prostu co jedliście ostatnim razem, gdy się widzieliście) możecie użyć tego sekretu by zweryfikować wzajemnie odciski swoich kluczy.\n\nPodasz podpowiedź lub pytanie dla twojego kontaktu i otrzymasz odpowiedź (wielkość liter ma znaczenie). + Twój kontakt chciałby zweryfikować odcisk Twojego klucza poprzez sprawdzenie znajomości wspólnego sekretu. Twój znajomy przedstawił następującą podpowiedź lub pytanie dotyczącego tego sekretu. + Wskazówka nie powinna być pusta + Sekret nie może być pusty + Ostrożnie porównaj odcisk klucza pokazany poniżej z odciskiem klucza twojego kontaktu.\nMożesz użyć bezpiecznego kanału komunikacji takiego, jak szyfrowany e-mail lub rozmowa telefoniczna, by wymienić odciski klucza. Zmień hasło Obecne hasło Nowe hasło Hasło nie może być puste Aktywuj wszystkie konta Wyłącz wszystkie konta + Użyj + Brak stanowiska + Brak funkcji + Wykluczony + Członek + Tryb zaawansowany + Przyznaj członkostwo + Cofnij członkostwo + Przyznaj uprawnienia administratora + Odbierz uprawnienia administratora + Usuń z konferencji + Nie udało się zmienić stanowiska dla %s + Zbanuj uczestnika konferencji + Próbujesz usunąć %s z publicznego pokoju. Jedyny sposób, by to zrobić, to wykluczyć tego użytkownika na zawsze. + Zbanuj teraz + Nie udało się zmienić funkcji %s + Konferencja publiczna + Konferencja prywatna, dla zaakceptowanych uczestników + Opcje konferencji + Prywatna (tylko zaakceptowani) + Opcje konferencji zostały zmienione! + Nie udało się zmienić opcji konferencji Nigdy 30 minut 1 godzina 2 godziny 8 godzin + Ręcznie + Ustawienia wprowadzania + Enter wysyła Używaj klawisza Enter do wysyłania wiadomości Pokaż klawisz Enter Zamień klawisz emotikon na klawisz Enter plik audio plik wideo obraz + Dokument PDF + Aplikacja Androida Kontakt Odebrano %s + Wyłącz podtrzymanie pierszego planu usługi + Dotknij, aby otworzyć Conversations Avatar został pomyślnie opublikowany! Wysyłanie %s Oferowanie %s Ukryj niedostępnych + Wyłącz konto + %s pisze... + %s przestał(a) pisać + Powiadomienia pisania + Powiadamiaj rozmówcę, kiedy rozpoczynasz nową wiadomość + Wyślij lokalizację + Pokaż lokalizację + Nie odnaleziono aplikacji do wyświetlenia lokalizacji + Lokalizacja + Otrzymano lokalizację + Zamknięto konwersację + Opuszczono konferencję + Nie ufaj certyfikatom systemowym + Wymagaj ręcznego potwierdzania certyfikatów diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 4a96a7fe..0f3ec4c7 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -11,6 +11,10 @@ Редактировать контакт Добавить в телефонную книгу Удалить из списка + Заблокировать контакт + Разблокировать контакт + Заблокировать домен + Разблокировать домен Управление Аккаунтами Настройки Сведения о Конференции @@ -18,6 +22,7 @@ Поделиться Начать беседу Выберите собеседника + Черный список только что 1 минуту назад %d мин. назад @@ -31,16 +36,25 @@ Участник Посетитель Вы хотите удалить %s из своего списка? Беседы, связанные с этим аккаунтом будут сохранены. + Вы хотите заблокировать дальнейшие сообщения от %s? + Вы хотите разблокировать пользователя %s? + Заблокировать всех пользователей домена %s? + Разблокировать всех пользователей домена %s? + Контакт заблокирован Вы хотите удалить %s из избранного? Беседы, связанные с данной закладкой будут сохранены Создать новый аккаунт на сервере + Изменить пароль на сервере Поделиться с Начать беседу Пригласить собеседника Контакты Отмена + Установить Добавить Редактировать Удалить + Заблокировать + Разблокировать Сохранить ОК Conversations был неожиданно остановлен @@ -134,6 +148,8 @@ Имя пользователя уже используется Регистрация завершена Сервер не поддерживает регистрацию + Ошибка безопасности + Несовместимый сервер Без шифрования OTR OpenPGP @@ -164,8 +180,13 @@ не в сети Конференция Другие участники + Информация о сервере + XEP-0313: Сохранение сообщений в архив Дублирование сообщений - Управление потоками + XEP-0352: Индикатор Состояния Клиента + XEP-0191: Команда Блокирования + XEP-0237: Управление версиями списков + XEP-0198: Управление потоками XEP-0163: PEP (Аватары) доступен недоступен @@ -192,6 +213,8 @@ Присоединиться к конференции Удалить Контакт Посмотреть данные контакта + Заблокировать контакт + Разблокировать контакт Создать Контакт уже существует Присоединиться @@ -245,8 +268,19 @@ Внимание: Это может привести к потере сообщений Расширенные настройки Пожалуйста, будьте осторожны с данными настройками + О Conversations + Информация о билде и лицензировании + Тихие Часы + Начало + Окончание + Включить режим «тихих часов» + Уведомления будут отключены во время «тихих часов» Увеличить размер шрифта Установите больший размер шрифта по всей программе Использовать кнопку-индикатор + Запрос в получении сообщения + Если поддерживается, поступившие сообщения будут отмечены зеленой галочкой Раскрасить кнопку отправить, указывая текущий статус собеседника + Другие + Название конференции -- cgit v1.2.3 From e9783b80d18c5d1b64090d7e6fa4cf1e6b95f177 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Apr 2015 10:13:28 +0200 Subject: added missing translations from transifex --- src/main/res/values-ar-rEG/strings.xml | 1 - src/main/res/values-bg/strings.xml | 6 +++++- src/main/res/values-ca/strings.xml | 1 - src/main/res/values-es/strings.xml | 6 +++++- src/main/res/values-eu/strings.xml | 3 ++- src/main/res/values-fr/strings.xml | 1 - src/main/res/values-it/strings.xml | 1 - src/main/res/values-ja/strings.xml | 4 ++++ src/main/res/values-sk/strings.xml | 1 - src/main/res/values-sr/strings.xml | 4 ++++ src/main/res/values-sv/strings.xml | 4 ++++ 11 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/res/values-ar-rEG/strings.xml b/src/main/res/values-ar-rEG/strings.xml index 3acf8e54..35eff49f 100644 --- a/src/main/res/values-ar-rEG/strings.xml +++ b/src/main/res/values-ar-rEG/strings.xml @@ -260,7 +260,6 @@ لايمكن تغيير كلمة السر ارسل رساله لبدأ محادثة مشفّرة أسال سؤال - إذا كنت و جهة اتصالك لديكم سر مشترك غير معروف لأحد آخر (مثل جملة مكرره بينكم او تاريخ ما يخصكم كتاريخ آخر لقاء بينكم ) استخدماه للتحقق من بصمات الأصابع \n\n عليك توفير تلميحا أو سؤال لجهة الإتصال بك للحصول على تلك الإجابه وبدأ التواصل سترغب جهة الإتصال بتأكيد بصمتك عبر السر المشترك بينكما لذلك أخبره تلميحا أو إسأله سؤالا يذكره بالسر ليكتبه برده التلميح الذي يراه صديقك لا يمكن ان يكون فارغ السر المشترك بينكما لا يمكن ان يترك فارغا !! diff --git a/src/main/res/values-bg/strings.xml b/src/main/res/values-bg/strings.xml index 2f89f3ae..b4810f51 100644 --- a/src/main/res/values-bg/strings.xml +++ b/src/main/res/values-bg/strings.xml @@ -359,7 +359,7 @@ Неуспешна промяна на паролата Изпратете съобщение, за да започнете нешифрован разговор Задаване на въпрос - Ако Вие и контакта Ви имате някаква тайна информация, която никой друг не знае (като някаква шега или пък просто какво сте обядвали, когато сте се срещнали за последно), можете да я използвате, за да проверите отпечатъците си един на друг.\n\nМожете да подсигурите подсказка или въпрос, на който контакта Ви да отговори, като има предвид, че главните и малките букви се броят за различни. + Ако Вие и контактът Ви имате някаква тайна информация, която никой друг не знае (като някаква шега или пък просто какво сте обядвали, когато сте се срещнали за последно), можете да я използвате, за да проверите отпечатъците си един на друг.\n\nМожете да подсигурите подсказка или въпрос, на който контактът Ви да отговори, като има предвид, че главните и малките букви се броят за различни. Вашият контакт би искал да провери отпечатъка Ви, като Ви попита за обща тайна информация. Контактът Ви предостави следната подсказка или въпрос, който да Ви насочи към тази тайна. Подсказката Ви не трябва да е празна Общата Ви тайна не може да е празна @@ -427,6 +427,10 @@ Няма намерено приложение за показване на местоположението Местоположение Получено местоположение + Conversation се затвори + Напуснахте беседата + Да не се вярва на системните сертификати + Всички сертификати трябва да бъдат одобрени на ръка Изберете %d контакт Изберете %d контакта diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml index e50fa740..a0861b16 100644 --- a/src/main/res/values-ca/strings.xml +++ b/src/main/res/values-ca/strings.xml @@ -359,7 +359,6 @@ No s\'ha pogut canviar la contrasenya Començar a enviar un missatge de conversació xifrat Fer una pregunta - Si vosté i el seu contacte tenen un secret en comú que ningú més sap (com una broma o simplement el que tenia per dinar l\'última vegada que es va trobar) pot utilitzar aquest secret per comprovar les empremtes dactilars de cadascú. \ n\ n Proporcionarás una pista o una pregunta per a la seu contacte que respondrà amb una resposta entre majúscules i minúscules. El seu contacte l\'hi agradaria verificar la seva empremta digital per un repte amb un secret compartit.El seu contacte proporciona el següent suggeriment o pregunta per aquest secret. El seu suggeriment no pot estar buit El teu secret compartit no pot estar buit diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 44d8abb2..d7c6a885 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -359,7 +359,7 @@ No se puede cambiar la contraseña Enviar mensaje para empezar una conversación cifrada Haz una pregunta - Si tu contacto y tú tenéis un secreto en común que nadie más sabe (como un pequeño juego o broma o simplemente lo que tomasteis para comer la última vez os visteis) podéis usar ese secreto para verificar la huella digital de cada uno.\n\nPuedes usar una sugerencia o pregunta para hacer a tu contacto que deberá responder distinguiendo mayúsculas y minúsculas. + Si tu contacto y tú tenéis un secreto en común que nadie más sabe (como una broma o simplemente lo que tomasteis para comer la última vez que os visteis) podéis usar ese secreto para verificar la huella digital de cada uno.\n\nPuedes usar una sugerencia o pregunta para hacer a tu contacto que deberá responder distinguiendo mayúsculas y minúsculas. Tu contacto quiere verificar tu huella digital a través de un secreto compartido. Te hace la siguiente sugerencia o pregunta para ese secreto. La pregunta no puede ser vacía El secreto compartido no puede ser vacío @@ -427,6 +427,10 @@ No se ha encontrado ninguna aplicación para mostrar la ubicación Ubicación Ubicación recibida + Conversación cerrada + Has salido de la conversación + No confiar en los CAs del sistema + Todos los certificados deben ser aprobados manualmente Seleccionado %d contacto Seleccionados %d contactos diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index b6d1fa3c..3c9dee1b 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -359,7 +359,6 @@ Pasahitza ezin izan da aldatu Mezu bat bidali enkripatutako elkarrizketa hasteko Galdetu - Zu eta zure kontaktua beste inor ezagutzen ez duen elkarren arteko sekreturen bat baduzue (ohiko txantxa edo azkenengo aldian bazkaldu zenutena adibidez) bakoitzaren hatz-markak egiaztatzeko sekretu hori erabili dezakezue.\n\nIradokizun edo galdera bat eman behar duzu zure kontaktuak erantzun dezan, letra larri eta xeheak bereiziz. Zure kontaktuak zure hatz-marka egiaztatu nahi du partekatutako sekretu batekin erronka eginez. Zure kontaktuak hurrengo iradokizuna edo sekretu horren galdera eman du. Zure iradokizuna ez luke hutsik egon behar Zure partekatutako sekretua ezin da hutsik egon @@ -427,6 +426,8 @@ Kokapena erakutsi dezakeen aplikaziorik ez da aurkitu Kokapena Kokapena jaso da + Elkarrizketa itxi egin da + Konferentzia utzi egin da Hautatu kontaktu %d Hautatu %d kontaktu diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 47c28517..4baef67f 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -359,7 +359,6 @@ Impossible de changer le mot de passe Envoyez un message pour commencer la conversation chiffrée Poser une question - Si vous et votre contact avez un secret en commun connu par vous deux uniquement (comme une histoire personnelle ou même comme ce que vous avez mangé lors de votre dernière rencontre) vous pouvez utiliser ce secret pour vérifier vos empreintes respectives.\n\nVous envoyez un indice ou une question à votre contact qui devra répondre en faisant attention à la casse. Votre contact voudrait vous identifier de manière sûre grâce à un secret commun. Il vous envoie le message ou la question suivante. Votre indice ne devrait pas être vide Votre secret ne peut être vide diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index c32e9585..836dced8 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -357,7 +357,6 @@ Impossibile cambiare la password Invia un messaggio per avviare una conversazione cifrata Fai una domanda - Se tu ed il tuo contatto avete un segreto in comune che nessun’altro conosce (come uno scherzo o semplicemente ciò che avete mangiato a pranzo l’ultima volta che vi siete incontrati), potete usare quel segreto per dimostrare la vostra identità reciprocamente.\n\nFornisci un suggerimento o una domanda al tuo contatto che ti risponderà con una domanda Case Sensitive. Il tuo contatto vorrebbe verificare la tua identità. Dovrai rispondere correttamente alla sua domanda con una risposta che condividete. Il tuo contatto ti ha fornito il suggerimento o la domanda seguente. Il suggerimento non dovrebbe essere vuoto Il segreto condiviso non può essere vuoto diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index baffa088..0996334e 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -427,6 +427,10 @@ 位置を表示するアプリケーションが見つかりません 位置 位置を受信しました + 会話が閉じられました + 退出した会話 + システムの CA を信頼しない + すべての証明書を手動で承認する必要があります %d 連絡先を選択 diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index cb45b4aa..e66bfd19 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -359,7 +359,6 @@ Nepodarilo sa zmeniť heslo Poslať správu pre spustenie šifrovaného chatu Položiť otázku - Ak máte vy a váš kontakt spoločné tajomstvo, ktoré nikto iný nepozná (napríklad spoločný vtip alebo čo ste mali na obed na vašom poslednom stretnutí), môžete ho použiť na overenie vzájomných identifikátorov.\n\nZadáte pomôcku alebo otázku a kontakt na ňu správne odpovie. Váš kontakt by chcel overiť váš identifikátor pomocou spoločného tajomstva. Váš kontakt zadal nasledujúcu pomôcku alebo otázku týkajúcu sa tajomstva. Vaša pomôcka by nemala byť prázdna Vaše spoločné tajomstvo nemôže byť prázdne diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 052463c8..3b632cdb 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -427,6 +427,10 @@ Нема апликације за приказ локације Локација Примљена локација + Преписка затворена + Напусти конференцију + Не веруј системским сертификационим телима + Сви сертификати морају ручно да се одобре Изабери %d контакт Изабери %d контакта diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index 874de244..b411f484 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -427,6 +427,10 @@ Kunde inte hitta applikation för att visa position Position Mottog position + Konversation stängd + Lämnade konferens + Lita inte på systemets CAs + Alla certifikat måste manuellt godkännas Välj %d kontakt Välj %d kontakter -- cgit v1.2.3 From 3a627f72fbc5f51efaf3d8723fc7ce883f2f6e83 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Apr 2015 18:36:11 +0200 Subject: fixed direct invites --- .../siacs/conversations/parser/MessageParser.java | 40 +++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 8ae9b642..76d01468 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -391,15 +391,17 @@ public class MessageParser extends AbstractParser implements private void parseNonMessage(Element packet, Account account) { final Jid from = packet.getAttributeAsJid("from"); + if (account.getJid().equals(from)) { + return; + } if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) { mXmppConnectionService.updateConversationUi(); } - Element invite = extractInvite(packet); - if (invite != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, from, true); + Invite invite = extractInvite(packet); + if (invite != null && invite.jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); if (!conversation.getMucOptions().online()) { - Element password = invite.findChild("password"); - conversation.getMucOptions().setPassword(password == null ? null : password.getContent()); + conversation.getMucOptions().setPassword(invite.password); mXmppConnectionService.databaseBackend.updateConversation(conversation); mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); @@ -439,16 +441,30 @@ public class MessageParser extends AbstractParser implements } } - private Element extractInvite(Element message) { - Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); - if (x == null) { - x = message.findChild("x","jabber:x:conference"); + private class Invite { + Jid jid; + String password; + Invite(Jid jid, String password) { + this.jid = jid; + this.password = password; } - if (x != null && x.hasChild("invite")) { - return x; + } + + private Invite extractInvite(Element message) { + Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); + if (x != null) { + Element invite = x.findChild("invite"); + if (invite != null) { + Element pw = x.findChild("password"); + return new Invite(message.getAttributeAsJid("from"), pw != null ? pw.getContent(): null); + } } else { - return null; + x = message.findChild("x","jabber:x:conference"); + if (x != null) { + return new Invite(x.getAttributeAsJid("jid"),x.getAttribute("password")); + } } + return null; } private void parseEvent(final Element event, final Jid from, final Account account) { -- cgit v1.2.3 From d6443d9b2f4654a0724ca273c81f400730b644c1 Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Tue, 21 Apr 2015 22:17:58 +0200 Subject: OTR: Fix onContactStatusChanged & dont archive OTR - Fix session handling on contact status change: Do not reset potentially active sessions; check peer's OTR-resource on disconnect - use no-permanent-store hint instead of no-store to ensure finished messages are delivered to offline/disconnected clients - add no-permanent-store to ask compliant servers not to archive OTR messages --- .../eu/siacs/conversations/crypto/OtrEngine.java | 2 +- .../conversations/generator/MessageGenerator.java | 1 + .../services/XmppConnectionService.java | 20 +++++++++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 263f6089..0dc7c37e 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -182,7 +182,7 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { packet.setBody(body); packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); - packet.addChild("no-store", "urn:xmpp:hints"); + packet.addChild("no-permanent-store", "urn:xmpp:hints"); try { Jid jid = Jid.fromSessionID(session); diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index a60c5613..474a3e1d 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -71,6 +71,7 @@ public class MessageGenerator extends AbstractGenerator { MessagePacket packet = preparePacket(message, addDelay); packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); + packet.addChild("no-permanent-store", "urn:xmpp:hints"); try { packet.setBody(otrSession.transformSending(message.getBody())[0]); return packet; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3e8ce65f..9ffffe0f 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -36,6 +36,7 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -174,13 +175,22 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onContactStatusChanged(Contact contact, boolean online) { Conversation conversation = find(getConversations(), contact); if (conversation != null) { - if (online && contact.getPresences().size() > 1) { + if (online) { conversation.endOtrIfNeeded(); + if (contact.getPresences().size() == 1) { + sendUnsentMessages(conversation); + } } else { - conversation.resetOtrSession(); - } - if (online && (contact.getPresences().size() == 1)) { - sendUnsentMessages(conversation); + if (contact.getPresences().size() >= 1) { + if (conversation.hasValidOtrSession()) { + String otrResource = conversation.getOtrSession().getSessionID().getUserID(); + if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) { + conversation.endOtrIfNeeded(); + } + } + } else { + conversation.endOtrIfNeeded(); + } } } } -- cgit v1.2.3 From 5e1492fbff8c8377abedac776405a09424a6a20e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 23 Apr 2015 17:37:47 +0200 Subject: send invite to other instanzes after creating ad hoc conference. fixes #1136 --- .../eu/siacs/conversations/services/XmppConnectionService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3e8ce65f..c0b609f3 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1537,6 +1537,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa for (Jid invite : jids) { invite(conversation, invite); } + if (account.countPresences() > 1) { + directInvite(conversation, account.getJid().toBareJid()); + } if (callback != null) { callback.success(conversation); } @@ -2022,6 +2025,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa sendMessagePacket(conversation.getAccount(), packet); } + public void directInvite(Conversation conversation, Jid jid) { + MessagePacket packet = mMessageGenerator.directInvite(conversation,jid); + sendMessagePacket(conversation.getAccount(),packet); + } + public void resetSendingToWaiting(Account account) { for (Conversation conversation : getConversations()) { if (conversation.getAccount() == account) { -- cgit v1.2.3 From d07baccf9722a464111273f7a364139ce534fad4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 25 Apr 2015 14:08:24 +0200 Subject: cleaned up file handling --- .../conversations/persistance/FileBackend.java | 138 ++++++++++++--------- .../xmpp/jingle/JingleInbandTransport.java | 3 + .../xmpp/jingle/JingleSocks5Transport.java | 17 ++- 3 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index c499d499..cb79b0e9 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.persistance; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -42,8 +43,7 @@ public class FileBackend { private static int IMAGE_SIZE = 1920; - private SimpleDateFormat imageDateFormat = new SimpleDateFormat( - "yyyyMMdd_HHmmssSSS", Locale.US); + private final SimpleDateFormat imageDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); private XmppConnectionService mXmppConnectionService; @@ -110,9 +110,7 @@ public class FileBackend { scalledW = size; scalledH = (int) (h / ((double) w / size)); } - Bitmap scalledBitmap = Bitmap.createScaledBitmap(originalBitmap, - scalledW, scalledH, true); - return scalledBitmap; + return Bitmap.createScaledBitmap(originalBitmap, scalledW, scalledH, true); } else { return originalBitmap; } @@ -148,31 +146,34 @@ public class FileBackend { } public DownloadableFile copyFileToPrivateStorage(Message message, Uri uri) throws FileCopyException { + Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage"); + String mime = mXmppConnectionService.getContentResolver().getType(uri); + String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime); + message.setRelativeFilePath(message.getUuid() + "." + extension); + DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message); + file.getParentFile().mkdirs(); + OutputStream os = null; + InputStream is = null; try { - Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage"); - String mime = mXmppConnectionService.getContentResolver().getType(uri); - String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime); - message.setRelativeFilePath(message.getUuid() + "." + extension); - DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message); - file.getParentFile().mkdirs(); - file.createNewFile(); - OutputStream os = new FileOutputStream(file); - InputStream is = mXmppConnectionService.getContentResolver().openInputStream(uri); + if (!file.createNewFile()) { + throw new FileCopyException(R.string.error_io_exception); + } + os = new FileOutputStream(file); + is = mXmppConnectionService.getContentResolver().openInputStream(uri); byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) > 0) { + int length; + while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); - } + } os.flush(); - os.close(); - is.close(); - Log.d(Config.LOGTAG, "output file name " + mXmppConnectionService.getFileBackend().getFile(message)); - return file; - } catch (FileNotFoundException e) { - throw new FileCopyException(R.string.error_file_not_found); } catch (IOException e) { throw new FileCopyException(R.string.error_io_exception); + } finally { + close(os); + close(is); } + Log.d(Config.LOGTAG, "output file name " + mXmppConnectionService.getFileBackend().getFile(message)); + return file; } public DownloadableFile copyImageToPrivateStorage(Message message, Uri image) @@ -182,40 +183,41 @@ public class FileBackend { private DownloadableFile copyImageToPrivateStorage(Message message, Uri image, int sampleSize) throws FileCopyException { + DownloadableFile file = getFile(message); + file.getParentFile().mkdirs(); + InputStream is = null; + OutputStream os = null; try { - InputStream is = mXmppConnectionService.getContentResolver() - .openInputStream(image); - DownloadableFile file = getFile(message); - file.getParentFile().mkdirs(); - file.createNewFile(); + if (!file.createNewFile()) { + throw new FileCopyException(R.string.error_io_exception); + } + is = mXmppConnectionService.getContentResolver().openInputStream(image); + os = new FileOutputStream(file); + Bitmap originalBitmap; BitmapFactory.Options options = new BitmapFactory.Options(); int inSampleSize = (int) Math.pow(2, sampleSize); - Log.d(Config.LOGTAG, "reading bitmap with sample size " - + inSampleSize); + Log.d(Config.LOGTAG, "reading bitmap with sample size " + inSampleSize); options.inSampleSize = inSampleSize; originalBitmap = BitmapFactory.decodeStream(is, null, options); is.close(); if (originalBitmap == null) { throw new FileCopyException(R.string.error_not_an_image_file); } - Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE); - originalBitmap = null; + Bitmap scaledBitmap = resize(originalBitmap, IMAGE_SIZE); int rotation = getRotation(image); if (rotation > 0) { - scalledBitmap = rotate(scalledBitmap, rotation); + scaledBitmap = rotate(scaledBitmap, rotation); } - OutputStream os = new FileOutputStream(file); - boolean success = scalledBitmap.compress( - Bitmap.CompressFormat.WEBP, 75, os); + + boolean success = scaledBitmap.compress(Bitmap.CompressFormat.WEBP, 75, os); if (!success) { throw new FileCopyException(R.string.error_compressing_image); } os.flush(); - os.close(); long size = file.getSize(); - int width = scalledBitmap.getWidth(); - int height = scalledBitmap.getHeight(); + int width = scaledBitmap.getWidth(); + int height = scaledBitmap.getHeight(); message.setBody(Long.toString(size) + ',' + width + ',' + height); return file; } catch (FileNotFoundException e) { @@ -223,8 +225,7 @@ public class FileBackend { } catch (IOException e) { throw new FileCopyException(R.string.error_io_exception); } catch (SecurityException e) { - throw new FileCopyException( - R.string.error_security_exception_during_image_copy); + throw new FileCopyException(R.string.error_security_exception_during_image_copy); } catch (OutOfMemoryError e) { ++sampleSize; if (sampleSize <= 3) { @@ -232,23 +233,24 @@ public class FileBackend { } else { throw new FileCopyException(R.string.error_out_of_memory); } + } finally { + close(os); + close(is); } } private int getRotation(Uri image) { + InputStream is = null; try { - InputStream is = mXmppConnectionService.getContentResolver() - .openInputStream(image); + is = mXmppConnectionService.getContentResolver().openInputStream(image); return ExifHelper.getOrientation(is); } catch (FileNotFoundException e) { return 0; + } finally { + close(is); } } - public Bitmap getImageFromMessage(Message message) { - return BitmapFactory.decodeFile(getFile(message).getAbsolutePath()); - } - public Bitmap getThumbnail(Message message, int size, boolean cacheOnly) throws FileNotFoundException { Bitmap thumbnail = mXmppConnectionService.getBitmapCache().get( @@ -257,8 +259,7 @@ public class FileBackend { File file = getFile(message); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = calcSampleSize(file, size); - Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(), - options); + Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(),options); if (fullsize == null) { throw new FileNotFoundException(); } @@ -271,13 +272,11 @@ public class FileBackend { public Uri getTakePhotoUri() { StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(Environment - .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)); + pathBuilder.append(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)); pathBuilder.append('/'); pathBuilder.append("Camera"); pathBuilder.append('/'); - pathBuilder.append("IMG_" + this.imageDateFormat.format(new Date()) - + ".jpg"); + pathBuilder.append("IMG_" + this.imageDateFormat.format(new Date()) + ".jpg"); Uri uri = Uri.parse("file://" + pathBuilder.toString()); File file = new File(uri.toString()); file.getParentFile().mkdirs(); @@ -325,13 +324,13 @@ public class FileBackend { String filename = getAvatarPath(avatar.getFilename()); file = new File(filename + ".tmp"); file.getParentFile().mkdirs(); + OutputStream os = null; try { file.createNewFile(); - FileOutputStream mFileOutputStream = new FileOutputStream(file); + os = new FileOutputStream(file); MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); - DigestOutputStream mDigestOutputStream = new DigestOutputStream( - mFileOutputStream, digest); + DigestOutputStream mDigestOutputStream = new DigestOutputStream(os, digest); mDigestOutputStream.write(avatar.getImageAsBytes()); mDigestOutputStream.flush(); mDigestOutputStream.close(); @@ -349,6 +348,8 @@ public class FileBackend { return false; } catch (NoSuchAlgorithmException e) { return false; + } finally { + close(os); } } avatar.size = file.length(); @@ -356,8 +357,7 @@ public class FileBackend { } public String getAvatarPath(String avatar) { - return mXmppConnectionService.getFilesDir().getAbsolutePath() - + "/avatars/" + avatar; + return mXmppConnectionService.getFilesDir().getAbsolutePath()+ "/avatars/" + avatar; } public Uri getAvatarUri(String avatar) { @@ -368,10 +368,11 @@ public class FileBackend { if (image == null) { return null; } + InputStream is = null; try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = calcSampleSize(image, size); - InputStream is = mXmppConnectionService.getContentResolver().openInputStream(image); + is = mXmppConnectionService.getContentResolver().openInputStream(image); Bitmap input = BitmapFactory.decodeStream(is, null, options); if (input == null) { return null; @@ -384,6 +385,8 @@ public class FileBackend { } } catch (FileNotFoundException e) { return null; + } finally { + close(is); } } @@ -391,10 +394,11 @@ public class FileBackend { if (image == null) { return null; } + InputStream is = null; try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = calcSampleSize(image,Math.max(newHeight, newWidth)); - InputStream is = mXmppConnectionService.getContentResolver().openInputStream(image); + is = mXmppConnectionService.getContentResolver().openInputStream(image); Bitmap source = BitmapFactory.decodeStream(is, null, options); int sourceWidth = source.getWidth(); @@ -414,8 +418,11 @@ public class FileBackend { return dest; } catch (FileNotFoundException e) { return null; + } catch (IOException e) { + return null; + } finally { + close(is); } - } public Bitmap cropCenterSquare(Bitmap input, int size) { @@ -522,4 +529,13 @@ public class FileBackend { public boolean isFileAvailable(Message message) { return getFile(message).exists(); } + + public static void close(Closeable stream) { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + } + } + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 3677bf4f..9866af03 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -11,6 +11,7 @@ import android.util.Base64; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; @@ -172,6 +173,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { + FileBackend.close(fileInputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } } @@ -198,6 +200,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { + FileBackend.close(fileOutputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index c3419580..72015a05 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -11,6 +11,7 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.CryptoHelper; public class JingleSocks5Transport extends JingleTransport { @@ -126,25 +127,19 @@ public class JingleSocks5Transport extends JingleTransport { } catch (NoSuchAlgorithmException e) { callback.onFileTransferAborted(); } finally { - try { - if (fileInputStream != null) { - fileInputStream.close(); - } - } catch (IOException e) { - callback.onFileTransferAborted(); - } + FileBackend.close(fileInputStream); } } }).start(); } - public void receive(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback) { + public void receive(final DownloadableFile file, final OnFileTransmissionStatusChanged callback) { new Thread(new Runnable() { @Override public void run() { + OutputStream fileOutputStream = null; try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); @@ -152,7 +147,7 @@ public class JingleSocks5Transport extends JingleTransport { socket.setSoTimeout(30000); file.getParentFile().mkdirs(); file.createNewFile(); - OutputStream fileOutputStream = file.createOutputStream(); + fileOutputStream = file.createOutputStream(); if (fileOutputStream == null) { callback.onFileTransferAborted(); return; @@ -183,6 +178,8 @@ public class JingleSocks5Transport extends JingleTransport { callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { callback.onFileTransferAborted(); + } finally { + FileBackend.close(fileOutputStream); } } }).start(); -- cgit v1.2.3 From 82daf849aa9b68dbd61f61923d8d618630af50bf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 25 Apr 2015 14:42:32 +0200 Subject: fixed #1039 --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index eb7e2c3c..466bc409 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -91,6 +91,9 @@ public final class CryptoHelper { } public static String prettifyFingerprint(String fingerprint) { + if (fingerprint.length() < 40) { + return fingerprint; + } StringBuilder builder = new StringBuilder(fingerprint); builder.insert(8, " "); builder.insert(17, " "); -- cgit v1.2.3 From 5ea1c547d5d956473d3bce83d1f4354c0936ac6f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 25 Apr 2015 18:24:10 +0200 Subject: fixed service discovery by properly storing and checking identities --- .../conversations/ui/EditAccountActivity.java | 2 +- .../ui/PublishProfilePictureActivity.java | 3 +- .../siacs/conversations/xmpp/XmppConnection.java | 75 ++++++++++++++-------- 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index dbad9e00..7aa7b1c2 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -468,7 +468,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } else { this.mServerInfoSm.setText(R.string.server_info_unavailable); } - if (features.pubsub()) { + if (features.pep()) { this.mServerInfoPep.setText(R.string.server_info_available); } else { this.mServerInfoPep.setText(R.string.server_info_unavailable); diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 3f72b723..e8ab8dae 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -163,8 +163,7 @@ public class PublishProfilePictureActivity extends XmppActivity { if (jid != null) { this.account = xmppConnectionService.findAccountByJid(jid); if (this.account.getXmppConnection() != null) { - this.support = this.account.getXmppConnection() - .getFeatures().pubsub(); + this.support = this.account.getXmppConnection().getFeatures().pep(); } if (this.avatarUri == null) { if (this.account.getAvatar() != null diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 1351226b..cf580df1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -90,7 +90,7 @@ public class XmppConnection implements Runnable { private boolean shouldBind = true; private boolean shouldAuthenticate = true; private Element streamFeatures; - private final HashMap> disco = new HashMap<>(); + private final HashMap disco = new HashMap<>(); private String streamId = null; private int smVersion = 3; @@ -334,6 +334,7 @@ public class XmppConnection implements Runnable { } catch (final NumberFormatException ignored) { } sendServiceDiscoveryInfo(account.getServer()); + sendServiceDiscoveryInfo(account.getJid().toBareJid()); sendServiceDiscoveryItems(account.getServer()); sendInitialPing(); } else if (nextTag.isStart("r")) { @@ -734,6 +735,7 @@ public class XmppConnection implements Runnable { features.blockListRequested = false; disco.clear(); sendServiceDiscoveryInfo(account.getServer()); + sendServiceDiscoveryInfo(account.getJid().toBareJid()); sendServiceDiscoveryItems(account.getServer()); if (bindListener != null) { bindListener.onBind(account); @@ -741,34 +743,35 @@ public class XmppConnection implements Runnable { sendInitialPing(); } - private void sendServiceDiscoveryInfo(final Jid server) { - if (disco.containsKey(server.toDomainJid().toString())) { - if (account.getServer().equals(server.toDomainJid())) { + private void sendServiceDiscoveryInfo(final Jid jid) { + if (disco.containsKey(jid)) { + if (account.getServer().equals(jid)) { enableAdvancedStreamFeatures(); } } else { final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); - iq.setTo(server.toDomainJid()); + iq.setTo(jid); iq.query("http://jabber.org/protocol/disco#info"); this.sendIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { final List elements = packet.query().getChildren(); - final List features = new ArrayList<>(); + final Info info = new Info(); for (final Element element : elements) { if (element.getName().equals("identity")) { - if ("irc".equals(element.getAttribute("type"))) { - //add fake feature to not confuse irc and real muc - features.add("siacs:no:muc"); + String type = element.getAttribute("type"); + String category = element.getAttribute("category"); + if (type != null && category != null) { + info.identities.add(new Pair<>(category,type)); } } else if (element.getName().equals("feature")) { - features.add(element.getAttribute("var")); + info.features.add(element.getAttribute("var")); } } - disco.put(server.toDomainJid().toString(), features); + disco.put(jid, info); - if (account.getServer().equals(server.toDomainJid())) { + if (account.getServer().equals(jid)) { enableAdvancedStreamFeatures(); for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) { listener.onAdvancedStreamFeaturesAvailable(account); @@ -987,9 +990,9 @@ public class XmppConnection implements Runnable { public List findDiscoItemsByFeature(final String feature) { final List items = new ArrayList<>(); - for (final Entry> cursor : disco.entrySet()) { - if (cursor.getValue().contains(feature)) { - items.add(cursor.getKey()); + for (final Entry cursor : disco.entrySet()) { + if (cursor.getValue().features.contains(feature)) { + items.add(cursor.getKey().toString()); } } return items; @@ -1008,10 +1011,12 @@ public class XmppConnection implements Runnable { } public String getMucServer() { - for (final Entry> cursor : disco.entrySet()) { - final List value = cursor.getValue(); - if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) { - return cursor.getKey(); + for (final Entry cursor : disco.entrySet()) { + final Info value = cursor.getValue(); + if (value.features.contains("http://jabber.org/protocol/muc") + && !value.features.contains("jabber:iq:gateway") + && !value.identities.contains(new Pair<>("conference","irc"))) { + return cursor.getKey().toString(); } } return null; @@ -1066,6 +1071,11 @@ public class XmppConnection implements Runnable { this.lastConnect = 0; } + private class Info { + public final ArrayList features = new ArrayList<>(); + public final ArrayList> identities = new ArrayList<>(); + } + public class Features { XmppConnection connection; private boolean carbonsEnabled = false; @@ -1077,8 +1087,8 @@ public class XmppConnection implements Runnable { } private boolean hasDiscoFeature(final Jid server, final String feature) { - return connection.disco.containsKey(server.toDomainJid().toString()) && - connection.disco.get(server.toDomainJid().toString()).contains(feature); + return connection.disco.containsKey(server) && + connection.disco.get(server).features.contains(feature); } public boolean carbons() { @@ -1094,24 +1104,35 @@ public class XmppConnection implements Runnable { } public boolean sm() { - return streamId != null; + return streamId != null + || (connection.streamFeatures != null && connection.streamFeatures.hasChild("sm")); } public boolean csi() { return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0"); } - public boolean pubsub() { - return hasDiscoFeature(account.getServer(), - "http://jabber.org/protocol/pubsub#publish"); + public boolean pep() { + final Pair needle = new Pair<>("pubsub","pep"); + Info info = disco.get(account.getServer()); + if (info != null && info.identities.contains(needle)) { + return true; + } else { + info = disco.get(account.getJid().toBareJid()); + return info != null && info.identities.contains(needle); + } } public boolean mam() { - return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0"); + if (hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:mam:0")) { + return true; + } else { + return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0"); + } } public boolean advancedStreamFeaturesLoaded() { - return disco.containsKey(account.getServer().toString()); + return disco.containsKey(account.getServer()); } public boolean rosterVersioning() { -- cgit v1.2.3 From 7f2a83a684023aa7ac59c640be8e877434ebcbe7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 26 Apr 2015 10:48:36 +0200 Subject: pulled translations from transifex --- src/main/res/values-bg/strings.xml | 11 ++++ src/main/res/values-de/strings.xml | 2 +- src/main/res/values-es/strings.xml | 11 ++++ src/main/res/values-eu/strings.xml | 3 ++ src/main/res/values-it/strings.xml | 43 +++++++++++++++ src/main/res/values-pl/strings.xml | 10 +++- src/main/res/values-ru/strings.xml | 106 +++++++++++++++++++++++++++++++++++++ src/main/res/values-sk/strings.xml | 10 ++++ src/main/res/values-sr/strings.xml | 12 +++++ 9 files changed, 205 insertions(+), 3 deletions(-) diff --git a/src/main/res/values-bg/strings.xml b/src/main/res/values-bg/strings.xml index b4810f51..b27481dd 100644 --- a/src/main/res/values-bg/strings.xml +++ b/src/main/res/values-bg/strings.xml @@ -429,8 +429,19 @@ Получено местоположение Conversation се затвори Напуснахте беседата + Настройки на сертификата Да не се вярва на системните сертификати Всички сертификати трябва да бъдат одобрени на ръка + Премахване на сертификатите + Изтриване на сертификатите, одобрени на ръка + Няма сертификати, одобрени на ръка + Премахване на сертификатите + Изтриване на избраните + Отказ + + %d сертификат е изтрит + %d сертификата са изтрити + Изберете %d контакт Изберете %d контакта diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index d5f550a3..08b0d4a5 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -439,7 +439,7 @@ Auswahl löschen Abbrechen - %d Zertifikat gelöscht + %d Zertifikat gelöscht %d Zertifikate gelöscht diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index d7c6a885..16531073 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -429,8 +429,19 @@ Ubicación recibida Conversación cerrada Has salido de la conversación + Opciones de Certificados No confiar en los CAs del sistema Todos los certificados deben ser aprobados manualmente + Eliminar Certificados + Eliminar manualmente certificados aceptados + No aceptar certificados manualmente + Eliminar Certificados + Deshacer selección + Cancelar + + %d certificado eliminado + %d certificados eliminados + Seleccionado %d contacto Seleccionados %d contactos diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 3c9dee1b..42309661 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -359,6 +359,7 @@ Pasahitza ezin izan da aldatu Mezu bat bidali enkripatutako elkarrizketa hasteko Galdetu + Zu eta zure kontaktua beste inor ezagutzen ez duen elkarren arteko sekreturen bat baduzue (ohiko txantxa edo azkenengo aldian bazkaldu zenutena adibidez) bakoitzaren hatz-markak egiaztatzeko sekretu hori erabili dezakezue.\n\nIradokizun edo galdera bat eman behar duzu zure kontaktuak erantzun dezan, letra larri eta xeheak bereiziz. Zure kontaktuak zure hatz-marka egiaztatu nahi du partekatutako sekretu batekin erronka eginez. Zure kontaktuak hurrengo iradokizuna edo sekretu horren galdera eman du. Zure iradokizuna ez luke hutsik egon behar Zure partekatutako sekretua ezin da hutsik egon @@ -428,6 +429,8 @@ Kokapena jaso da Elkarrizketa itxi egin da Konferentzia utzi egin da + Sistemaren CAtaz ez fidatu + Ziurtagiri guztiak eskuz onartu behar dira Hautatu kontaktu %d Hautatu %d kontaktu diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 836dced8..8960f60b 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -304,6 +304,7 @@ Trasmissione dell’immagine fallita Scansiona codice QR Mostra codice QR + Mostra la black list Dettagli utente Verifica OTR Impronta remota @@ -328,6 +329,7 @@ Scegli file Ricezione di %1$s file (%2$d%% completato) Scarica %s + file Apri %s invio (%1$d%% completato) Preparazione alla trasmissione del file @@ -357,6 +359,7 @@ Impossibile cambiare la password Invia un messaggio per avviare una conversazione cifrata Fai una domanda + Se condividi con il tuo contatto un segreto in comune non conosciuto da altri (come uno scherzo privato o semplicemente quel che avete mangiato l\'ultima volta insieme) potete usarlo per verificare le vostre fingerprint.\n\nInvia un suggerimento o una domanda al tuo contatto il quale dovrà rispondere con una risposta controllando le maiuscole. Il tuo contatto vorrebbe verificare la tua identità. Dovrai rispondere correttamente alla sua domanda con una risposta che condividete. Il tuo contatto ti ha fornito il suggerimento o la domanda seguente. Il suggerimento non dovrebbe essere vuoto Il segreto condiviso non può essere vuoto @@ -399,6 +402,46 @@ Opzioni di ingresso Invio invia Il tasto invio spedisce il messaggio + Mostra il tasto invio + Cambia il tasto delle faccine nel tastodi invio + audio + video + immagine Documento PDF + Applicazione Android + Contatto Ricevuto %s + Tocca per avviare Conversations + Il tuo avatar è stato pubblicato! + Invio %s + Inviando %s + Nascondi i contatti offline + Disabilita l\'account + %s sta digitando... + %s ha smesso di digitare + Permetti al tuo contatto di vedere quando stai digitando + Invia la posizione + Mostra la posizione + Non è stata trovata alcuna applicazione per mostrare la posizione + Posizione + Posizione ricevuta + Conversazione interrotta + Conferenza terminata + Opzioni per i certificati + Non ti fidare delle CA di sistema + Tutti i certificati devono essere accettati manualmente + Elimina i certificati + Cancella manualmente i certificati già accettati + Non sono presenti certificati accettati manualmente + Elimina i certificati + Cancella la selezione + Annulla + + Cancellato il %d certificato + Cancellati %d certificati + + + Seleziona il %d contatto + Selezionati %d contatti + diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 3c58c485..e1849357 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -19,7 +19,7 @@ Ustawienia Szczegóły konferencji Szczegóły kontaktu - Udostępnij przez Conversation + Udostępnij w konwersacji Rozpocznij konwersację Wybierz kontakt Czarna lista @@ -183,6 +183,11 @@ Informacje o serwerze XEP-0313: MAM XEP-0280: Kopie wiadomości + XEP-0352: Client State Indication + XEP-0191: Blocking Command + XEP-0237: Roster Versioning + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) dostępny niedostępny Brak informacji o kluczu publicznym @@ -237,7 +242,7 @@ Połącz Konto już istnieje Dalej - Połączono + Połączono z serwerem Dodatkowe informacje Pomiń Wyłącz powiadomienia @@ -417,4 +422,5 @@ Opuszczono konferencję Nie ufaj certyfikatom systemowym Wymagaj ręcznego potwierdzania certyfikatów + Anuluj diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 0f3ec4c7..fb39e24a 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -283,4 +283,110 @@ Раскрасить кнопку отправить, указывая текущий статус собеседника Другие Название конференции + Использовать тему беседы заместо JID для отображения конференций + OTR-отпечаток скопирован в буфер обмена! + Вы заблокированы в этой конференции + Эта конференция требует членства + Вы были удалены из конференции + использовать учётную запись %s + Проверка изображения на узле HTTP + Файл изображения был удалён + Вы неподключены. Попробуйте позже + Проверить размер файла изображения + Опции сообщения + Копировать текст + Копировать адрес ссылки + Отправить ещё раз + Адрес изображения + Текст сообщения + Ссылка скопирована в буфер обмена + Сообщение скопировано в буфер обмена + Передача изображения не удалась + Поиск QR-кода + Показать QR-код + Показать чёрный список + Сведения об учётной записи + Подтвердить OTR + Удалённый отпечаток + поиск + (или сенсорные телефоны) + Socialist Millionaire Protocol + Подсказка или вопрос + Общий секретный ключ + Подтвердить + В ходе выполнения + Ответ + Не удалось + Ключи не совпадают + Попробуйте ещё раз + Завершить + Подтверждён! + Контакт запросил подтверждение SMP + Действительная OTR-сессия не найдена! + Диалоги + Оставить службу на переднем плане + Не позволяет операционной системе закрыть ваше соединение + Выберите файл + Получение %1$s (%2$d%% выполнено) + Загружено %s + файл + Открыть %s + отправка (%1$d%% выполнено) + Файл готовится для передачи + %s предлагается скачать + Отменить передачу + передача файла не удалась + Файл был удалён + Не найдено приложения для открытия файла + Не удалось подтвердить отпечаток + Ручная проверка + Вы точно хотите подтвердить OTR-отпечатки ваших контактов? + Показывать динамические тэги + Отображать теги только для чтения под контактами + Включить уведомления + Создать конференцию с... + Сервер конференции не был найден + Не удалось создать конференцию! + Конференция создана! + Секретный ключ принят! + Сброс + Изображение учётной записи + Скопировать OTR-отпечаток в буфер обмена + Получение истории с сервера + На сервере больше нет истории + Обновление... + Пароль изменён! + Не удалось изменить пароль + Отправить сообщение чтобы начать зашифрованный чат + Задать вопрос + Если у вас и вашего собеседника есть общая тайна, о которой никто кроме вас не знает (например, шутка, понятная только \"своим\" или что вы ели на обед при последней вашей встрече) вы можете использовать эту тайну, чтобы подтвердить отпечаток друг друга.\n\nВы даёте подсказку или задаёте вопрос вашему контакту, а она даст регистрозависимый ответ. + Ваш собеседник желает проверить ваш отпечаток с помощью общего секрета. Ваш собеседник дал следующую подсказку или вопрос в качестве этого секрета. + Ваша подсказка не может быть пустой + Ваш общий секрет не может быть пустым + Внимательно сверьте отпечаток, показанный ниже с отпечатком вашего собеседника.\nДля обмена ими вы можете использовать любое доверенное средство связи, например, зашифрованное электронное письмо или телефонный звонок. + Изменить пароль + Текущий пароль + Новый пароль + Пароль не может быть пустым + Включить все учётные записи + Отключить все учётные записи + Взаимодействовать с + Не является участником + Нет роли + Заблокированный пользователь + Участник + Расширенный режим + Предоставить участие + Отменить участие + Назначить административные права + Снять административные права + Исключить из конференции + Не удалось изменить принадлежность %s + Запретить доступ к конференции + Вы пытаетесь исключить %s из публичной конференции. Единственный способ — это навсегда запретить доступ пользователю. + Заблокировать + Не удалось сменить роль %s + Публичная конференция + Приватная конференция только для членов + Настройки конференции diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index e66bfd19..aa0fcff7 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -359,6 +359,7 @@ Nepodarilo sa zmeniť heslo Poslať správu pre spustenie šifrovaného chatu Položiť otázku + Ak máte vy a váš kontakt spoločné tajomstvo, ktoré nikto iný nepozná (napríklad nejaký spoločný vtip alebo len čo ste mali na obed, keď ste sa naposledy stretli), môžte použiť toto tajomstvo na overenie vzájomných identifikátorov. \n\nZadáte pomôcku alebo otázku pre váš kontakt, ktorý na ňu správne odpovie. Váš kontakt by chcel overiť váš identifikátor pomocou spoločného tajomstva. Váš kontakt zadal nasledujúcu pomôcku alebo otázku týkajúcu sa tajomstva. Vaša pomôcka by nemala byť prázdna Vaše spoločné tajomstvo nemôže byť prázdne @@ -426,4 +427,13 @@ Nenašla sa aplikácia na zobrazenie polohy Poloha Prijatá poloha + Konverzácia zatvorená + Opustil skupinovú konverzáciu + Nedôverovať systému CAs + Všetky certifikáty musia byť ručne schválené + + Vybrať %d kontaktu + Vybrať %d kontaktu + Vybrať %d kontaktov + diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 3b632cdb..bcf420ba 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -429,8 +429,20 @@ Примљена локација Преписка затворена Напусти конференцију + Опције сертификата Не веруј системским сертификационим телима Сви сертификати морају ручно да се одобре + Уклони сертификате + Обриши ручно одобрене сертификате + Нема ручно одобрених сертификата + Уклањање сертификата + Обриши изабрано + Одустани + + %d сертификат обрисан + %d сертификата обрисана + %d сертификата обрисано + Изабери %d контакт Изабери %d контакта -- cgit v1.2.3 From 031b752906a1f921e6c41bd22164d9bdfe3f82c0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 26 Apr 2015 10:49:25 +0200 Subject: version bump to 1.3.0-beta --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 1664fa57..37050656 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 57 - versionName "1.3.0-alpha" + versionCode 58 + versionName "1.3.0-beta" } compileOptions { -- cgit v1.2.3 From e50910590903b1db6c9ff3fa107935076d898c2e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 26 Apr 2015 12:40:03 +0200 Subject: added changelog. removed deprecated todo list --- CHANGELOG.md | 8 ++++++++ todo.md | 23 ----------------------- 2 files changed, 8 insertions(+), 23 deletions(-) delete mode 100644 todo.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 28bf2765..ae267086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ###Changelog +####Version 1.3.0 +* swipe conversations to end them +* quickly enable / disable account via slider +* share multiple images at once +* expert option to distrust system CAs +* mlink compatibility +* bug fixes + ####Version 1.2.0 * Send current location. (requires [plugin](https://play.google.com/store/apps/details?id=eu.siacs.conversations.sharelocation)) * Invite multiple contacts at once diff --git a/todo.md b/todo.md deleted file mode 100644 index bace5987..00000000 --- a/todo.md +++ /dev/null @@ -1,23 +0,0 @@ -##GSOC teaser tasks - -####update Contacts last seen for muc messages as well -The contact class (entities/Contact) has the ability to save the last time that Conversations - received a message from that contact. Currently this time only gets updated for one-on-one - messages. In non-anonymous mucs messages from a contact should also update the last seen - time. - -####Select multiple Contact in Choose Contact Activity -Currently the choose Contact activity allows only for one contact to be selected. A long -press on one contact should bring the activity in a mode where the user can select multiple -contacts. -The Activity should then return an array of contacts instead of just one - -####Request and respond to message receipts in MUC PNs -Private MUC messages either dont request message receipts or dont respond to them. The source -of error should be determined and eliminated. A rather small tasks that just teaches you a bit -about the stanza parser and generator in Conversations - -####Edit dynamic tags / groups -The context menu for the contact list (StartConversationActivity) should offer the ability to -edit groups. (Any UI decissions are left to you) Quick suggestion though: Dialog with -checkboxes for existing groups and some way to enter new tags. -- cgit v1.2.3 From c283fec0d1af6d4dc8c6b794a065fa1029b6d178 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 26 Apr 2015 20:26:59 +0200 Subject: hard code bitmap configs --- src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index cb79b0e9..ac169180 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -412,7 +412,7 @@ public class FileBackend { float top = (newHeight - scaledHeight) / 2; RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight); - Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig()); + Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(dest); canvas.drawBitmap(source, null, targetRect, null); return dest; @@ -437,7 +437,7 @@ public class FileBackend { float top = (size - outHeight) / 2; RectF target = new RectF(left, top, left + outWidth, top + outHeight); - Bitmap output = Bitmap.createBitmap(size, size, input.getConfig()); + Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); canvas.drawBitmap(input, null, target, null); return output; -- cgit v1.2.3 From e11d658f5e1cc89142df468eb12c2af388c97d7d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 26 Apr 2015 20:27:30 +0200 Subject: use xmppserviceconnection to send iq packets in jingle connection --- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 68eadbc6..e448f947 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -192,7 +192,7 @@ public class JingleConnection implements Downloadable { } else { response = packet.generateResponse(IqPacket.TYPE.ERROR); } - account.getXmppConnection().sendIqPacket(response, null); + mXmppConnectionService.sendIqPacket(account,response,null); } public void init(Message message) { @@ -459,11 +459,11 @@ public class JingleConnection implements Downloadable { } private void sendJinglePacket(JinglePacket packet) { - account.getXmppConnection().sendIqPacket(packet, responseListener); + mXmppConnectionService.sendIqPacket(account,packet,responseListener); } private void sendJinglePacket(JinglePacket packet, OnIqPacketReceived callback) { - account.getXmppConnection().sendIqPacket(packet,callback); + mXmppConnectionService.sendIqPacket(account,packet,callback); } private boolean receiveAccept(JinglePacket packet) { @@ -556,7 +556,7 @@ public class JingleConnection implements Downloadable { .setAttribute("sid", this.getSessionId()); activation.query().addChild("activate") .setContent(this.getCounterPart().toString()); - this.account.getXmppConnection().sendIqPacket(activation, + mXmppConnectionService.sendIqPacket(account,activation, new OnIqPacketReceived() { @Override -- cgit v1.2.3 From 4caa92e8ff374e28663fd1fe6c9494c767622004 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 27 Apr 2015 12:18:27 +0200 Subject: handle returning from camera without picture --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index e5389dd6..1f8fd0aa 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1034,6 +1034,9 @@ public class ConversationActivity extends XmppActivity this.mPendingGeoUri = null; } } + } else { + mPendingImageUris.clear(); + mPendingFileUris.clear(); } } -- cgit v1.2.3 From a4ff8e36337acab6fb3d945159f6d143e825f16b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 27 Apr 2015 12:19:05 +0200 Subject: increased padding around switches in manage accounts --- src/main/res/layout/account_row.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/res/layout/account_row.xml b/src/main/res/layout/account_row.xml index 94c59111..0e73dd64 100644 --- a/src/main/res/layout/account_row.xml +++ b/src/main/res/layout/account_row.xml @@ -3,7 +3,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/activatedBackgroundIndicator" - android:padding="8dp" > + android:paddingLeft="8dp" + android:paddingBottom="8dp" + android:paddingTop="8dp"> @@ -50,6 +51,7 @@ android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" + android:padding="8dp" android:focusable="false"/> \ No newline at end of file -- cgit v1.2.3 From f8e06d8e9a45d5e08c067fe9302ea96ddeebd175 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 09:25:58 +0200 Subject: revert undo timeout to a more reasonable value --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 1f8fd0aa..063b0259 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -246,7 +246,7 @@ public class ConversationActivity extends XmppActivity listView.enableSwipeToDismiss(); listView.setSwipingLayout(R.id.swipeable_item); listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP); - listView.setUndoHideDelay(8000); + listView.setUndoHideDelay(5000); listView.setRequireTouchBeforeDismiss(false); mContentView = findViewById(R.id.content_view_spl); -- cgit v1.2.3 From b10b8e2c50374c3f2f7d8f02b77f726c8921b721 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 09:32:58 +0200 Subject: escape nick in highlight regex pattern --- src/main/java/eu/siacs/conversations/services/NotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 7269a559..be01eebd 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -454,7 +454,7 @@ public class NotificationService { // nick (matched in case-insensitive manner), followed by optional // punctuation (for example "bob: i disagree" or "how are you alice?"), // followed by another word boundary. - return Pattern.compile("\\b" + nick + "\\p{Punct}?\\b", + return Pattern.compile("\\b" + Pattern.quote(nick) + "\\p{Punct}?\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } -- cgit v1.2.3 From b1843fb61a3f3c52ec99e3239a62d1976355f88c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 09:35:10 +0200 Subject: print stack trace on io error --- .../java/eu/siacs/conversations/persistance/FileBackend.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index ac169180..9ae56b04 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -155,9 +155,7 @@ public class FileBackend { OutputStream os = null; InputStream is = null; try { - if (!file.createNewFile()) { - throw new FileCopyException(R.string.error_io_exception); - } + file.createNewFile(); os = new FileOutputStream(file); is = mXmppConnectionService.getContentResolver().openInputStream(uri); byte[] buffer = new byte[1024]; @@ -166,7 +164,10 @@ public class FileBackend { os.write(buffer, 0, length); } os.flush(); + } catch(FileNotFoundException e) { + throw new FileCopyException(R.string.error_file_not_found); } catch (IOException e) { + e.printStackTrace(); throw new FileCopyException(R.string.error_io_exception); } finally { close(os); @@ -188,9 +189,7 @@ public class FileBackend { InputStream is = null; OutputStream os = null; try { - if (!file.createNewFile()) { - throw new FileCopyException(R.string.error_io_exception); - } + file.createNewFile(); is = mXmppConnectionService.getContentResolver().openInputStream(image); os = new FileOutputStream(file); @@ -223,6 +222,7 @@ public class FileBackend { } catch (FileNotFoundException e) { throw new FileCopyException(R.string.error_file_not_found); } catch (IOException e) { + e.printStackTrace(); throw new FileCopyException(R.string.error_io_exception); } catch (SecurityException e) { throw new FileCopyException(R.string.error_security_exception_during_image_copy); -- cgit v1.2.3 From 51bf8ec98ea6b628ed38d03969492ef0fddd6c77 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 13:31:33 +0200 Subject: fixed npe when rotating screen in contact details activity --- .../eu/siacs/conversations/ui/ContactDetailsActivity.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 40a4587c..f7156d7a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -256,16 +256,19 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd MenuItem unblock = menu.findItem(R.id.action_unblock); MenuItem edit = menu.findItem(R.id.action_edit_contact); MenuItem delete = menu.findItem(R.id.action_delete_contact); + if (contact == null) { + return true; + } final XmppConnection connection = contact.getAccount().getXmppConnection(); if (connection != null && connection.getFeatures().blocking()) { if (this.contact.isBlocked()) { - menu.findItem(R.id.action_block).setVisible(false); + block.setVisible(false); } else { - menu.findItem(R.id.action_unblock).setVisible(false); + unblock.setVisible(false); } } else { - menu.findItem(R.id.action_unblock).setVisible(false); - menu.findItem(R.id.action_block).setVisible(false); + unblock.setVisible(false); + block.setVisible(false); } if (!contact.showInRoster()) { edit.setVisible(false); @@ -275,6 +278,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } private void populateView() { + invalidateOptionsMenu(); setTitle(contact.getDisplayName()); if (contact.showInRoster()) { send.setVisibility(View.VISIBLE); -- cgit v1.2.3 From f3805b8bab6cc8aead9ea19e98161eb872d05996 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 13:56:08 +0200 Subject: stop conference details from crashing when rotating the screen --- src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index e4bfd6ff..8c4f6eaf 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -237,6 +237,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark); MenuItem menuItemAdvancedMode = menu.findItem(R.id.action_advanced_mode); menuItemAdvancedMode.setChecked(mAdvancedMode); + if (mConversation == null) { + return true; + } Account account = mConversation.getAccount(); if (account.hasBookmarkFor(mConversation.getJid().toBareJid())) { menuItemSaveBookmark.setVisible(false); -- cgit v1.2.3 From 93e942f96d856b4ea2ac2595dd8f76ffa0832db3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 14:28:51 +0200 Subject: made material icons smaller (24dp) --- .../services/NotificationService.java | 4 +-- .../conversations/ui/ConversationActivity.java | 2 +- src/main/res/drawable-hdpi/ic_add_white_24dp.png | Bin 0 -> 223 bytes src/main/res/drawable-hdpi/ic_add_white_48dp.png | Bin 222 -> 0 bytes .../drawable-hdpi/ic_attach_file_white_24dp.png | Bin 0 -> 452 bytes .../drawable-hdpi/ic_attach_file_white_48dp.png | Bin 870 -> 0 bytes src/main/res/drawable-hdpi/ic_chat_white_48dp.png | Bin 363 -> 0 bytes .../drawable-hdpi/ic_content_copy_grey600_24dp.png | Bin 0 -> 287 bytes .../drawable-hdpi/ic_content_copy_grey600_36dp.png | Bin 348 -> 0 bytes .../res/drawable-hdpi/ic_delete_grey600_24dp.png | Bin 0 -> 248 bytes .../res/drawable-hdpi/ic_delete_white_24dp.png | Bin 0 -> 246 bytes .../res/drawable-hdpi/ic_delete_white_48dp.png | Bin 338 -> 0 bytes .../res/drawable-hdpi/ic_edit_grey600_24dp.png | Bin 0 -> 341 bytes .../res/drawable-hdpi/ic_edit_grey600_36dp.png | Bin 419 -> 0 bytes src/main/res/drawable-hdpi/ic_edit_white_24dp.png | Bin 0 -> 339 bytes src/main/res/drawable-hdpi/ic_edit_white_48dp.png | Bin 490 -> 0 bytes .../res/drawable-hdpi/ic_group_add_white_24dp.png | Bin 0 -> 396 bytes .../res/drawable-hdpi/ic_group_add_white_48dp.png | Bin 722 -> 0 bytes src/main/res/drawable-hdpi/ic_group_white_24dp.png | Bin 0 -> 417 bytes src/main/res/drawable-hdpi/ic_group_white_48dp.png | Bin 599 -> 0 bytes .../drawable-hdpi/ic_import_export_white_24dp.png | Bin 0 -> 300 bytes .../drawable-hdpi/ic_import_export_white_48dp.png | Bin 414 -> 0 bytes .../res/drawable-hdpi/ic_lock_open_white_24dp.png | Bin 0 -> 400 bytes .../res/drawable-hdpi/ic_lock_open_white_48dp.png | Bin 739 -> 0 bytes .../drawable-hdpi/ic_lock_outline_white_48dp.png | Bin 743 -> 0 bytes src/main/res/drawable-hdpi/ic_lock_white_24dp.png | Bin 0 -> 399 bytes .../res/drawable-hdpi/ic_person_add_white_24dp.png | Bin 0 -> 383 bytes .../res/drawable-hdpi/ic_person_add_white_48dp.png | Bin 683 -> 0 bytes .../res/drawable-hdpi/ic_refresh_white_48dp.png | Bin 875 -> 0 bytes .../res/drawable-hdpi/ic_remove_grey600_36dp.png | Bin 217 -> 0 bytes .../res/drawable-hdpi/ic_search_white_24dp.png | Bin 0 -> 504 bytes .../res/drawable-hdpi/ic_search_white_48dp.png | Bin 871 -> 0 bytes .../res/drawable-hdpi/ic_settings_grey600_24dp.png | Bin 0 -> 572 bytes .../res/drawable-hdpi/ic_settings_grey600_36dp.png | Bin 780 -> 0 bytes .../res/drawable-hdpi/ic_warning_white_24dp.png | Bin 0 -> 421 bytes .../res/drawable-hdpi/ic_warning_white_36dp.png | Bin 540 -> 0 bytes src/main/res/drawable-mdpi/ic_add_white_24dp.png | Bin 0 -> 174 bytes src/main/res/drawable-mdpi/ic_add_white_48dp.png | Bin 198 -> 0 bytes .../drawable-mdpi/ic_attach_file_white_24dp.png | Bin 0 -> 332 bytes .../drawable-mdpi/ic_attach_file_white_48dp.png | Bin 576 -> 0 bytes src/main/res/drawable-mdpi/ic_chat_white_48dp.png | Bin 290 -> 0 bytes .../drawable-mdpi/ic_content_copy_grey600_24dp.png | Bin 0 -> 217 bytes .../drawable-mdpi/ic_content_copy_grey600_36dp.png | Bin 287 -> 0 bytes .../res/drawable-mdpi/ic_delete_grey600_24dp.png | Bin 0 -> 199 bytes .../res/drawable-mdpi/ic_delete_white_24dp.png | Bin 0 -> 197 bytes .../res/drawable-mdpi/ic_delete_white_48dp.png | Bin 270 -> 0 bytes .../res/drawable-mdpi/ic_edit_grey600_24dp.png | Bin 0 -> 276 bytes .../res/drawable-mdpi/ic_edit_grey600_36dp.png | Bin 341 -> 0 bytes src/main/res/drawable-mdpi/ic_edit_white_24dp.png | Bin 0 -> 272 bytes src/main/res/drawable-mdpi/ic_edit_white_48dp.png | Bin 378 -> 0 bytes .../res/drawable-mdpi/ic_group_add_white_24dp.png | Bin 0 -> 313 bytes .../res/drawable-mdpi/ic_group_add_white_48dp.png | Bin 484 -> 0 bytes src/main/res/drawable-mdpi/ic_group_white_24dp.png | Bin 0 -> 296 bytes src/main/res/drawable-mdpi/ic_group_white_48dp.png | Bin 464 -> 0 bytes .../drawable-mdpi/ic_import_export_white_24dp.png | Bin 0 -> 226 bytes .../drawable-mdpi/ic_import_export_white_48dp.png | Bin 330 -> 0 bytes .../res/drawable-mdpi/ic_lock_open_white_24dp.png | Bin 0 -> 290 bytes .../res/drawable-mdpi/ic_lock_open_white_48dp.png | Bin 513 -> 0 bytes .../drawable-mdpi/ic_lock_outline_white_48dp.png | Bin 449 -> 0 bytes src/main/res/drawable-mdpi/ic_lock_white_24dp.png | Bin 0 -> 296 bytes .../res/drawable-mdpi/ic_person_add_white_24dp.png | Bin 0 -> 289 bytes .../res/drawable-mdpi/ic_person_add_white_48dp.png | Bin 423 -> 0 bytes .../res/drawable-mdpi/ic_refresh_white_48dp.png | Bin 637 -> 0 bytes .../res/drawable-mdpi/ic_remove_grey600_36dp.png | Bin 197 -> 0 bytes .../res/drawable-mdpi/ic_search_white_24dp.png | Bin 0 -> 346 bytes .../res/drawable-mdpi/ic_search_white_48dp.png | Bin 591 -> 0 bytes .../res/drawable-mdpi/ic_settings_grey600_24dp.png | Bin 0 -> 423 bytes .../res/drawable-mdpi/ic_settings_grey600_36dp.png | Bin 572 -> 0 bytes .../res/drawable-mdpi/ic_warning_white_24dp.png | Bin 0 -> 328 bytes .../res/drawable-mdpi/ic_warning_white_36dp.png | Bin 421 -> 0 bytes src/main/res/drawable-xhdpi/ic_add_white_24dp.png | Bin 0 -> 198 bytes src/main/res/drawable-xhdpi/ic_add_white_48dp.png | Bin 269 -> 0 bytes .../drawable-xhdpi/ic_attach_file_white_24dp.png | Bin 0 -> 576 bytes .../drawable-xhdpi/ic_attach_file_white_48dp.png | Bin 1039 -> 0 bytes src/main/res/drawable-xhdpi/ic_chat_white_48dp.png | Bin 533 -> 0 bytes .../ic_content_copy_grey600_24dp.png | Bin 0 -> 320 bytes .../ic_content_copy_grey600_36dp.png | Bin 435 -> 0 bytes .../res/drawable-xhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 271 bytes .../res/drawable-xhdpi/ic_delete_white_24dp.png | Bin 0 -> 270 bytes .../res/drawable-xhdpi/ic_delete_white_48dp.png | Bin 397 -> 0 bytes .../res/drawable-xhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 379 bytes .../res/drawable-xhdpi/ic_edit_grey600_36dp.png | Bin 493 -> 0 bytes src/main/res/drawable-xhdpi/ic_edit_white_24dp.png | Bin 0 -> 378 bytes src/main/res/drawable-xhdpi/ic_edit_white_48dp.png | Bin 632 -> 0 bytes .../res/drawable-xhdpi/ic_group_add_white_24dp.png | Bin 0 -> 484 bytes .../res/drawable-xhdpi/ic_group_add_white_48dp.png | Bin 935 -> 0 bytes .../res/drawable-xhdpi/ic_group_white_24dp.png | Bin 0 -> 464 bytes .../res/drawable-xhdpi/ic_group_white_48dp.png | Bin 759 -> 0 bytes .../drawable-xhdpi/ic_import_export_white_24dp.png | Bin 0 -> 330 bytes .../drawable-xhdpi/ic_import_export_white_48dp.png | Bin 502 -> 0 bytes .../res/drawable-xhdpi/ic_lock_open_white_24dp.png | Bin 0 -> 513 bytes .../res/drawable-xhdpi/ic_lock_open_white_48dp.png | Bin 946 -> 0 bytes .../drawable-xhdpi/ic_lock_outline_white_48dp.png | Bin 948 -> 0 bytes src/main/res/drawable-xhdpi/ic_lock_white_24dp.png | Bin 0 -> 465 bytes .../drawable-xhdpi/ic_person_add_white_24dp.png | Bin 0 -> 423 bytes .../drawable-xhdpi/ic_person_add_white_48dp.png | Bin 909 -> 0 bytes .../res/drawable-xhdpi/ic_refresh_white_48dp.png | Bin 1148 -> 0 bytes .../res/drawable-xhdpi/ic_remove_grey600_36dp.png | Bin 212 -> 0 bytes .../res/drawable-xhdpi/ic_search_white_24dp.png | Bin 0 -> 591 bytes .../res/drawable-xhdpi/ic_search_white_48dp.png | Bin 1090 -> 0 bytes .../drawable-xhdpi/ic_settings_grey600_24dp.png | Bin 0 -> 704 bytes .../drawable-xhdpi/ic_settings_grey600_36dp.png | Bin 994 -> 0 bytes .../res/drawable-xhdpi/ic_warning_white_24dp.png | Bin 0 -> 460 bytes .../res/drawable-xhdpi/ic_warning_white_36dp.png | Bin 639 -> 0 bytes src/main/res/drawable-xxhdpi/ic_add_white_24dp.png | Bin 0 -> 222 bytes src/main/res/drawable-xxhdpi/ic_add_white_48dp.png | Bin 356 -> 0 bytes .../drawable-xxhdpi/ic_attach_file_white_24dp.png | Bin 0 -> 870 bytes .../drawable-xxhdpi/ic_attach_file_white_48dp.png | Bin 1642 -> 0 bytes .../res/drawable-xxhdpi/ic_chat_white_48dp.png | Bin 717 -> 0 bytes .../ic_content_copy_grey600_24dp.png | Bin 0 -> 435 bytes .../ic_content_copy_grey600_36dp.png | Bin 631 -> 0 bytes .../res/drawable-xxhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 341 bytes .../res/drawable-xxhdpi/ic_delete_white_24dp.png | Bin 0 -> 338 bytes .../res/drawable-xxhdpi/ic_delete_white_48dp.png | Bin 574 -> 0 bytes .../res/drawable-xxhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 493 bytes .../res/drawable-xxhdpi/ic_edit_grey600_36dp.png | Bin 656 -> 0 bytes .../res/drawable-xxhdpi/ic_edit_white_24dp.png | Bin 0 -> 490 bytes .../res/drawable-xxhdpi/ic_edit_white_48dp.png | Bin 843 -> 0 bytes .../drawable-xxhdpi/ic_group_add_white_24dp.png | Bin 0 -> 722 bytes .../drawable-xxhdpi/ic_group_add_white_48dp.png | Bin 1406 -> 0 bytes .../res/drawable-xxhdpi/ic_group_white_24dp.png | Bin 0 -> 599 bytes .../res/drawable-xxhdpi/ic_group_white_48dp.png | Bin 1273 -> 0 bytes .../ic_import_export_white_24dp.png | Bin 0 -> 414 bytes .../ic_import_export_white_48dp.png | Bin 768 -> 0 bytes .../drawable-xxhdpi/ic_lock_open_white_24dp.png | Bin 0 -> 739 bytes .../drawable-xxhdpi/ic_lock_open_white_48dp.png | Bin 1438 -> 0 bytes .../drawable-xxhdpi/ic_lock_outline_white_48dp.png | Bin 1437 -> 0 bytes .../res/drawable-xxhdpi/ic_lock_white_24dp.png | Bin 0 -> 760 bytes .../drawable-xxhdpi/ic_person_add_white_24dp.png | Bin 0 -> 683 bytes .../drawable-xxhdpi/ic_person_add_white_48dp.png | Bin 1346 -> 0 bytes .../res/drawable-xxhdpi/ic_refresh_white_48dp.png | Bin 1704 -> 0 bytes .../res/drawable-xxhdpi/ic_remove_grey600_36dp.png | Bin 278 -> 0 bytes .../res/drawable-xxhdpi/ic_search_white_24dp.png | Bin 0 -> 871 bytes .../res/drawable-xxhdpi/ic_search_white_48dp.png | Bin 1671 -> 0 bytes .../drawable-xxhdpi/ic_settings_grey600_24dp.png | Bin 0 -> 994 bytes .../drawable-xxhdpi/ic_settings_grey600_36dp.png | Bin 1486 -> 0 bytes .../res/drawable-xxhdpi/ic_warning_white_24dp.png | Bin 0 -> 639 bytes .../res/drawable-xxhdpi/ic_warning_white_36dp.png | Bin 1050 -> 0 bytes .../res/drawable-xxxhdpi/ic_add_white_24dp.png | Bin 0 -> 269 bytes .../res/drawable-xxxhdpi/ic_add_white_48dp.png | Bin 470 -> 0 bytes .../drawable-xxxhdpi/ic_attach_file_white_24dp.png | Bin 0 -> 1039 bytes .../drawable-xxxhdpi/ic_attach_file_white_48dp.png | Bin 2215 -> 0 bytes .../res/drawable-xxxhdpi/ic_chat_white_48dp.png | Bin 929 -> 0 bytes .../ic_content_copy_grey600_24dp.png | Bin 0 -> 521 bytes .../ic_content_copy_grey600_36dp.png | Bin 760 -> 0 bytes .../drawable-xxxhdpi/ic_delete_grey600_24dp.png | Bin 0 -> 402 bytes .../res/drawable-xxxhdpi/ic_delete_white_24dp.png | Bin 0 -> 397 bytes .../res/drawable-xxxhdpi/ic_delete_white_48dp.png | Bin 719 -> 0 bytes .../res/drawable-xxxhdpi/ic_edit_grey600_24dp.png | Bin 0 -> 639 bytes .../res/drawable-xxxhdpi/ic_edit_grey600_36dp.png | Bin 846 -> 0 bytes .../res/drawable-xxxhdpi/ic_edit_white_24dp.png | Bin 0 -> 632 bytes .../res/drawable-xxxhdpi/ic_edit_white_48dp.png | Bin 1098 -> 0 bytes .../drawable-xxxhdpi/ic_group_add_white_24dp.png | Bin 0 -> 935 bytes .../drawable-xxxhdpi/ic_group_add_white_48dp.png | Bin 1935 -> 0 bytes .../res/drawable-xxxhdpi/ic_group_white_24dp.png | Bin 0 -> 759 bytes .../res/drawable-xxxhdpi/ic_group_white_48dp.png | Bin 1719 -> 0 bytes .../ic_import_export_white_24dp.png | Bin 0 -> 502 bytes .../ic_import_export_white_48dp.png | Bin 1025 -> 0 bytes .../drawable-xxxhdpi/ic_lock_open_white_24dp.png | Bin 0 -> 946 bytes .../drawable-xxxhdpi/ic_lock_open_white_48dp.png | Bin 1872 -> 0 bytes .../ic_lock_outline_white_48dp.png | Bin 1874 -> 0 bytes .../res/drawable-xxxhdpi/ic_lock_white_24dp.png | Bin 0 -> 971 bytes .../drawable-xxxhdpi/ic_person_add_white_24dp.png | Bin 0 -> 909 bytes .../drawable-xxxhdpi/ic_person_add_white_48dp.png | Bin 1729 -> 0 bytes .../res/drawable-xxxhdpi/ic_refresh_white_48dp.png | Bin 2312 -> 0 bytes .../drawable-xxxhdpi/ic_remove_grey600_36dp.png | Bin 341 -> 0 bytes .../res/drawable-xxxhdpi/ic_search_white_24dp.png | Bin 0 -> 1090 bytes .../res/drawable-xxxhdpi/ic_search_white_48dp.png | Bin 2279 -> 0 bytes .../drawable-xxxhdpi/ic_settings_grey600_24dp.png | Bin 0 -> 1299 bytes .../drawable-xxxhdpi/ic_settings_grey600_36dp.png | Bin 1978 -> 0 bytes .../res/drawable-xxxhdpi/ic_warning_white_24dp.png | Bin 0 -> 887 bytes .../res/drawable-xxxhdpi/ic_warning_white_36dp.png | Bin 1324 -> 0 bytes src/main/res/values-v21/themes.xml | 32 ++++++++++----------- 173 files changed, 18 insertions(+), 20 deletions(-) create mode 100644 src/main/res/drawable-hdpi/ic_add_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_add_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_attach_file_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_attach_file_white_48dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_chat_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_content_copy_grey600_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_content_copy_grey600_36dp.png create mode 100644 src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png create mode 100644 src/main/res/drawable-hdpi/ic_delete_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_delete_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_edit_grey600_36dp.png create mode 100644 src/main/res/drawable-hdpi/ic_edit_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_edit_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_group_add_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_group_add_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_group_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_group_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_import_export_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_import_export_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_lock_open_white_48dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_lock_outline_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_lock_white_24dp.png create mode 100644 src/main/res/drawable-hdpi/ic_person_add_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_person_add_white_48dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_refresh_white_48dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_remove_grey600_36dp.png create mode 100644 src/main/res/drawable-hdpi/ic_search_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_search_white_48dp.png create mode 100644 src/main/res/drawable-hdpi/ic_settings_grey600_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_settings_grey600_36dp.png create mode 100644 src/main/res/drawable-hdpi/ic_warning_white_24dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_warning_white_36dp.png create mode 100644 src/main/res/drawable-mdpi/ic_add_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_add_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_attach_file_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_attach_file_white_48dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_chat_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_content_copy_grey600_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_content_copy_grey600_36dp.png create mode 100644 src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png create mode 100644 src/main/res/drawable-mdpi/ic_delete_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_delete_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_edit_grey600_36dp.png create mode 100644 src/main/res/drawable-mdpi/ic_edit_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_edit_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_group_add_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_group_add_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_group_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_group_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_import_export_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_import_export_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_lock_open_white_48dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_lock_outline_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_lock_white_24dp.png create mode 100644 src/main/res/drawable-mdpi/ic_person_add_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_person_add_white_48dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_refresh_white_48dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_remove_grey600_36dp.png create mode 100644 src/main/res/drawable-mdpi/ic_search_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_search_white_48dp.png create mode 100644 src/main/res/drawable-mdpi/ic_settings_grey600_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_settings_grey600_36dp.png create mode 100644 src/main/res/drawable-mdpi/ic_warning_white_24dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_warning_white_36dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_add_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_add_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_attach_file_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_attach_file_white_48dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_chat_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_content_copy_grey600_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_content_copy_grey600_36dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_delete_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_delete_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_edit_grey600_36dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_edit_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_edit_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_group_add_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_group_add_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_group_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_group_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_import_export_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_import_export_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_lock_open_white_48dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_lock_outline_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_lock_white_24dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_person_add_white_48dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_refresh_white_48dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_remove_grey600_36dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_search_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_search_white_48dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_settings_grey600_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_settings_grey600_36dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_warning_white_24dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_warning_white_36dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_add_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_attach_file_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_attach_file_white_48dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_chat_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_content_copy_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_content_copy_grey600_36dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_delete_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_edit_grey600_36dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_edit_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_group_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_group_add_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_group_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_group_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_import_export_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_import_export_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_lock_open_white_48dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_lock_outline_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_person_add_white_48dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_refresh_white_48dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_remove_grey600_36dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_search_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_search_white_48dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_settings_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_settings_grey600_36dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_warning_white_24dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_warning_white_36dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_add_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_attach_file_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_attach_file_white_48dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_chat_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_36dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_delete_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_edit_grey600_36dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_edit_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_group_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_group_add_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_group_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_group_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_import_export_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_import_export_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_lock_open_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_lock_open_white_48dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_lock_outline_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_person_add_white_48dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_refresh_white_48dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_remove_grey600_36dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_search_white_48dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_settings_grey600_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_settings_grey600_36dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_warning_white_24dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_warning_white_36dp.png diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index be01eebd..fc40ce75 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -493,7 +493,7 @@ public class NotificationService { final int cancelIcon; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mBuilder.setCategory(Notification.CATEGORY_SERVICE); - mBuilder.setSmallIcon(R.drawable.ic_import_export_white_48dp); + mBuilder.setSmallIcon(R.drawable.ic_import_export_white_24dp); cancelIcon = R.drawable.ic_cancel_white_24dp; } else { mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); @@ -540,7 +540,7 @@ public class NotificationService { mBuilder.setOngoing(true); //mBuilder.setLights(0xffffffff, 2000, 4000); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setSmallIcon(R.drawable.ic_warning_white_36dp); + mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); } else { mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 063b0259..aec755fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -375,7 +375,7 @@ public class ConversationActivity extends XmppActivity if (this.getSelectedConversation().getLatestMessage() .getEncryption() != Message.ENCRYPTION_NONE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - menuSecure.setIcon(R.drawable.ic_lock_outline_white_48dp); + menuSecure.setIcon(R.drawable.ic_lock_white_24dp); } else { menuSecure.setIcon(R.drawable.ic_action_secure); } diff --git a/src/main/res/drawable-hdpi/ic_add_white_24dp.png b/src/main/res/drawable-hdpi/ic_add_white_24dp.png new file mode 100644 index 00000000..481643ec Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_add_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_add_white_48dp.png b/src/main/res/drawable-hdpi/ic_add_white_48dp.png deleted file mode 100644 index 72cedcad..00000000 Binary files a/src/main/res/drawable-hdpi/ic_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_attach_file_white_24dp.png b/src/main/res/drawable-hdpi/ic_attach_file_white_24dp.png new file mode 100644 index 00000000..66299b88 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_attach_file_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_attach_file_white_48dp.png b/src/main/res/drawable-hdpi/ic_attach_file_white_48dp.png deleted file mode 100644 index 7256ca3d..00000000 Binary files a/src/main/res/drawable-hdpi/ic_attach_file_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_chat_white_48dp.png b/src/main/res/drawable-hdpi/ic_chat_white_48dp.png deleted file mode 100644 index 71cac75a..00000000 Binary files a/src/main/res/drawable-hdpi/ic_chat_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_content_copy_grey600_24dp.png b/src/main/res/drawable-hdpi/ic_content_copy_grey600_24dp.png new file mode 100644 index 00000000..5592d5c8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_content_copy_grey600_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_content_copy_grey600_36dp.png b/src/main/res/drawable-hdpi/ic_content_copy_grey600_36dp.png deleted file mode 100644 index bd2c60b8..00000000 Binary files a/src/main/res/drawable-hdpi/ic_content_copy_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png b/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png new file mode 100644 index 00000000..b72a9f3c Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_delete_grey600_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_delete_white_24dp.png b/src/main/res/drawable-hdpi/ic_delete_white_24dp.png new file mode 100644 index 00000000..a9eac0ca Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_delete_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_delete_white_48dp.png b/src/main/res/drawable-hdpi/ic_delete_white_48dp.png deleted file mode 100644 index 0e95e9b1..00000000 Binary files a/src/main/res/drawable-hdpi/ic_delete_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png b/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png new file mode 100644 index 00000000..b5f88c80 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_edit_grey600_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_edit_grey600_36dp.png b/src/main/res/drawable-hdpi/ic_edit_grey600_36dp.png deleted file mode 100644 index f8970cb2..00000000 Binary files a/src/main/res/drawable-hdpi/ic_edit_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_edit_white_24dp.png b/src/main/res/drawable-hdpi/ic_edit_white_24dp.png new file mode 100644 index 00000000..730416c9 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_edit_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_edit_white_48dp.png b/src/main/res/drawable-hdpi/ic_edit_white_48dp.png deleted file mode 100644 index 34ec7092..00000000 Binary files a/src/main/res/drawable-hdpi/ic_edit_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_group_add_white_24dp.png b/src/main/res/drawable-hdpi/ic_group_add_white_24dp.png new file mode 100644 index 00000000..d96c584c Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_group_add_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_group_add_white_48dp.png b/src/main/res/drawable-hdpi/ic_group_add_white_48dp.png deleted file mode 100644 index a5ad0a29..00000000 Binary files a/src/main/res/drawable-hdpi/ic_group_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_group_white_24dp.png b/src/main/res/drawable-hdpi/ic_group_white_24dp.png new file mode 100644 index 00000000..dada448f Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_group_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_group_white_48dp.png b/src/main/res/drawable-hdpi/ic_group_white_48dp.png deleted file mode 100644 index a6ed594f..00000000 Binary files a/src/main/res/drawable-hdpi/ic_group_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_import_export_white_24dp.png b/src/main/res/drawable-hdpi/ic_import_export_white_24dp.png new file mode 100644 index 00000000..705a4cc7 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_import_export_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_import_export_white_48dp.png b/src/main/res/drawable-hdpi/ic_import_export_white_48dp.png deleted file mode 100644 index c3497037..00000000 Binary files a/src/main/res/drawable-hdpi/ic_import_export_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png b/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png new file mode 100644 index 00000000..1f582254 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_lock_open_white_48dp.png b/src/main/res/drawable-hdpi/ic_lock_open_white_48dp.png deleted file mode 100644 index b90a5980..00000000 Binary files a/src/main/res/drawable-hdpi/ic_lock_open_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_lock_outline_white_48dp.png b/src/main/res/drawable-hdpi/ic_lock_outline_white_48dp.png deleted file mode 100644 index d0c25290..00000000 Binary files a/src/main/res/drawable-hdpi/ic_lock_outline_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_lock_white_24dp.png b/src/main/res/drawable-hdpi/ic_lock_white_24dp.png new file mode 100644 index 00000000..b94735ec Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_lock_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_person_add_white_24dp.png b/src/main/res/drawable-hdpi/ic_person_add_white_24dp.png new file mode 100644 index 00000000..53341908 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_person_add_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_person_add_white_48dp.png b/src/main/res/drawable-hdpi/ic_person_add_white_48dp.png deleted file mode 100644 index 074db2d3..00000000 Binary files a/src/main/res/drawable-hdpi/ic_person_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_refresh_white_48dp.png b/src/main/res/drawable-hdpi/ic_refresh_white_48dp.png deleted file mode 100644 index 72128fe6..00000000 Binary files a/src/main/res/drawable-hdpi/ic_refresh_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_remove_grey600_36dp.png b/src/main/res/drawable-hdpi/ic_remove_grey600_36dp.png deleted file mode 100644 index aeb1cea9..00000000 Binary files a/src/main/res/drawable-hdpi/ic_remove_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/src/main/res/drawable-hdpi/ic_search_white_24dp.png new file mode 100644 index 00000000..a2fc5b2e Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_search_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_search_white_48dp.png b/src/main/res/drawable-hdpi/ic_search_white_48dp.png deleted file mode 100644 index 0bbeab15..00000000 Binary files a/src/main/res/drawable-hdpi/ic_search_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_settings_grey600_24dp.png b/src/main/res/drawable-hdpi/ic_settings_grey600_24dp.png new file mode 100644 index 00000000..20d2b66e Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_settings_grey600_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_settings_grey600_36dp.png b/src/main/res/drawable-hdpi/ic_settings_grey600_36dp.png deleted file mode 100644 index cff84744..00000000 Binary files a/src/main/res/drawable-hdpi/ic_settings_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_warning_white_24dp.png b/src/main/res/drawable-hdpi/ic_warning_white_24dp.png new file mode 100644 index 00000000..30eee6c4 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_warning_white_24dp.png differ diff --git a/src/main/res/drawable-hdpi/ic_warning_white_36dp.png b/src/main/res/drawable-hdpi/ic_warning_white_36dp.png deleted file mode 100644 index c8b7140a..00000000 Binary files a/src/main/res/drawable-hdpi/ic_warning_white_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_add_white_24dp.png b/src/main/res/drawable-mdpi/ic_add_white_24dp.png new file mode 100644 index 00000000..977dd342 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_add_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_add_white_48dp.png b/src/main/res/drawable-mdpi/ic_add_white_48dp.png deleted file mode 100644 index 67042105..00000000 Binary files a/src/main/res/drawable-mdpi/ic_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_attach_file_white_24dp.png b/src/main/res/drawable-mdpi/ic_attach_file_white_24dp.png new file mode 100644 index 00000000..fc62a5bf Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_attach_file_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_attach_file_white_48dp.png b/src/main/res/drawable-mdpi/ic_attach_file_white_48dp.png deleted file mode 100644 index db23fd65..00000000 Binary files a/src/main/res/drawable-mdpi/ic_attach_file_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_chat_white_48dp.png b/src/main/res/drawable-mdpi/ic_chat_white_48dp.png deleted file mode 100644 index 526ebec6..00000000 Binary files a/src/main/res/drawable-mdpi/ic_chat_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_content_copy_grey600_24dp.png b/src/main/res/drawable-mdpi/ic_content_copy_grey600_24dp.png new file mode 100644 index 00000000..bab9b4d6 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_content_copy_grey600_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_content_copy_grey600_36dp.png b/src/main/res/drawable-mdpi/ic_content_copy_grey600_36dp.png deleted file mode 100644 index 5592d5c8..00000000 Binary files a/src/main/res/drawable-mdpi/ic_content_copy_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png b/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png new file mode 100644 index 00000000..e757fdb0 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_delete_grey600_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_delete_white_24dp.png b/src/main/res/drawable-mdpi/ic_delete_white_24dp.png new file mode 100644 index 00000000..e4ea52ef Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_delete_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_delete_white_48dp.png b/src/main/res/drawable-mdpi/ic_delete_white_48dp.png deleted file mode 100644 index cdb230c2..00000000 Binary files a/src/main/res/drawable-mdpi/ic_delete_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png b/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png new file mode 100644 index 00000000..bae3480c Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_edit_grey600_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_edit_grey600_36dp.png b/src/main/res/drawable-mdpi/ic_edit_grey600_36dp.png deleted file mode 100644 index b5f88c80..00000000 Binary files a/src/main/res/drawable-mdpi/ic_edit_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_edit_white_24dp.png b/src/main/res/drawable-mdpi/ic_edit_white_24dp.png new file mode 100644 index 00000000..85cff0b9 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_edit_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_edit_white_48dp.png b/src/main/res/drawable-mdpi/ic_edit_white_48dp.png deleted file mode 100644 index 7f0ea51b..00000000 Binary files a/src/main/res/drawable-mdpi/ic_edit_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_group_add_white_24dp.png b/src/main/res/drawable-mdpi/ic_group_add_white_24dp.png new file mode 100644 index 00000000..d0ef7ee8 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_group_add_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_group_add_white_48dp.png b/src/main/res/drawable-mdpi/ic_group_add_white_48dp.png deleted file mode 100644 index 6055325e..00000000 Binary files a/src/main/res/drawable-mdpi/ic_group_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_group_white_24dp.png b/src/main/res/drawable-mdpi/ic_group_white_24dp.png new file mode 100644 index 00000000..ff2a916b Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_group_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_group_white_48dp.png b/src/main/res/drawable-mdpi/ic_group_white_48dp.png deleted file mode 100644 index 0c5fd333..00000000 Binary files a/src/main/res/drawable-mdpi/ic_group_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_import_export_white_24dp.png b/src/main/res/drawable-mdpi/ic_import_export_white_24dp.png new file mode 100644 index 00000000..5f6e11bc Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_import_export_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_import_export_white_48dp.png b/src/main/res/drawable-mdpi/ic_import_export_white_48dp.png deleted file mode 100644 index fb82f420..00000000 Binary files a/src/main/res/drawable-mdpi/ic_import_export_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png b/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png new file mode 100644 index 00000000..ab9efde0 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_lock_open_white_48dp.png b/src/main/res/drawable-mdpi/ic_lock_open_white_48dp.png deleted file mode 100644 index 6e1321e4..00000000 Binary files a/src/main/res/drawable-mdpi/ic_lock_open_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_lock_outline_white_48dp.png b/src/main/res/drawable-mdpi/ic_lock_outline_white_48dp.png deleted file mode 100644 index 2d2c9417..00000000 Binary files a/src/main/res/drawable-mdpi/ic_lock_outline_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_lock_white_24dp.png b/src/main/res/drawable-mdpi/ic_lock_white_24dp.png new file mode 100644 index 00000000..381b6a11 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_lock_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_person_add_white_24dp.png b/src/main/res/drawable-mdpi/ic_person_add_white_24dp.png new file mode 100644 index 00000000..d0857a49 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_person_add_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_person_add_white_48dp.png b/src/main/res/drawable-mdpi/ic_person_add_white_48dp.png deleted file mode 100644 index c402e8f0..00000000 Binary files a/src/main/res/drawable-mdpi/ic_person_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_refresh_white_48dp.png b/src/main/res/drawable-mdpi/ic_refresh_white_48dp.png deleted file mode 100644 index 5f89fc25..00000000 Binary files a/src/main/res/drawable-mdpi/ic_refresh_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_remove_grey600_36dp.png b/src/main/res/drawable-mdpi/ic_remove_grey600_36dp.png deleted file mode 100644 index efc9560e..00000000 Binary files a/src/main/res/drawable-mdpi/ic_remove_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/src/main/res/drawable-mdpi/ic_search_white_24dp.png new file mode 100644 index 00000000..dff1e3a8 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_search_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_search_white_48dp.png b/src/main/res/drawable-mdpi/ic_search_white_48dp.png deleted file mode 100644 index 043759ac..00000000 Binary files a/src/main/res/drawable-mdpi/ic_search_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_settings_grey600_24dp.png b/src/main/res/drawable-mdpi/ic_settings_grey600_24dp.png new file mode 100644 index 00000000..5a1b41f0 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_settings_grey600_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_settings_grey600_36dp.png b/src/main/res/drawable-mdpi/ic_settings_grey600_36dp.png deleted file mode 100644 index 20d2b66e..00000000 Binary files a/src/main/res/drawable-mdpi/ic_settings_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_warning_white_24dp.png b/src/main/res/drawable-mdpi/ic_warning_white_24dp.png new file mode 100644 index 00000000..385c0f68 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_warning_white_24dp.png differ diff --git a/src/main/res/drawable-mdpi/ic_warning_white_36dp.png b/src/main/res/drawable-mdpi/ic_warning_white_36dp.png deleted file mode 100644 index 30eee6c4..00000000 Binary files a/src/main/res/drawable-mdpi/ic_warning_white_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_add_white_24dp.png b/src/main/res/drawable-xhdpi/ic_add_white_24dp.png new file mode 100644 index 00000000..67042105 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_add_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_add_white_48dp.png b/src/main/res/drawable-xhdpi/ic_add_white_48dp.png deleted file mode 100644 index 2bef0595..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_attach_file_white_24dp.png b/src/main/res/drawable-xhdpi/ic_attach_file_white_24dp.png new file mode 100644 index 00000000..db23fd65 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_attach_file_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_attach_file_white_48dp.png b/src/main/res/drawable-xhdpi/ic_attach_file_white_48dp.png deleted file mode 100644 index caaee37a..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_attach_file_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_chat_white_48dp.png b/src/main/res/drawable-xhdpi/ic_chat_white_48dp.png deleted file mode 100644 index 1230ab39..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_chat_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_content_copy_grey600_24dp.png b/src/main/res/drawable-xhdpi/ic_content_copy_grey600_24dp.png new file mode 100644 index 00000000..68ccece6 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_content_copy_grey600_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_content_copy_grey600_36dp.png b/src/main/res/drawable-xhdpi/ic_content_copy_grey600_36dp.png deleted file mode 100644 index 2fdbbea1..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_content_copy_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png b/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png new file mode 100644 index 00000000..c6bb43e8 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_delete_grey600_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png b/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png new file mode 100644 index 00000000..cdb230c2 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_delete_white_48dp.png b/src/main/res/drawable-xhdpi/ic_delete_white_48dp.png deleted file mode 100644 index ccf8c716..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_delete_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png b/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png new file mode 100644 index 00000000..4c95bd57 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_edit_grey600_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_edit_grey600_36dp.png b/src/main/res/drawable-xhdpi/ic_edit_grey600_36dp.png deleted file mode 100644 index 6ed4351c..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_edit_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png b/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png new file mode 100644 index 00000000..7f0ea51b Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_edit_white_48dp.png b/src/main/res/drawable-xhdpi/ic_edit_white_48dp.png deleted file mode 100644 index 9380370f..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_edit_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_group_add_white_24dp.png b/src/main/res/drawable-xhdpi/ic_group_add_white_24dp.png new file mode 100644 index 00000000..6055325e Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_group_add_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_group_add_white_48dp.png b/src/main/res/drawable-xhdpi/ic_group_add_white_48dp.png deleted file mode 100644 index 0ac3d4a8..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_group_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_group_white_24dp.png b/src/main/res/drawable-xhdpi/ic_group_white_24dp.png new file mode 100644 index 00000000..0c5fd333 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_group_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_group_white_48dp.png b/src/main/res/drawable-xhdpi/ic_group_white_48dp.png deleted file mode 100644 index a62b5677..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_group_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_import_export_white_24dp.png b/src/main/res/drawable-xhdpi/ic_import_export_white_24dp.png new file mode 100644 index 00000000..fb82f420 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_import_export_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_import_export_white_48dp.png b/src/main/res/drawable-xhdpi/ic_import_export_white_48dp.png deleted file mode 100644 index 06b27ea1..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_import_export_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png b/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png new file mode 100644 index 00000000..6e1321e4 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_lock_open_white_48dp.png b/src/main/res/drawable-xhdpi/ic_lock_open_white_48dp.png deleted file mode 100644 index 8f35034c..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_lock_open_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_lock_outline_white_48dp.png b/src/main/res/drawable-xhdpi/ic_lock_outline_white_48dp.png deleted file mode 100644 index 3de35f9b..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_lock_outline_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png b/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png new file mode 100644 index 00000000..c5e9d0b4 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png b/src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png new file mode 100644 index 00000000..c402e8f0 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_person_add_white_48dp.png b/src/main/res/drawable-xhdpi/ic_person_add_white_48dp.png deleted file mode 100644 index 4e2121e5..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_person_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_refresh_white_48dp.png b/src/main/res/drawable-xhdpi/ic_refresh_white_48dp.png deleted file mode 100644 index d271d8e0..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_refresh_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_remove_grey600_36dp.png b/src/main/res/drawable-xhdpi/ic_remove_grey600_36dp.png deleted file mode 100644 index 3d5136fe..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_remove_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/src/main/res/drawable-xhdpi/ic_search_white_24dp.png new file mode 100644 index 00000000..043759ac Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_search_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_search_white_48dp.png b/src/main/res/drawable-xhdpi/ic_search_white_48dp.png deleted file mode 100644 index 70c21baf..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_search_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_settings_grey600_24dp.png b/src/main/res/drawable-xhdpi/ic_settings_grey600_24dp.png new file mode 100644 index 00000000..2251d2bb Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_settings_grey600_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_settings_grey600_36dp.png b/src/main/res/drawable-xhdpi/ic_settings_grey600_36dp.png deleted file mode 100644 index 6a70402b..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_settings_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_warning_white_24dp.png b/src/main/res/drawable-xhdpi/ic_warning_white_24dp.png new file mode 100644 index 00000000..6eb7943c Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_warning_white_24dp.png differ diff --git a/src/main/res/drawable-xhdpi/ic_warning_white_36dp.png b/src/main/res/drawable-xhdpi/ic_warning_white_36dp.png deleted file mode 100644 index 3f401317..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_warning_white_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png new file mode 100644 index 00000000..72cedcad Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_add_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_add_white_48dp.png deleted file mode 100644 index b12e040e..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_attach_file_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_attach_file_white_24dp.png new file mode 100644 index 00000000..7256ca3d Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_attach_file_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_attach_file_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_attach_file_white_48dp.png deleted file mode 100644 index b50e5161..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_attach_file_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_chat_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_chat_white_48dp.png deleted file mode 100644 index bb39d157..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_chat_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_24dp.png b/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_24dp.png new file mode 100644 index 00000000..2fdbbea1 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_36dp.png b/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_36dp.png deleted file mode 100644 index 72b3474b..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_content_copy_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png b/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png new file mode 100644 index 00000000..4886ab1e Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_delete_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png new file mode 100644 index 00000000..0e95e9b1 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_delete_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_delete_white_48dp.png deleted file mode 100644 index a8d8ca84..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_delete_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png b/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png new file mode 100644 index 00000000..6ed4351c Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_edit_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_edit_grey600_36dp.png b/src/main/res/drawable-xxhdpi/ic_edit_grey600_36dp.png deleted file mode 100644 index 21b617a9..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_edit_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png new file mode 100644 index 00000000..34ec7092 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_edit_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_edit_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_edit_white_48dp.png deleted file mode 100644 index fe5bd13f..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_edit_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_group_add_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_group_add_white_24dp.png new file mode 100644 index 00000000..a5ad0a29 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_group_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_group_add_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_group_add_white_48dp.png deleted file mode 100644 index 7ff60d6f..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_group_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_group_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_group_white_24dp.png new file mode 100644 index 00000000..a6ed594f Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_group_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_group_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_group_white_48dp.png deleted file mode 100644 index fffa6a6a..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_group_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_import_export_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_import_export_white_24dp.png new file mode 100644 index 00000000..c3497037 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_import_export_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_import_export_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_import_export_white_48dp.png deleted file mode 100644 index cabd50c0..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_import_export_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png new file mode 100644 index 00000000..b90a5980 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_lock_open_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_lock_open_white_48dp.png deleted file mode 100644 index 031eb06e..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_lock_open_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_lock_outline_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_lock_outline_white_48dp.png deleted file mode 100644 index f57082d8..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_lock_outline_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png new file mode 100644 index 00000000..0dcada81 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png new file mode 100644 index 00000000..074db2d3 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_person_add_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_person_add_white_48dp.png deleted file mode 100644 index ba242487..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_person_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_refresh_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_refresh_white_48dp.png deleted file mode 100644 index 87ab2d64..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_refresh_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_remove_grey600_36dp.png b/src/main/res/drawable-xxhdpi/ic_remove_grey600_36dp.png deleted file mode 100644 index 4b1003db..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_remove_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png new file mode 100644 index 00000000..0bbeab15 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_search_white_48dp.png b/src/main/res/drawable-xxhdpi/ic_search_white_48dp.png deleted file mode 100644 index 75d9aa69..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_search_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_settings_grey600_24dp.png b/src/main/res/drawable-xxhdpi/ic_settings_grey600_24dp.png new file mode 100644 index 00000000..6a70402b Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_settings_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_settings_grey600_36dp.png b/src/main/res/drawable-xxhdpi/ic_settings_grey600_36dp.png deleted file mode 100644 index d47d042e..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_settings_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_warning_white_24dp.png b/src/main/res/drawable-xxhdpi/ic_warning_white_24dp.png new file mode 100644 index 00000000..3f401317 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_warning_white_24dp.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_warning_white_36dp.png b/src/main/res/drawable-xxhdpi/ic_warning_white_36dp.png deleted file mode 100644 index a6e5788b..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_warning_white_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png new file mode 100644 index 00000000..2bef0595 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_add_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_add_white_48dp.png deleted file mode 100644 index cd32f0a8..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_attach_file_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_attach_file_white_24dp.png new file mode 100644 index 00000000..caaee37a Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_attach_file_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_attach_file_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_attach_file_white_48dp.png deleted file mode 100644 index 55464b7e..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_attach_file_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_chat_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_chat_white_48dp.png deleted file mode 100644 index 68f14af6..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_chat_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_24dp.png b/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_24dp.png new file mode 100644 index 00000000..1eb62d42 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_36dp.png b/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_36dp.png deleted file mode 100644 index 435c087a..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_content_copy_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png b/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png new file mode 100644 index 00000000..e4e21812 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_delete_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png new file mode 100644 index 00000000..ccf8c716 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_delete_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_delete_white_48dp.png deleted file mode 100644 index 47fef5aa..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_delete_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png b/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png new file mode 100644 index 00000000..0c0fd76f Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_edit_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_edit_grey600_36dp.png b/src/main/res/drawable-xxxhdpi/ic_edit_grey600_36dp.png deleted file mode 100644 index 1361eedc..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_edit_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png new file mode 100644 index 00000000..9380370f Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_edit_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_edit_white_48dp.png deleted file mode 100644 index 73680649..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_edit_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_group_add_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_group_add_white_24dp.png new file mode 100644 index 00000000..0ac3d4a8 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_group_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_group_add_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_group_add_white_48dp.png deleted file mode 100644 index 7e9d67f6..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_group_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_group_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_group_white_24dp.png new file mode 100644 index 00000000..a62b5677 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_group_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_group_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_group_white_48dp.png deleted file mode 100644 index 2a27316b..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_group_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_import_export_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_import_export_white_24dp.png new file mode 100644 index 00000000..06b27ea1 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_import_export_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_import_export_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_import_export_white_48dp.png deleted file mode 100644 index ea80bc00..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_import_export_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_lock_open_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_lock_open_white_24dp.png new file mode 100644 index 00000000..8f35034c Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_lock_open_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_lock_open_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_lock_open_white_48dp.png deleted file mode 100644 index f7652e60..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_lock_open_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_lock_outline_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_lock_outline_white_48dp.png deleted file mode 100644 index 440070a1..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_lock_outline_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png new file mode 100644 index 00000000..a70c55b7 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png new file mode 100644 index 00000000..4e2121e5 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_person_add_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_person_add_white_48dp.png deleted file mode 100644 index 89c1aef2..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_person_add_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_refresh_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_refresh_white_48dp.png deleted file mode 100644 index fe0ae13a..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_refresh_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_remove_grey600_36dp.png b/src/main/res/drawable-xxxhdpi/ic_remove_grey600_36dp.png deleted file mode 100644 index 524cc0a0..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_remove_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png new file mode 100644 index 00000000..70c21baf Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_search_white_48dp.png b/src/main/res/drawable-xxxhdpi/ic_search_white_48dp.png deleted file mode 100644 index 7caf6c9b..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_search_white_48dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_settings_grey600_24dp.png b/src/main/res/drawable-xxxhdpi/ic_settings_grey600_24dp.png new file mode 100644 index 00000000..5eba9e8e Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_settings_grey600_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_settings_grey600_36dp.png b/src/main/res/drawable-xxxhdpi/ic_settings_grey600_36dp.png deleted file mode 100644 index 8fea47f6..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_settings_grey600_36dp.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp.png new file mode 100644 index 00000000..b80446e7 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_warning_white_36dp.png b/src/main/res/drawable-xxxhdpi/ic_warning_white_36dp.png deleted file mode 100644 index abc5c7a5..00000000 Binary files a/src/main/res/drawable-xxxhdpi/ic_warning_white_36dp.png and /dev/null differ diff --git a/src/main/res/values-v21/themes.xml b/src/main/res/values-v21/themes.xml index 75539533..a1f3d0c5 100644 --- a/src/main/res/values-v21/themes.xml +++ b/src/main/res/values-v21/themes.xml @@ -10,25 +10,23 @@ 14sp 20sp - @drawable/ic_group_add_white_48dp - @drawable/ic_person_add_white_48dp + @drawable/ic_group_add_white_24dp + @drawable/ic_person_add_white_24dp @drawable/ic_cancel_white_24dp - @drawable/ic_chat_white_48dp - @drawable/ic_content_copy_grey600_36dp - @drawable/ic_delete_white_48dp + @drawable/ic_content_copy_grey600_24dp + @drawable/ic_delete_white_24dp @drawable/ic_file_download_white_24dp - @drawable/ic_edit_white_48dp - @drawable/ic_edit_grey600_36dp - @drawable/ic_group_white_48dp - @drawable/ic_add_white_48dp - @drawable/ic_attach_file_white_48dp - @drawable/ic_lock_open_white_48dp - @drawable/ic_refresh_white_48dp - @drawable/ic_remove_grey600_36dp - @drawable/ic_search_white_48dp - @drawable/ic_lock_outline_white_48dp - @drawable/ic_settings_grey600_36dp - @drawable/ic_import_export_white_48dp + @drawable/ic_edit_white_24dp + @drawable/ic_edit_grey600_24dp + @drawable/ic_group_white_24dp + @drawable/ic_add_white_24dp + @drawable/ic_attach_file_white_24dp + @drawable/ic_lock_open_white_24dp + @drawable/ic_delete_grey600_24dp + @drawable/ic_search_white_24dp + @drawable/ic_lock_open_white_24dp + @drawable/ic_settings_grey600_24dp + @drawable/ic_import_export_white_24dp -- cgit v1.2.3 From 92d14c4a0090c71842440d96be1f84dab5a82d16 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 14:46:52 +0200 Subject: increased padding on image buttons on v21 to match material guidelines --- src/main/res/layout/activity_edit_account.xml | 2 +- src/main/res/layout/activity_muc_details.xml | 4 ++-- src/main/res/layout/contact_key.xml | 2 +- src/main/res/values-v21/dimens.xml | 1 + src/main/res/values/dimens.xml | 7 ++++--- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index 750c28e0..7d84a4af 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -337,7 +337,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:padding="8dp" + android:padding="@dimen/image_button_padding" android:src="?attr/icon_copy" android:visibility="visible" android:contentDescription="@string/copy_otr_clipboard_description"/> diff --git a/src/main/res/layout/activity_muc_details.xml b/src/main/res/layout/activity_muc_details.xml index 36873654..11602651 100644 --- a/src/main/res/layout/activity_muc_details.xml +++ b/src/main/res/layout/activity_muc_details.xml @@ -75,7 +75,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:padding="8dp" + android:padding="@dimen/image_button_padding" android:src="?attr/icon_edit_dark"/> @@ -102,7 +102,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:padding="8dp" + android:padding="@dimen/image_button_padding" android:src="?attr/icon_settings"/> diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index 75572877..b7817b38 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -34,7 +34,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:padding="8dp" + android:padding="@dimen/image_button_padding" android:src="?attr/icon_remove" android:visibility="invisible" /> diff --git a/src/main/res/values-v21/dimens.xml b/src/main/res/values-v21/dimens.xml index 8bc8f3f7..b689d100 100644 --- a/src/main/res/values-v21/dimens.xml +++ b/src/main/res/values-v21/dimens.xml @@ -1,4 +1,5 @@ 63dp + 12dp \ No newline at end of file diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml index 79e920e9..95e80055 100644 --- a/src/main/res/values/dimens.xml +++ b/src/main/res/values/dimens.xml @@ -1,7 +1,8 @@ - - 8dp - 8dp + + 8dp + 8dp 16dp 288dp + 8dp -- cgit v1.2.3 From d94c231a744900ca7a1297ffd0980536591d61f5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 16:25:32 +0200 Subject: adjust dimens slightly to work with v21+ (v21 doesn't count the navigation bar) --- .../fragment_conversations_overview.xml | 32 ++++++++++++++++++++++ .../fragment_conversations_overview.xml | 32 ---------------------- src/main/res/values-w585dp/dimens.xml | 4 +++ src/main/res/values-w600dp/dimens.xml | 4 --- src/main/res/values-w945dp/dimens.xml | 3 ++ src/main/res/values-w960dp/dimens.xml | 3 -- 6 files changed, 39 insertions(+), 39 deletions(-) create mode 100644 src/main/res/layout-w945dp/fragment_conversations_overview.xml delete mode 100644 src/main/res/layout-w960dp/fragment_conversations_overview.xml create mode 100644 src/main/res/values-w585dp/dimens.xml delete mode 100644 src/main/res/values-w600dp/dimens.xml create mode 100644 src/main/res/values-w945dp/dimens.xml delete mode 100644 src/main/res/values-w960dp/dimens.xml diff --git a/src/main/res/layout-w945dp/fragment_conversations_overview.xml b/src/main/res/layout-w945dp/fragment_conversations_overview.xml new file mode 100644 index 00000000..50039c03 --- /dev/null +++ b/src/main/res/layout-w945dp/fragment_conversations_overview.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout-w960dp/fragment_conversations_overview.xml b/src/main/res/layout-w960dp/fragment_conversations_overview.xml deleted file mode 100644 index 50039c03..00000000 --- a/src/main/res/layout-w960dp/fragment_conversations_overview.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/res/values-w585dp/dimens.xml b/src/main/res/values-w585dp/dimens.xml new file mode 100644 index 00000000..df6525e6 --- /dev/null +++ b/src/main/res/values-w585dp/dimens.xml @@ -0,0 +1,4 @@ + + 416dp + 32dp + diff --git a/src/main/res/values-w600dp/dimens.xml b/src/main/res/values-w600dp/dimens.xml deleted file mode 100644 index df6525e6..00000000 --- a/src/main/res/values-w600dp/dimens.xml +++ /dev/null @@ -1,4 +0,0 @@ - - 416dp - 32dp - diff --git a/src/main/res/values-w945dp/dimens.xml b/src/main/res/values-w945dp/dimens.xml new file mode 100644 index 00000000..146c0e15 --- /dev/null +++ b/src/main/res/values-w945dp/dimens.xml @@ -0,0 +1,3 @@ + + 64dp + diff --git a/src/main/res/values-w960dp/dimens.xml b/src/main/res/values-w960dp/dimens.xml deleted file mode 100644 index 146c0e15..00000000 --- a/src/main/res/values-w960dp/dimens.xml +++ /dev/null @@ -1,3 +0,0 @@ - - 64dp - -- cgit v1.2.3 From 6a15bc26b6310c5b0915e7511fba4dfa5eb2cae2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 22:23:45 +0200 Subject: npe check after reading image uri --- src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 9ae56b04..e120adbd 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -400,7 +400,9 @@ public class FileBackend { options.inSampleSize = calcSampleSize(image,Math.max(newHeight, newWidth)); is = mXmppConnectionService.getContentResolver().openInputStream(image); Bitmap source = BitmapFactory.decodeStream(is, null, options); - + if (source == null) { + return null; + } int sourceWidth = source.getWidth(); int sourceHeight = source.getHeight(); float xScale = (float) newWidth / sourceWidth; @@ -418,8 +420,6 @@ public class FileBackend { return dest; } catch (FileNotFoundException e) { return null; - } catch (IOException e) { - return null; } finally { close(is); } -- cgit v1.2.3 From 06244011379d8ab61cdc032fc88063c54227ed7d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Apr 2015 22:23:59 +0200 Subject: version bump to 1.3.0-beta --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 37050656..0fe56ff8 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 58 - versionName "1.3.0-beta" + versionCode 59 + versionName "1.3.0-beta2" } compileOptions { -- cgit v1.2.3 From f0d51fcb77a728da12179fb8a044b6a78f71eb44 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 29 Apr 2015 10:19:03 +0200 Subject: pulled translations from transifex --- src/main/res/values-cs/strings.xml | 12 + src/main/res/values-es/strings.xml | 2 +- src/main/res/values-eu/strings.xml | 11 + src/main/res/values-id/strings.xml | 104 +++++++++ src/main/res/values-ja/strings.xml | 10 + src/main/res/values-ko/strings.xml | 447 +++++++++++++++++++++++++++++++++++++ src/main/res/values-nl/strings.xml | 11 + src/main/res/values-sv/strings.xml | 11 + 8 files changed, 607 insertions(+), 1 deletion(-) create mode 100644 src/main/res/values-ko/strings.xml diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml index 192df52f..f49cb1b9 100644 --- a/src/main/res/values-cs/strings.xml +++ b/src/main/res/values-cs/strings.xml @@ -429,8 +429,20 @@ Přijmout pozici Conversation zavřena Opustil(a) konferenci + Nastavení certifikátu Nedůvěřovat systémovým CA Všechny certifikáty musí být schváleny ručně + Odstranit certifikáty + Smazat ručně povolené certifikáty + Žádné ručně povolené certifikáty + Odstranit certifikáty + Smazat výběr + Zrušit + + %d certifikát smazán + %d certifikáty smazány + %d certifikátů smazáno + Vybrat %d kontakt Vybrat %d kontakty diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 16531073..109715e3 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -436,7 +436,7 @@ Eliminar manualmente certificados aceptados No aceptar certificados manualmente Eliminar Certificados - Deshacer selección + Eliminar seleccionados Cancelar %d certificado eliminado diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 42309661..ac66bfc1 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -429,8 +429,19 @@ Kokapena jaso da Elkarrizketa itxi egin da Konferentzia utzi egin da + Ziurtagirien aukerak Sistemaren CAtaz ez fidatu Ziurtagiri guztiak eskuz onartu behar dira + Ziurtagiriak kendu + Eskuz ezabatu onartutako ziurtagiriak + Ez dago eskuz onartutako ziurtagiririk + Ziurtagiriak kendu + Aukeratutakoak ezabatu + Utzi + + Ziurtagiri %d ezabatua + %d ziurtagiri ezabatuak + Hautatu kontaktu %d Hautatu %d kontaktu diff --git a/src/main/res/values-id/strings.xml b/src/main/res/values-id/strings.xml index 6c2dedb6..69bd0911 100644 --- a/src/main/res/values-id/strings.xml +++ b/src/main/res/values-id/strings.xml @@ -74,6 +74,7 @@ Hapus Riwayat Percakapan Apakah Anda ingin menghapus semua pesan dalam Percakapan ini\n\nPeringatan:ini tidak akan mempengaruhi pesan yang disimpan pada perangkat atau server lain. Hapus pesan + Akhiri percakapan setelahnya Pilih kehadiran untuk kontak Kirim pesan teks biasa Kirim pesan terenskripsi OTR @@ -83,11 +84,13 @@ Kirim tidak terenkripsi Dekripsi gagal. Mungkin Anda tidak memiliki kunci pribadi yang tepat. OpenKeychain + Conversations menggunakan app pihak ke-3 bernama OpenKeychain untuk mengenkripsi dan menerjemahkan pesan dan mengorganisir kunci anda.\n\nOpenKeychain berlisensi GPLv3 dan tersedia fi F-Droid dan Google play.\n\n(Silahkan mulai ulang Conversations setelah menginstall.) Mulai ulang Pasang menawarkan... menunggu... Tidak ada kunci OpenPGP ditemukan + Conversations tidak dapat mengenkripsi pesan Anda karena kontak tidak mengumumkan kunci publiknya.\n\nSilakan meminta kontak Anda untuk menyetel OpenPGP Tidak ada kunci OpenPGP ditemukan Percakapan tidak dapat mengenkripsi pesan Anda karena kontak tidak mengumumkan kunci publik mereka.\n\nSilakan meminta kontak Anda untuk setup OpenPGP. Pesan terenkripsi diterima. Sentuh untuk membongkar dan melihatnya. @@ -154,8 +157,51 @@ Hapus akun Sementara dimatikan Publikasikan avatar + Publikasikan kunci OpenPGP + Aktifkan Akun + Apakah Anda yakin.? + Jika Anda menghapus akun, semua data percakapan Anda di Conversation akan hilang. + Rekam suara + Jabber ID + Password + username@example.com + Ketik ulang password + Password + Ketik ulang password + Password tidak sama + Jabber ID tidak valid + Memori habis. Gambar terlalu besar + Apakah anda ingin menambahkan %s ke daftar kontak anda? + online + bebas untuk chatting + pergi + pergi lama + jangan ganggu + offline + Conference + Member lainnya + Info Server + XEP-0313: MAM + XEP-0280: Message Carbons + XEP-0352: Client State Indication + XEP-0191: Blocking Command + XEP-0237: Roster Versioning + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) + tersedia + tidak tersedia + Pemberitahuan kunci publik tidak ditemukan + terakhir terlihat sekarang + terakhir terlihat 1 menit lalu + terlihat %d menit lalu + terlihat 1 jam lalu + terlihat %d jam lalu + terlihat 1 hari lalu terlihat %d hari lalu tidak pernah terlihat + Pesan terenskripsi. Pasang OpenKeychain untuk menerjemahkan + Sidik OTR tidak diketahui + pesan terkunci OpenPGP ditemukan Penerimaan gagal Fingerprint Anda OTR fingerprint @@ -176,13 +222,30 @@ room@conference.example.com Simpan sebagai bookmark Hapus bookmark + Bookmark ini sudah ada Anda + Ubah subjek conference Conference tidak ditemukan + Tinggalkan + Kontak ditambahkan ke daftar anda Tambah kembali + %s telah membaca hingga disini + Publikasi + Sentuh Avatar untuk memilih gambar dari gallery + Harap dicatat: Setiap orang yang berlangganan update kehadiran Anda akan diizinkan untuk melihat gambar ini. + Mempublikasi... + Server tidak mengijinkan publikasi Anda + Sesuatu yang salah terjadi ketika mengkonversi gambar anda + Tidak dapat menyimpan Avatar ke memori + (Tekan yang lama untuk mengembalikan semula) + Server Anda tidak mendukung publikasi Avatar + berbisik + kepada %s Kirim pesan pribadi ke %s Hubungkan Akun ini sudah ada Selanjutnya + Sesi saat didirikan Informasi tambahan Lewati Nonaktifkan notifikasi @@ -191,7 +254,13 @@ Aktifkan Conference membutuhkan password Masukan password + Pembaruan kehadiran hilang dari kontak + Silakan meminta pembaruan kehadiran dari kontak Anda lebih dulu.\n\nIni akan digunakan untuk menentukan (klien) mana yang digunakan dikontak Anda. + Request sekarang + Hapus sidik jari + Apakah anda yakin menghapus sidik jari? Abaikan + Perhatian Mengirim ini tanpa kehadiran sesama pembaruan bisa menyebabkan masalah tak terduga.\n\nPergi ke kontak untuk memverifikasi langganan kehadiran anda. Pengaturan enskripsi Paksa enskripsi end-to-end Selalu mengirim pesan terenkripsi (kecuali untuk conferences) @@ -205,9 +274,20 @@ Waktu mulai Waktu selesai Aktifkan waktu sunyi + Pemberitahuan akan disunyukan ketika jam sunyi. Perbesar ukuran huruf + Gunakan ukuran huruf lebih besar diseluruh aplikasi Tombol kirim menunjukan statusnya + Permintaan penerimaan pesan + Pesan yang diterima akan ditambahkan centang hijau jika didukung + Warnai tombol kirim untuk mengindikasikan status kontak Lainnya + nama Conference + Gunakan subjek \'room\' daripada JID untuk mengidentifikasi conferences + sidik jari OTR disalin ke clipboard! + Anda ditendang dari conference ini + Conference ini hanya untuk member terdaftar + Anda telah ditendang dari conference ini menggunakan akun %s Mengecek gambar di host HTTP Berkas gambar telah dihapus @@ -226,11 +306,23 @@ Tampilkan kode QR Tampilkan daftar blokir Detil akun + Verifikasi OTR + Remote Sidik jari + pindai + (atau menyentuh telepon) + Socialist Millionaire Protocol + Petunjuk atau Pertanyaan + Rahasia bersama + Konfirmasi Sedang diproses + Menanggapi Gagal + Rahasia tidak match Coba lagi Selesai Terverifikasi! + Kontak meminta verifikasi SMP + Tidak ada sesi OTR yang valid ditemukan! Percakapan Jaga layanan di latar depan Cegah sistem operasi mematikan koneksi @@ -267,6 +359,8 @@ Tidak dapat mengubah password Kirim pesan untuk memulai obrolan dienkripsi Bertanya + Jika Anda dan kontak Anda memiliki rahasia yang sama yang tidak ada orang lain yang tahu (seperti sebuah lelucon atau hanya apa yang Anda punya untuk makan siang terakhir kali Anda bertemu) Anda dapat menggunakan rahasia itu untuk memverifikasi sidik jari masing-masing.\n\nAnda memberikan petunjuk atau pertanyaan untuk kontak yang akan merespon dengan jawaban case-sensitive. + Kontak Anda ingin memverifikasi sidik jari Anda dengan menantang Anda dengan rahasia bersama. Kontak Anda memberikan petunjuk berikut atau pertanyaan untuk rahasia itu. Petunjuk Anda tidak boleh kosong Rahasia bersama Anda tidak boleh kosong Hati-hati membandingkan sidik jari yang ditunjukkan di bawah dengan sidik jari kontak Anda.\nAnda dapat mengunakan layanan komunikasi terpercaya seperti e-mail terenskripsi atau panggilan telepon untuk menukarkannya. @@ -335,8 +429,18 @@ Lokasi yang diterima Percakapan tertutup Tinggalkan conference + Opsi Sertifikat Jangan percaya sistem CA Semua sertifikat harus disetujui secara manual + Hapus sertifikat + Hapus sertifikat yang disahkan secara manual + Tidak ada sertifikat yang disahkan secara manual + Hapus sertifikat + Hapus seleksi + Batal + + %d sertifikat dihapus + Pilih %d kontak diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 0996334e..35fb5472 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -429,8 +429,18 @@ 位置を受信しました 会話が閉じられました 退出した会話 + 証明書オプション システムの CA を信頼しない すべての証明書を手動で承認する必要があります + 証明書を削除 + 手動で承認された証明書を削除します + 手動で承認された証明書はありません + 証明書を削除 + 選択を削除 + キャンセル + + %d 証明書を削除しました + %d 連絡先を選択 diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml new file mode 100644 index 00000000..d00ab0fd --- /dev/null +++ b/src/main/res/values-ko/strings.xml @@ -0,0 +1,447 @@ + + + 설정 + 새 대화 + 계정 + 이 대화 + 연락처 정보 + 회의 정보 + 안전한 대화 + 계정 추가 + 이름 편집 + 주소록에 추가 + 명단에서 삭제 + 연락처 + 연락처 차단 해제 + 도메인 차단 + 도메인 차단 해제 + 계정 관리 + 설정 + 회의 정보 + 연락처 정보 + 대화 공유 + 대화 시작 + 연락처 선택 + 목록 차단 + 방금 + 1분 전 + %d 분 전 + 읽지 않은 대화 + 보내는중... + 메세지 복호화중입니다. 기다리세요... + 사용중인 별명입니다 + 관리자 + 소유자 + 중재자 + 참가자 + 방문자 + %s 를 당신의 명단에서 삭제하시겠습니까? 이 연락처와 연관된 대화는 삭제되지 않습니다. + %s 이(가) 당신에게 메세지를 보내지 못하도록 차단할까요? + %s 로부터 메세지를 받을 수 있도록 차단을 해제할까요? + %s 의 모든 연락처를 차단할까요? + %s 의 모든 연락처를 차단 해제할까요? + 연락처 차단됨 + %s 를 즐겨찾기에서 삭제할까요? 이 즐겨찾기와 연관된 대화는 삭제되지 않습니다. + 서버에서 새 계정을 등록 + 서버에서 비밀번호 변경 + 공유 + 대화 시작 + 연락처 초대 + 연락처 + 취소 + 설정 + 추가 + 편집 + 삭제 + 차단 + 차단 해제 + 저장 + 확인 + Conversations가 작동 중지되었습니다 + Stack trace 정보를 보냄으로서 Conversations의 개발에 기여할 수 있습니다. 경고: 이것은 Stack trace 정보를 개발자에게 보내기 위해 당신의 XMPP 계정을 사용할 것입니다. + 지금 보내기 + 더이상 묻지 않기 + 계정에 접속할 수 없습니다 + 다중 계정에 접속할 수 없습니다 + 여기를 선택해 당신의 계정을 관리하세요 + 파일 첨부 + 연락처가 당신의 명단에 없습니다. 추가하시겠습니까? + 연락처 추가 + 전송 실패 + 거부됨 + 이미지 전송 준비중 + 기록 삭제 + 대화 기록 삭제 + 이 대화의 모든 메세지를 삭제하시겠습니까? 경고: 이것은 다른 기기나 서버에 있는 메세지에는 영향을 미치지 않습니다. + 메세지 삭제 + 나중에 이 대화 끝내기 + 연락할 프레즌스 선택 + 평문 메세지 전송 + OTR 암호화된 메세지 전송 + OpenPGP 암호화된 메세지 전송 + 닉네임이 변경되었습니다 + 이미지 다운로드 + 암호화하지 않고 전송 + 복호화 실패. 올바른 개인 키를 가지고 있지 않은 것 같습니다. + OpenKeychain + Conversations는 메세지를 암호화 및 복호화하고 공개 키를 관리하기 위해 OpenKeychain이라는 제 3자 앱을 활용합니다. OpenKeychain은 GPLv3 라이센스를 사용하며 F-Droid와 Google Play에서 구하실 수 있습니다. (이후 Conversations를 재시작하세요) + 재시작 + 설치 + 제공중... + 대기중... + OpenPGP 키가 발견되지 않음 + 당신의 연락처가 그들의 공개 키를 선언하지 않고 있기 때문에 Conversations는 당신의 메세지를 암호화할 수 없습니다. OpenPGP를 설정하도록 당신의 연락처에게 물어보세요. + OpenPGP 키가 발견되지 않음 + 당신의 연락처가 그들의 공개 키를 선언하지 않고 있기 때문에 Conversations는 당신의 메세지를 암호화할 수 없습니다. OpenPGP를 설정하도록 당신의 연락처에게 물어보세요. + 암호화된 메세지 수신됨. 터치해서 복호화 및 열람하세요. + 일반 + XMPP 자원 + 이 클라이언트가 자신을 알아보는 이름 + 파일 수락 + 이 크기보다 작은 파일을 자동으로 수락 + 알림 설정 + 알림 + 새 메세지 도착시 알림 + 진동 + 새 메세지 도착시 진동 + 소리 + 알림과 동시에 벨소리 재생 + 회의 알림 + 새 회의 메세지가 도착시, 강조됐을 때 뿐만 아니라 항상 알림 + 알림 유예 + Carbon Copy 수신 후에 잠시동안 알림 해제 + 추가 설정 + 충돌 보고서 보내지 않음 + Stack trace 정보를 보냄으로서 Conversations의 개발에 기여할 수 있습니다 + 메세지 확인 + 메세지를 수신하고 읽었는지를 연락처에게 알려줌 + 사용자 환경 설정 + OpenKeychain이 오류를 보고합니다 + 파일 복호화 입출력 오류 + 수락 + 오류가 발생했습니다 + 프레즌스 업데이트 허가 + 당신이 추가한 연락처의 프레즌스 구독을 선제적으로 허가 및 요청함 + 구독 + 당신의 계정 + + 프레즌스 업데이트 보내기 + 프레즌스 업데이트 받기 + 프레즌스 업데이트 요청 + 사진 선택 + 사진 찍기 + 구독 요청을 선제적으로 허가 + 선택한 파일은 이미지가 아닙니다 + 이미지 파일 변환 중 오류 발생 + 파일을 찾을 수 없음 + 일반 입출력 오류. 저장소 공간이 부족한 것 같습니다. + 이 이미지를 선택하기 위해 사용한 앱이 이 파일을 읽는데 필요한 충분한 허가를 제공하지 않았습니다. 다른 파일 탐색기를 이용해 이미지를 선택하세요. + 알 수 없음 + 임시로 해제 + 접속중 + 접속중\u2026 + 오프라인 + 승인되지 않음 + 서버를 찾을 수 없음 + 접속할 수 없음 + 등록 실패 + 사용자 이름이 이미 사용중입니다 + 등록 성공 + 서버가 등록을 지원하지 않습니다 + 보안 오류 + 호환되지 않는 서버 + 평문 + OTR + OpenPGP + 계정 편집 + 계정 삭제 + 임시로 해제 + 아바타 공개 + OpenPGP 공개 키 공개 + 계정 사용 + 확실합니까? + 계정을 삭제하면 당신의 모든 대화 기록이 사라집니다 + 녹음 + Jabber ID + 비밀번호 + username@example.com + 암호 확인 + 암호 + 암호 확인 + 암호가 일치하지 않습니다 + 올바른 Jabber ID가 아닙니다 + 메모리 부족. 이미지 용량이 너무 큽니다 + %s를 기기의 연락처 목록에 추가하시겠습니까? + 접속중 + 대화 가능 + 자리 비움 + 장기간 비움 + 방해 금지 + 오프라인 + 회의 + 다른 멤버 + 서버 정보 + XEP-0313: MAM + XEP-0280: Message Carbons + XEP-0352: Client State Indication + XEP-0191: Blocking Command + XEP-0237: Roster Versioning + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) + 가능 + 불가 + 공개 키 선언 누락 + 방금 전까지 접속했었음 + 1분 전까지 접속했었음 + %d 분 전까지 접속했었음 + 1시간 전까지 접속했었음 + %d 시간 전까지 접속했었음 + 1일 전까지 접속했었음 + %d 일 전까지 접속했었음 + 접속한적 없음 + 암호화된 메세지. 복호화하기 위해 OpenKeychain을 설치하세요. + 알 수 없는 OTR 지문 + OpenPGP 암호화 메세지 발견 + 접수 실패 + 당신의 지문 + OTR 지문 + 검증 + 복호화 + 회의 + 검색 + 연락처 생성 + 회의 참석 + 연락처 삭제 + 연락처 정보 보기 + 연락처 차단 + 연락처 차단 해제 + 만들기 + 이미 존재하는 연락처입니다 + 참석 + 회의 주소 + room@conference.example.com + 즐겨찾기로 저장 + 즐겨찾기 삭제 + 즐겨찾기가 이미 존재합니다 + 당신 + 회의 제목 편집 + 회의를 찾을 수 없습니다 + 퇴장 + 연락처가 당신을 연락처 목록에 추가했습니다 + Add back + %s 가 여기까지 읽었습니다 + 공개 + 갤러리에서 사진을 선택하기 위해 아바타를 터치하세요 + 참고하세요: 당신의 프레즌스 업데이트를 구독한 모든 사람들은 이 사진을 볼 수 있습니다 + 공개중... + 서버가 당신의 발표를 거부했습니다 + 사진을 변환하는 중 오류가 발생했습니다 + 아바타를 저장할 수 없습니다 + (혹은 기본값을 되돌리기 위해 길게 누름) + 서버가 아바타 발표를 지원하지 않습니다 + 속삭임 + %s 에게 + %s 에게 개인 매세지 보내기 + 접속 + 계정이 이미 존재합니다 + 다음 + 현재 세션이 수립되었습니다 + 추가 정보 + 건너뛰기 + 알림 해제 + 이 대화의 알림 해제 + 알림이 해제되었습니다 + 사용 + 회의에 암호가 필요합니다 + 암호 입력 + 연락처로부터 프레즌스 업데이트 찾을 수 없음 + 먼저 연락처로부터 프레즌스 업데이트를 요청하세요. 이는 당신의 연락처가 어떤 클라이언트를 사용하는지 결정하는 데 사용됩니다. + 지금 요청 + 지문 삭제 + 이 지문을 삭제하시겠습니까? + 무시 + 경고: 상호간의 프레즌스 업데이트 없이 이것을 보내면 예기치 못한 문제를 발생시킬 수 있습니다. 당신의 프레즌스 구독을 검증하기 위해 연락처 상세 정보로 가세요. + 암호화 설정 + 강제적인 종단간 암호화 + 언제나 암호화 메세지로 전송 (회의 제외) + 암호화된 메세지 저장하지 않음 + 경고: 메세지가 손실될 수 있습니다 + 전문가 설정 + 설정시 주의하시기 바랍니다 + Conversations에 대해서 + 빌드 및 라이센스 정보 + 무음 시간대 + 시작 시간 + 마감 시간 + 무음 시간대 사용 + 무음 시간대에는 알림이 해제됩니다 + 글자 크기 증가 + 앱 전반에 큰 글자 크기를 사용합니다 + 전송 버튼이 상태를 나타냄 + 메세지 영수증 요청 + 만약 지원될 경우, 수신된 메세지는 초록색 기호로 표시됩니다. + 연락처 상태를 표시하기 위해 전송 버튼을 색칠함 + 기타 + 회의 이름 + 회의를 식별하기 위해 JID 대신 방 제목을 사용 + OTR 지문이 클립보드에 복사되었습니다 + 당신은 이 회의에서 금지되었습니다 + 이 회의는 멤버 전용입니다 + 당신은 이 회의에서 추방되었습니다 + using account %s + HTTP 호스트에서 이미지 확인중 + 이미지 파일이 삭제되었습니다 + 접속중이 아닙니다. 다시 시도하세요. + 이미지 파일 크기 확인 + 메세지 설정 + 텍스트 복사 + 원본 URL 복사 + 다시 보내기 + 이미지 URL + 메세지 텍스트 + URL이 클립보드에 복사되었습니다 + 메세지가 클립보드에 복사되었습니다 + 이미지 전송 실패 + QR코드 스캔 + QR코드 보기 + 차단 목록 보기 + 계정 정보 + OTR 검증 + Remote Fingerprint + 스캔 + (혹은 기기 터치) + Socialist Millionaire Protocol + 힌트 혹은 질문 + 공유된 비밀 + 확인 + 진행중 + 응답 + 실패 + 비밀이 일치하지 않습니다 + 다시 시도하세요 + 완료 + 검증 완료 + 연락처가 SMP 검증을 요구했습니다 + 올바른 OTR 세션이 발견되지 않았습니다 + Conversations + 포어그라운드에서 서비스 유지 + 운영체제가 접속을 해제하지 못하도록 예방합니다 + 파일 선택 + 수신중 %1$s (%2$d%% 완료) + %s 다운로드 + 파일 + %s 열기 + 전송중 (%1$d%% 완료) + 파일 전송 준비중 + %s 다운로드 제공됨 + 전송 취소 + 파일 전송 실패 + 파일이 삭제되었습니다 + 파일을 열기 위한 앱이 발견되지 않았습니다 + 지문을 검증할 수 없습니다 + 수동 검증 + 연락처의 OTR 지문을 검증하시겠습니까? + 동적 태그 표시 + 연락처 밑에 읽기 전용 태그 표시 + 알림 사용 + 회의 생성 + 회의 서버가 발견되지 않았습니다 + 회의 생성 실패 + 회의 생성됨 + 비밀 접수됨 + 초기화 + 계정 아바타 + OTR 지문을 클립보드에 복사 + 서버로부터 기록 가져오는중 + 서버에 더이상 기록이 없습니다 + 업데이트중... + 암호 변경됨 + 암호를 변경할 수 없습니다 + 암호화된 대화를 시작하기 위해 메세지 보내기 + 질문하기 + 만약 당신과 당신의 연락처가 다른 사람은 모르는 비밀을 공유하고 있다면, 그 비밀을 서로의 지문을 검증하는 데 사용할 수 있습니다. 대소문자가 구분된 대답을 할 연락처에게 힌트나 질문을 주세요. + 당신의 연락처는 당신의 지문을 검증하고자 공유된 비밀을 확인하려고 합니다. 당신의 연락처는 그 비밀에 관한 다음과 같은 힌트 혹은 질문을 제공했습니다. + 힌트를 반드시 입력해야 합니다 + 공유된 비밀을 반드시 입력해야 합니다 + 아래에 보이는 지문을 당신의 연락처의 지문과 세심하게 비교하세요. 당신은 암호화된 이메일이나 전화와 같은 믿을만한 통신수단으로 이것을 주고 받을 수 있습니다. + 암호 변경 + 현재 암호 + 새 암호 + 암호를 반드시 입력해야 합니다 + 모든 계정 사용 + 모든 계정 해제 + 다음으로 동작을 수행 + 관련 없음 + 역할 없음 + 추방됨 + 멤버 + 고급 모드 + 멤버십 허가 + 멤버십 철회 + 관리자 특권 허가 + 관리자 특권 철회 + 회의에서 제거 + %s 의 관련 여부를 변경할 수 없습니다 + 회의에서 금지 + %s 를 공개 회의에서 제거하려고 하고 있습니다. 유일한 방법은 이 사용자를 앞으로 금지시키는 것입니다. + 지금 금지 + %s 의 역할을 변경할 수 없습니다 + 공개적으로 접근 가능한 회의 + 멤버 전용 사설 회의 + 회의 설정 + 사설 (멤버 전용) + 익명 아님 + 회의 설정 변경됨 + 회의 설정을 변경할 수 없습니다 + 안함 + 30분 + 1시간 + 2시간 + 8시간 + 나중에 알릴때까지 + 입력 설정 + 엔터 키로 전송 + 엔터 키로 메세지를 보냅니다 + 엔터 키 표시 + 이모티콘 키를 엔터 키로 바꿉니다 + 오디오 + 비디오 + 이미지 + PDF 문서 + 안드로이드 앱 + 연락처 + %s 수신 + 포어그라운드 서비스 해제 + 터치해서 Conversations 열기 + 아바타가 공개되었습니다 + %s 전송중 + %s 제공중 + 오프라인 숨기기 + 계정 해제 + %s 이(가) 입력중입니다... + %s 이(가) 입력을 중단했습니다 + 입력 알림 + 새 메세지를 작성할 때 이를 연락처에게 알립니다 + 위치 전송 + 위치 표시 + 위치를 표시할 수 있는 앱이 발견되지 않았습니다 + 위치 + 위치 수신 + 대화 끝남 + 회의에서 나감 + 인증 설정 + 시스템 CA를 신뢰하지 않음 + 모든 인증서는 수동으로 승인되어야 함 + 인증서 삭제 + 수동으로 승인된 인증서 삭제 + 수동으로 승인된 인증서 없음 + 인증서 삭제 + 선택 삭제 + 취소 + + %d 인증서 삭제됨 + + + %d 연락처 선택 + + diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 650e18c4..2532130d 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -429,8 +429,19 @@ Locatie ontvangen Gesprek gesloten Groepsgesprek verlaten + Certificaatopties Vertrouw geen systeem-CA\'s. Alle certificaten moeten handmatig goedgekeurd worden + Verwijder certificaten + Verwijder handmatig goedgekeurde certificaten + Geen handmatig goedgekeurde certificaten + Verwijder certificaten + Verwijder selectie + Annuleer + + %d certificaat verwijderd + %d certificaten verwijderd + Selecteer %d contact Selecteer %d contacten diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index b411f484..4f84110b 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -429,8 +429,19 @@ Mottog position Konversation stängd Lämnade konferens + Certifikatalternativ Lita inte på systemets CAs Alla certifikat måste manuellt godkännas + Ta bort certifikat + Ta bort manuellt accepterade certifikat + Inga manuellt accepterade certifikat + Ta bort certifikat + Ta bort val + Avbryt + + %d certifikat borttaget + %d certifikat borttagna + Välj %d kontakt Välj %d kontakter -- cgit v1.2.3 From bcdfdb9ccf4cdd4e875850bc45852eb14ed6faf1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 29 Apr 2015 16:15:07 +0200 Subject: added config option to be a bit more verbose about stanza counts --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../eu/siacs/conversations/xmpp/XmppConnection.java | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index f38bcbfc..5cca6c0b 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -28,6 +28,7 @@ public final class Config { public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance + public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index cf580df1..0b6bb15b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -339,12 +339,18 @@ public class XmppConnection implements Runnable { sendInitialPing(); } else if (nextTag.isStart("r")) { tagReader.readElement(nextTag); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": acknowledging stanza #" + this.stanzasReceived); + } final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion); tagWriter.writeStanzaAsync(ack); } else if (nextTag.isStart("a")) { final Element ack = tagReader.readElement(nextTag); lastPacketReceived = SystemClock.elapsedRealtime(); final int serverSequence = Integer.parseInt(ack.getAttribute("h")); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence); + } final String msgId = this.messageReceipts.get(serverSequence); if (msgId != null) { if (this.acknowledgedListener != null) { @@ -598,8 +604,10 @@ public class XmppConnection implements Runnable { } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { - final ResumePacket resume = new ResumePacket(this.streamId, - stanzasReceived, smVersion); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": resuming after stanza #"+stanzasReceived); + } + final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived, smVersion); this.tagWriter.writeStanzaAsync(resume); } else if (this.streamFeatures.hasChild("bind") && shouldBind) { sendBindRequest(); @@ -787,7 +795,7 @@ public class XmppConnection implements Runnable { sendEnableCarbons(); } if (getFeatures().blocking() && !features.blockListRequested) { - Log.d(Config.LOGTAG, "Requesting block list"); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": Requesting block list"); this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser()); } } @@ -894,7 +902,9 @@ public class XmppConnection implements Runnable { } tagWriter.writeStanzaAsync(packet); if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) { - Log.d(Config.LOGTAG, "request delivery report for stanza " + stanzasSent); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent); + } this.messageReceipts.put(stanzasSent, packet.getId()); tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion)); } -- cgit v1.2.3 From e1fab8a488ea99271f1920056f58c779bf300bdf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 May 2015 13:52:19 +0200 Subject: pulled translations from transifex --- src/main/res/values-el/strings.xml | 11 +++++++ src/main/res/values-ru/strings.xml | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index ec1da08c..01b33908 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -429,8 +429,19 @@ Ελήφθη τοποθεσία Η συζήτηση έκλεισε Έφυγε από την συνδιάσκεψη + Επιλογές πιστοποιητικών Μη έμπιστες αρχές πιστοποίησης συστήματος Όλα τα πιστοποιητικά πρέπει να εγκριθούν χειροκίνητα + Αφαίρεση πιστοποιητικών + Διαγραφή με μη αυτόματο τρόπο των αναγνωρισμένων πιστοποιητικών + Δεν υπάρχουν με μη αυτόματο τρόπο αναγνωρισμένα πιστοποιητικα + Αφαίρεση πιστοποιητικών + Διαγραφή επιλογής + Ακύρωση + + %d πιστοποιητικο διαγραφθηκε + %d πιστοποιητικά διαγραφθηκαν + Επιλογή %d επαφής Επιλογή %d επαφών diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index fb39e24a..2fc257f7 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -389,4 +389,63 @@ Публичная конференция Приватная конференция только для членов Настройки конференции + Закрытый доступ (только для участников) + Не анонимно + Настройки конференции изменены! + Не удалось изменить настройки конференции + Никогда + 30 минут + 1 час + 2 часа + 8 часов + До следующего уведомления + Настройки ввода + Отправить на \"Enter\" + Клавиша \"Enter\" отправляет сообщение + Показывать клавишу ввода + Поменять кнопку смайликов на кнопку ввода + аудио + звук + изображение + PDF-документ + Приложение Android + Контакт + Получено %s + Отключить фоновую службу + Коснитесь, чтобы открыть Conversations + Аватар загружен! + Отправляется %s + Предложен %s + Скрыть пользователей вне сети + Отключить учётную запись + %s набирает сообщение... + %s прекратил набор + Оповещения о наборе + Позволяет вашим контактам видеть когда вы пишете новое сообщение + Отправить местоположение + Показать местоположение + Не найдено приложений для отображения местоположения + Местоположение + Получено местоположение + Беседа окончена + Покинул беседу + Опции сертификата + Не доверять системным УЦ + Все сертификаты должны быть подтверждены вручную + Удалить сертификат + Удалить сертификаты, подтверждённые вручную + Не найдено сертификатов, подтверждённых вручную + Удалить сертификаты + Удалить отмеченное + Отмена + + Удалён %d сертификат + Удалено %d сертификатов + Удалено %d сертификатов + + + Выбран %d контакт + Выбрано %d контактов + Выбрано %d контактов + -- cgit v1.2.3 From 8617932aad2f9604d7d5ce1321da6926a7bf2f37 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 May 2015 13:52:56 +0200 Subject: version bump to 1.3.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0fe56ff8..a4062ec3 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 59 - versionName "1.3.0-beta2" + versionCode 60 + versionName "1.3.0" } compileOptions { -- cgit v1.2.3 From 53fea9e1fe25a1f0f2a7fe219195b0009ecb4f5b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 11:38:56 +0200 Subject: replace send button with quick action button as long as no text has been entered --- art/ic_action_send_now.svg | 69 -- art/ic_received_indicator.svg | 16 +- art/ic_send_location_away.svg | 54 ++ art/ic_send_location_dnd.svg | 54 ++ art/ic_send_location_offline.svg | 54 ++ art/ic_send_location_online.svg | 54 ++ art/ic_send_photo_away.svg | 60 ++ art/ic_send_photo_dnd.svg | 60 ++ art/ic_send_photo_offline.svg | 60 ++ art/ic_send_photo_online.svg | 60 ++ art/ic_send_text_away.svg | 69 ++ art/ic_send_text_dnd.svg | 69 ++ art/ic_send_text_offline.svg | 69 ++ art/ic_send_text_online.svg | 69 ++ art/ic_send_voice_away.svg | 54 ++ art/ic_send_voice_dnd.svg | 54 ++ art/ic_send_voice_offline.svg | 54 ++ art/ic_send_voice_online.svg | 54 ++ art/render.rb | 16 + .../conversations/ui/ConversationActivity.java | 23 +- .../conversations/ui/ConversationFragment.java | 275 ++++--- .../res/drawable-hdpi/ic_action_send_now_away.png | Bin 932 -> 0 bytes .../res/drawable-hdpi/ic_action_send_now_dnd.png | Bin 1135 -> 0 bytes .../drawable-hdpi/ic_action_send_now_offline.png | Bin 767 -> 0 bytes .../drawable-hdpi/ic_action_send_now_online.png | Bin 1095 -> 0 bytes src/main/res/drawable-hdpi/ic_launcher.png | Bin 4497 -> 4486 bytes src/main/res/drawable-hdpi/ic_notification.png | Bin 806 -> 798 bytes .../res/drawable-hdpi/ic_received_indicator.png | Bin 686 -> 560 bytes .../res/drawable-hdpi/ic_send_location_away.png | Bin 0 -> 1159 bytes .../res/drawable-hdpi/ic_send_location_dnd.png | Bin 0 -> 1333 bytes .../res/drawable-hdpi/ic_send_location_offline.png | Bin 0 -> 971 bytes .../res/drawable-hdpi/ic_send_location_online.png | Bin 0 -> 1341 bytes src/main/res/drawable-hdpi/ic_send_photo_away.png | Bin 0 -> 1203 bytes src/main/res/drawable-hdpi/ic_send_photo_dnd.png | Bin 0 -> 1381 bytes .../res/drawable-hdpi/ic_send_photo_offline.png | Bin 0 -> 987 bytes .../res/drawable-hdpi/ic_send_photo_online.png | Bin 0 -> 1400 bytes src/main/res/drawable-hdpi/ic_send_text_away.png | Bin 0 -> 982 bytes src/main/res/drawable-hdpi/ic_send_text_dnd.png | Bin 0 -> 1126 bytes .../res/drawable-hdpi/ic_send_text_offline.png | Bin 0 -> 800 bytes src/main/res/drawable-hdpi/ic_send_text_online.png | Bin 0 -> 1143 bytes src/main/res/drawable-hdpi/ic_send_voice_away.png | Bin 0 -> 1017 bytes src/main/res/drawable-hdpi/ic_send_voice_dnd.png | Bin 0 -> 1149 bytes .../res/drawable-hdpi/ic_send_voice_offline.png | Bin 0 -> 844 bytes .../res/drawable-hdpi/ic_send_voice_online.png | Bin 0 -> 1162 bytes .../res/drawable-mdpi/ic_action_send_now_away.png | Bin 650 -> 0 bytes .../res/drawable-mdpi/ic_action_send_now_dnd.png | Bin 784 -> 0 bytes .../drawable-mdpi/ic_action_send_now_offline.png | Bin 535 -> 0 bytes .../drawable-mdpi/ic_action_send_now_online.png | Bin 779 -> 0 bytes src/main/res/drawable-mdpi/ic_launcher.png | Bin 2741 -> 2762 bytes src/main/res/drawable-mdpi/ic_notification.png | Bin 553 -> 554 bytes .../res/drawable-mdpi/ic_received_indicator.png | Bin 447 -> 402 bytes .../res/drawable-mdpi/ic_send_location_away.png | Bin 0 -> 784 bytes .../res/drawable-mdpi/ic_send_location_dnd.png | Bin 0 -> 908 bytes .../res/drawable-mdpi/ic_send_location_offline.png | Bin 0 -> 673 bytes .../res/drawable-mdpi/ic_send_location_online.png | Bin 0 -> 919 bytes src/main/res/drawable-mdpi/ic_send_photo_away.png | Bin 0 -> 776 bytes src/main/res/drawable-mdpi/ic_send_photo_dnd.png | Bin 0 -> 909 bytes .../res/drawable-mdpi/ic_send_photo_offline.png | Bin 0 -> 666 bytes .../res/drawable-mdpi/ic_send_photo_online.png | Bin 0 -> 938 bytes src/main/res/drawable-mdpi/ic_send_text_away.png | Bin 0 -> 677 bytes src/main/res/drawable-mdpi/ic_send_text_dnd.png | Bin 0 -> 769 bytes .../res/drawable-mdpi/ic_send_text_offline.png | Bin 0 -> 542 bytes src/main/res/drawable-mdpi/ic_send_text_online.png | Bin 0 -> 793 bytes src/main/res/drawable-mdpi/ic_send_voice_away.png | Bin 0 -> 679 bytes src/main/res/drawable-mdpi/ic_send_voice_dnd.png | Bin 0 -> 774 bytes .../res/drawable-mdpi/ic_send_voice_offline.png | Bin 0 -> 575 bytes .../res/drawable-mdpi/ic_send_voice_online.png | Bin 0 -> 788 bytes .../res/drawable-xhdpi/ic_action_send_now_away.png | Bin 1180 -> 0 bytes .../res/drawable-xhdpi/ic_action_send_now_dnd.png | Bin 1438 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_offline.png | Bin 968 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_online.png | Bin 1395 -> 0 bytes src/main/res/drawable-xhdpi/ic_launcher.png | Bin 6336 -> 6377 bytes src/main/res/drawable-xhdpi/ic_notification.png | Bin 1079 -> 1075 bytes .../res/drawable-xhdpi/ic_received_indicator.png | Bin 855 -> 717 bytes .../res/drawable-xhdpi/ic_send_location_away.png | Bin 0 -> 1507 bytes .../res/drawable-xhdpi/ic_send_location_dnd.png | Bin 0 -> 1721 bytes .../drawable-xhdpi/ic_send_location_offline.png | Bin 0 -> 1278 bytes .../res/drawable-xhdpi/ic_send_location_online.png | Bin 0 -> 1751 bytes src/main/res/drawable-xhdpi/ic_send_photo_away.png | Bin 0 -> 1516 bytes src/main/res/drawable-xhdpi/ic_send_photo_dnd.png | Bin 0 -> 1723 bytes .../res/drawable-xhdpi/ic_send_photo_offline.png | Bin 0 -> 1247 bytes .../res/drawable-xhdpi/ic_send_photo_online.png | Bin 0 -> 1755 bytes src/main/res/drawable-xhdpi/ic_send_text_away.png | Bin 0 -> 1270 bytes src/main/res/drawable-xhdpi/ic_send_text_dnd.png | Bin 0 -> 1395 bytes .../res/drawable-xhdpi/ic_send_text_offline.png | Bin 0 -> 1007 bytes .../res/drawable-xhdpi/ic_send_text_online.png | Bin 0 -> 1468 bytes src/main/res/drawable-xhdpi/ic_send_voice_away.png | Bin 0 -> 1257 bytes src/main/res/drawable-xhdpi/ic_send_voice_dnd.png | Bin 0 -> 1426 bytes .../res/drawable-xhdpi/ic_send_voice_offline.png | Bin 0 -> 1075 bytes .../res/drawable-xhdpi/ic_send_voice_online.png | Bin 0 -> 1433 bytes .../drawable-xxhdpi/ic_action_send_now_away.png | Bin 1426 -> 0 bytes .../res/drawable-xxhdpi/ic_action_send_now_dnd.png | Bin 1456 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_offline.png | Bin 1433 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_online.png | Bin 1458 -> 0 bytes src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 10221 -> 10254 bytes src/main/res/drawable-xxhdpi/ic_notification.png | Bin 1573 -> 1618 bytes .../res/drawable-xxhdpi/ic_received_indicator.png | Bin 1236 -> 1016 bytes .../res/drawable-xxhdpi/ic_send_location_away.png | Bin 0 -> 2229 bytes .../res/drawable-xxhdpi/ic_send_location_dnd.png | Bin 0 -> 2578 bytes .../drawable-xxhdpi/ic_send_location_offline.png | Bin 0 -> 1881 bytes .../drawable-xxhdpi/ic_send_location_online.png | Bin 0 -> 2605 bytes .../res/drawable-xxhdpi/ic_send_photo_away.png | Bin 0 -> 2256 bytes src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png | Bin 0 -> 2588 bytes .../res/drawable-xxhdpi/ic_send_photo_offline.png | Bin 0 -> 1802 bytes .../res/drawable-xxhdpi/ic_send_photo_online.png | Bin 0 -> 2571 bytes src/main/res/drawable-xxhdpi/ic_send_text_away.png | Bin 0 -> 1776 bytes src/main/res/drawable-xxhdpi/ic_send_text_dnd.png | Bin 0 -> 2004 bytes .../res/drawable-xxhdpi/ic_send_text_offline.png | Bin 0 -> 1410 bytes .../res/drawable-xxhdpi/ic_send_text_online.png | Bin 0 -> 2001 bytes .../res/drawable-xxhdpi/ic_send_voice_away.png | Bin 0 -> 1895 bytes src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png | Bin 0 -> 2152 bytes .../res/drawable-xxhdpi/ic_send_voice_offline.png | Bin 0 -> 1621 bytes .../res/drawable-xxhdpi/ic_send_voice_online.png | Bin 0 -> 2183 bytes src/main/res/drawable-xxxhdpi/ic_launcher.png | Bin 14234 -> 14117 bytes src/main/res/drawable-xxxhdpi/ic_notification.png | Bin 2063 -> 2117 bytes .../res/drawable-xxxhdpi/ic_received_indicator.png | Bin 1608 -> 1303 bytes .../res/drawable-xxxhdpi/ic_send_location_away.png | Bin 0 -> 3015 bytes .../res/drawable-xxxhdpi/ic_send_location_dnd.png | Bin 0 -> 3456 bytes .../drawable-xxxhdpi/ic_send_location_offline.png | Bin 0 -> 2523 bytes .../drawable-xxxhdpi/ic_send_location_online.png | Bin 0 -> 3514 bytes .../res/drawable-xxxhdpi/ic_send_photo_away.png | Bin 0 -> 3040 bytes .../res/drawable-xxxhdpi/ic_send_photo_dnd.png | Bin 0 -> 3544 bytes .../res/drawable-xxxhdpi/ic_send_photo_offline.png | Bin 0 -> 2491 bytes .../res/drawable-xxxhdpi/ic_send_photo_online.png | Bin 0 -> 3566 bytes .../res/drawable-xxxhdpi/ic_send_text_away.png | Bin 0 -> 2311 bytes src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png | Bin 0 -> 2597 bytes .../res/drawable-xxxhdpi/ic_send_text_offline.png | Bin 0 -> 1862 bytes .../res/drawable-xxxhdpi/ic_send_text_online.png | Bin 0 -> 2708 bytes .../res/drawable-xxxhdpi/ic_send_voice_away.png | Bin 0 -> 2491 bytes .../res/drawable-xxxhdpi/ic_send_voice_dnd.png | Bin 0 -> 2811 bytes .../res/drawable-xxxhdpi/ic_send_voice_offline.png | Bin 0 -> 2092 bytes .../res/drawable-xxxhdpi/ic_send_voice_online.png | Bin 0 -> 2868 bytes src/main/res/layout/fragment_conversation.xml | 2 +- src/main/res/values/arrays.xml | 15 + src/main/res/values/strings.xml | 813 +++++++++++---------- src/main/res/xml/preferences.xml | 8 + 136 files changed, 1597 insertions(+), 588 deletions(-) delete mode 100644 art/ic_action_send_now.svg create mode 100644 art/ic_send_location_away.svg create mode 100644 art/ic_send_location_dnd.svg create mode 100644 art/ic_send_location_offline.svg create mode 100644 art/ic_send_location_online.svg create mode 100644 art/ic_send_photo_away.svg create mode 100644 art/ic_send_photo_dnd.svg create mode 100644 art/ic_send_photo_offline.svg create mode 100644 art/ic_send_photo_online.svg create mode 100644 art/ic_send_text_away.svg create mode 100644 art/ic_send_text_dnd.svg create mode 100644 art/ic_send_text_offline.svg create mode 100644 art/ic_send_text_online.svg create mode 100644 art/ic_send_voice_away.svg create mode 100644 art/ic_send_voice_dnd.svg create mode 100644 art/ic_send_voice_offline.svg create mode 100644 art/ic_send_voice_online.svg delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_online.png diff --git a/art/ic_action_send_now.svg b/art/ic_action_send_now.svg deleted file mode 100644 index 6bde9158..00000000 --- a/art/ic_action_send_now.svg +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/art/ic_received_indicator.svg b/art/ic_received_indicator.svg index d9378c60..43689c26 100644 --- a/art/ic_received_indicator.svg +++ b/art/ic_received_indicator.svg @@ -13,7 +13,7 @@ width="95" height="95" id="Yes_check" - inkscape:version="0.48.5 r10040" + inkscape:version="0.91 r13725" sodipodi:docname="ic_received_indicator.svg"> @@ -23,7 +23,7 @@ image/svg+xml - + @@ -36,17 +36,17 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1233" - inkscape:window-height="828" + inkscape:window-width="956" + inkscape:window-height="1156" id="namedview8" showgrid="false" showguides="true" inkscape:guide-bbox="true" inkscape:zoom="5.04" - inkscape:cx="26.829268" + inkscape:cx="-4.3215257" inkscape:cy="37.489149" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:window-x="2880" + inkscape:window-y="20" inkscape:window-maximized="0" inkscape:current-layer="Yes_check" fit-margin-top="0" @@ -69,7 +69,7 @@ diff --git a/art/ic_send_location_away.svg b/art/ic_send_location_away.svg new file mode 100644 index 00000000..fcd50b52 --- /dev/null +++ b/art/ic_send_location_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_dnd.svg b/art/ic_send_location_dnd.svg new file mode 100644 index 00000000..d91fa913 --- /dev/null +++ b/art/ic_send_location_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_offline.svg b/art/ic_send_location_offline.svg new file mode 100644 index 00000000..56529b72 --- /dev/null +++ b/art/ic_send_location_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_online.svg b/art/ic_send_location_online.svg new file mode 100644 index 00000000..275a7a78 --- /dev/null +++ b/art/ic_send_location_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_photo_away.svg b/art/ic_send_photo_away.svg new file mode 100644 index 00000000..31a20e09 --- /dev/null +++ b/art/ic_send_photo_away.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_dnd.svg b/art/ic_send_photo_dnd.svg new file mode 100644 index 00000000..0e406ede --- /dev/null +++ b/art/ic_send_photo_dnd.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_offline.svg b/art/ic_send_photo_offline.svg new file mode 100644 index 00000000..b2ca20a6 --- /dev/null +++ b/art/ic_send_photo_offline.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_online.svg b/art/ic_send_photo_online.svg new file mode 100644 index 00000000..79f71347 --- /dev/null +++ b/art/ic_send_photo_online.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_text_away.svg b/art/ic_send_text_away.svg new file mode 100644 index 00000000..ea83086a --- /dev/null +++ b/art/ic_send_text_away.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_dnd.svg b/art/ic_send_text_dnd.svg new file mode 100644 index 00000000..b594f319 --- /dev/null +++ b/art/ic_send_text_dnd.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_offline.svg b/art/ic_send_text_offline.svg new file mode 100644 index 00000000..c87bfaac --- /dev/null +++ b/art/ic_send_text_offline.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_online.svg b/art/ic_send_text_online.svg new file mode 100644 index 00000000..39e3d1e8 --- /dev/null +++ b/art/ic_send_text_online.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_voice_away.svg b/art/ic_send_voice_away.svg new file mode 100644 index 00000000..379f55b7 --- /dev/null +++ b/art/ic_send_voice_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_dnd.svg b/art/ic_send_voice_dnd.svg new file mode 100644 index 00000000..372a2ca8 --- /dev/null +++ b/art/ic_send_voice_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_offline.svg b/art/ic_send_voice_offline.svg new file mode 100644 index 00000000..64ea4473 --- /dev/null +++ b/art/ic_send_voice_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_online.svg b/art/ic_send_voice_online.svg new file mode 100644 index 00000000..97284b02 --- /dev/null +++ b/art/ic_send_voice_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 2ab3e94f..32d06f8f 100755 --- a/art/render.rb +++ b/art/render.rb @@ -10,6 +10,22 @@ images = { 'conversations_baloon.svg' => ['ic_launcher', 48], 'conversations_mono.svg' => ['ic_notification', 24], 'ic_received_indicator.svg' => ['ic_received_indicator', 12], + 'ic_send_text_offline.svg' => ['ic_send_text_offline', 36], + 'ic_send_text_online.svg' => ['ic_send_text_online', 36], + 'ic_send_text_away.svg' => ['ic_send_text_away', 36], + 'ic_send_text_dnd.svg' => ['ic_send_text_dnd', 36], + 'ic_send_photo_online.svg' => ['ic_send_photo_online', 36], + 'ic_send_photo_offline.svg' => ['ic_send_photo_offline', 36], + 'ic_send_photo_away.svg' => ['ic_send_photo_away', 36], + 'ic_send_photo_dnd.svg' => ['ic_send_photo_dnd', 36], + 'ic_send_location_online.svg' => ['ic_send_location_online', 36], + 'ic_send_location_offline.svg' => ['ic_send_location_offline', 36], + 'ic_send_location_away.svg' => ['ic_send_location_away', 36], + 'ic_send_location_dnd.svg' => ['ic_send_location_dnd', 36], + 'ic_send_voice_online.svg' => ['ic_send_voice_online', 36], + 'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36], + 'ic_send_voice_away.svg' => ['ic_send_voice_away', 36], + 'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36], } images.each do |source, result| resolutions.each do |name, factor| diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index aec755fc..a76efbc3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -60,11 +60,11 @@ public class ConversationActivity extends XmppActivity public static final int REQUEST_SEND_MESSAGE = 0x0201; public static final int REQUEST_DECRYPT_PGP = 0x0202; public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207; - private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; - private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; - private static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; - private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304; - private static final int ATTACHMENT_CHOICE_LOCATION = 0x0305; + public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; + public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; + public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; + public static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304; + public static final int ATTACHMENT_CHOICE_LOCATION = 0x0305; private static final String STATE_OPEN_CONVERSATION = "state_open_conversation"; private static final String STATE_PANEL_OPEN = "state_panel_open"; private static final String STATE_PENDING_URI = "state_pending_uri"; @@ -452,7 +452,18 @@ public class ConversationActivity extends XmppActivity } } - private void attachFile(final int attachmentChoice) { + public void attachFile(final int attachmentChoice) { + switch (attachmentChoice) { + case ATTACHMENT_CHOICE_LOCATION: + getPreferences().edit().putString("recently_used_quick_action","location").apply(); + break; + case ATTACHMENT_CHOICE_RECORD_VOICE: + getPreferences().edit().putString("recently_used_quick_action","voice").apply(); + break; + case ATTACHMENT_CHOICE_TAKE_PHOTO: + getPreferences().edit().putString("recently_used_quick_action","photo").apply(); + break; + } final Conversation conversation = getSelectedConversation(); final int encryption = conversation.getNextEncryption(forceEncryption()); if (encryption == Message.ENCRYPTION_PGP) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5b1e9b4d..37ae00a3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -119,7 +119,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { + int visibleItemCount, int totalItemCount) { synchronized (ConversationFragment.this.messageList) { if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) { long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent(); @@ -145,7 +145,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa try { Message tmpMessage = messageList.get(newPosition); - while(tmpMessage.wasMergedIntoPrevious()) { + while (tmpMessage.wasMergedIntoPrevious()) { offset++; tmpMessage = tmpMessage.prev(); } @@ -174,7 +174,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (ConversationFragment.this.conversation != conversation) { return; } - messageLoaderToast = Toast.makeText(activity,resId,Toast.LENGTH_LONG); + messageLoaderToast = Toast.makeText(activity, resId, Toast.LENGTH_LONG); messageLoaderToast.show(); } }); @@ -208,7 +208,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - activity.verifyOtrSessionDialog(conversation,v); + activity.verifyOtrSessionDialog(conversation, v); } }; private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue<>(); @@ -219,7 +219,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEND) { InputMethodManager imm = (InputMethodManager) v.getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE); + .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); sendMessage(); return true; @@ -232,7 +232,25 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - sendMessage(); + Object tag = v.getTag(); + if (tag instanceof SendButtonAction) { + SendButtonAction action = (SendButtonAction) tag; + switch (action) { + case TAKE_PHOTO: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_TAKE_PHOTO); + break; + case SEND_LOCATION: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_LOCATION); + break; + case RECORD_VOICE: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_RECORD_VOICE); + break; + default: + sendMessage(); + } + } else { + sendMessage(); + } } }; private OnClickListener clickToMuc = new OnClickListener() { @@ -262,7 +280,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } Message message = new Message(conversation, mEditMessage.getText() .toString(), conversation.getNextEncryption(activity - .forceEncryption())); + .forceEncryption())); if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getNextCounterpart() != null) { message.setCounterpart(conversation.getNextCounterpart()); @@ -282,13 +300,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMode() == Conversation.MODE_MULTI && conversation.getNextCounterpart() != null) { this.mEditMessage.setHint(getString( - R.string.send_private_message_to, - conversation.getNextCounterpart().getResourcepart())); + R.string.send_private_message_to, + conversation.getNextCounterpart().getResourcepart())); } else { switch (conversation.getNextEncryption(activity.forceEncryption())) { case Message.ENCRYPTION_NONE: mEditMessage - .setHint(getString(R.string.send_plain_text_message)); + .setHint(getString(R.string.send_plain_text_message)); break; case Message.ENCRYPTION_OTR: mEditMessage.setHint(getString(R.string.send_otr_message)); @@ -304,7 +322,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } private void setupIme() { - if (((ConversationActivity)getActivity()).usingEnterKey()) { + if (((ConversationActivity) getActivity()).usingEnterKey()) { mEditMessage.setInputType(mEditMessage.getInputType() & (~InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE)); } else { mEditMessage.setInputType(mEditMessage.getInputType() | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE); @@ -313,8 +331,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public View onCreateView(final LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.fragment_conversation,container, false); + ViewGroup container, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.fragment_conversation, container, false); view.setOnClickListener(null); mEditMessage = (EditMessage) view.findViewById(R.id.textinput); setupIme(); @@ -365,21 +383,21 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } }); messageListAdapter - .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { + .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { - @Override - public void onContactPictureLongClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getCounterpart() != null) { - privateMessageWith(message.getCounterpart()); + @Override + public void onContactPictureLongClicked(Message message) { + if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getCounterpart() != null) { + privateMessageWith(message.getCounterpart()); + } } + } else { + activity.showQrCode(); } - } else { - activity.showQrCode(); } - } - }); + }); messagesView.setAdapter(messageListAdapter); registerForContextMenu(messagesView); @@ -389,7 +407,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { + ContextMenuInfo menuInfo) { synchronized (this.messageList) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; @@ -416,7 +434,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE || m.getDownloadable() != null) - && (!GeoHelper.isGeoUri(m.getBody()))) { + && (!GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(false); } if (m.getStatus() != Message.STATUS_SEND_FAILED) { @@ -425,17 +443,17 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) || m.getImageParams().url == null) && !GeoHelper.isGeoUri(m.getBody())) { copyUrl.setVisible(false); - } + } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null || !m.bodyContainsDownloadable()) { downloadImage.setVisible(false); - } + } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) - || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING - || m.getStatus() == Message.STATUS_OFFERED)))) { + || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING + || m.getStatus() == Message.STATUS_OFFERED)))) { cancelTransmission.setVisible(false); - } + } } } @@ -483,12 +501,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } shareIntent.setType(mime); } - activity.startActivity(Intent.createChooser(shareIntent,getText(R.string.share_with))); + activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); } private void copyText(Message message) { if (activity.copyTextToClipboard(message.getMergedBody(), - R.string.message_text)) { + R.string.message_text)) { Toast.makeText(activity, R.string.message_copied_to_clipboard, Toast.LENGTH_SHORT).show(); } @@ -498,7 +516,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) { DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { - Toast.makeText(activity,R.string.file_deleted,Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); return; } @@ -519,20 +537,20 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (activity.copyTextToClipboard(url, resId)) { Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show(); - } + } } private void downloadImage(Message message) { activity.xmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + .createNewConnection(message); } private void cancelTransmission(Message message) { Downloadable downloadable = message.getDownloadable(); - if (downloadable!=null) { + if (downloadable != null) { downloadable.cancel(); } else { - activity.xmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); + activity.xmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); } } @@ -548,9 +566,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa mEditMessage.getText().insert(0, nick + ": "); } else { if (mEditMessage.getText().charAt( - mEditMessage.getSelectionStart() - 1) != ' ') { + mEditMessage.getSelectionStart() - 1) != ' ') { nick = " " + nick; - } + } mEditMessage.getText().insert(mEditMessage.getSelectionStart(), nick + " "); } @@ -563,7 +581,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (this.conversation != null) { final String msg = mEditMessage.getText().toString(); this.conversation.setNextMessage(msg); - updateChatState(this.conversation,msg); + updateChatState(this.conversation, msg); } } @@ -586,7 +604,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final String msg = mEditMessage.getText().toString(); this.conversation.setNextMessage(msg); if (this.conversation != conversation) { - updateChatState(this.conversation,msg); + updateChatState(this.conversation, msg); } this.conversation.trim(); } @@ -632,7 +650,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - final Contact contact = conversation == null ? null :conversation.getContact(); + final Contact contact = conversation == null ? null : conversation.getContact(); if (contact != null) { activity.xmppConnectionService.createContact(contact); activity.switchToContactDetails(contact); @@ -655,7 +673,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT); intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString()); intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString()); - intent.putExtra("mode",VerifyOTRActivity.MODE_ANSWER_QUESTION); + intent.putExtra("mode", VerifyOTRActivity.MODE_ANSWER_QUESTION); startActivity(intent); } }; @@ -665,11 +683,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final Contact contact = conversation.getContact(); final int mode = conversation.getMode(); if (conversation.isBlocked()) { - showSnackbar(R.string.contact_blocked, R.string.unblock,this.mUnblockClickListener); + showSnackbar(R.string.contact_blocked, R.string.unblock, this.mUnblockClickListener); } else if (!contact.showInRoster() && contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - showSnackbar(R.string.contact_added_you, R.string.add_back,this.mAddBackClickListener); + showSnackbar(R.string.contact_added_you, R.string.add_back, this.mAddBackClickListener); } else if (mode == Conversation.MODE_MULTI - &&!conversation.getMucOptions().online() + && !conversation.getMucOptions().online() && account.getStatus() == Account.State.ONLINE) { switch (conversation.getMucOptions().getError()) { case MucOptions.ERROR_NICK_IN_USE: @@ -693,18 +711,18 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa default: break; } - } else if (askForPassphraseIntent != null ) { - showSnackbar(R.string.openpgp_messages_found,R.string.decrypt, clickToDecryptListener); + } else if (askForPassphraseIntent != null) { + showSnackbar(R.string.openpgp_messages_found, R.string.decrypt, clickToDecryptListener); } else if (mode == Conversation.MODE_SINGLE && conversation.smpRequested()) { - showSnackbar(R.string.smp_requested, R.string.verify,this.mAnswerSmpClickListener); + showSnackbar(R.string.smp_requested, R.string.verify, this.mAnswerSmpClickListener); } else if (mode == Conversation.MODE_SINGLE - &&conversation.hasValidOtrSession() + && conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!conversation.isOtrFingerprintVerified())) { showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify); } else if (conversation.isMuted()) { - showSnackbar(R.string.notifications_disabled, R.string.enable,this.mUnmuteClickListener); + showSnackbar(R.string.notifications_disabled, R.string.enable, this.mUnmuteClickListener); } else { hideSnackbar(); } @@ -722,12 +740,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP && (message.getStatus() == Message.STATUS_RECEIVED || message - .getStatus() >= Message.STATUS_SEND) + .getStatus() >= Message.STATUS_SEND) && message.getDownloadable() == null) { if (!mEncryptedMessages.contains(message)) { mEncryptedMessages.add(message); } - } + } } decryptNext(); updateStatusMessages(); @@ -790,53 +808,108 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateChatMsgHint(); } - public void updateSendButton() { - Conversation c = this.conversation; - if (activity.useSendButtonToIndicateStatus() && c != null - && c.getAccount().getStatus() == Account.State.ONLINE) { - if (c.getMode() == Conversation.MODE_SINGLE) { - switch (c.getContact().getMostAvailableStatus()) { + enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE} + + private int getSendButtonImageResource(SendButtonAction action, int status) { + switch (action) { + case TEXT: + switch (status) { case Presences.CHAT: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; case Presences.ONLINE: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; + return R.drawable.ic_send_text_online; case Presences.AWAY: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; + return R.drawable.ic_send_text_away; case Presences.XA: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; case Presences.DND: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_dnd); + return R.drawable.ic_send_text_dnd; + default: + return R.drawable.ic_send_text_offline; + } + case TAKE_PHOTO: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_photo_online; + case Presences.AWAY: + return R.drawable.ic_send_photo_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_photo_dnd; + default: + return R.drawable.ic_send_photo_offline; + } + case RECORD_VOICE: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_voice_online; + case Presences.AWAY: + return R.drawable.ic_send_voice_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_voice_dnd; + default: + return R.drawable.ic_send_voice_offline; + } + case SEND_LOCATION: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_location_online; + case Presences.AWAY: + return R.drawable.ic_send_location_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_location_dnd; + default: + return R.drawable.ic_send_location_offline; + } + } + return R.drawable.ic_send_text_offline; + } + + public void updateSendButton() { + final Conversation c = this.conversation; + final SendButtonAction action; + final int status; + if (c.getMode() == Conversation.MODE_MULTI) { + action = SendButtonAction.TEXT; + } else { + if (this.mEditMessage == null || this.mEditMessage.getText().length() == 0) { + String setting = activity.getPreferences().getString("quick_action","recent"); + if (setting.equals("recent")) { + setting = activity.getPreferences().getString("recently_used_quick_action","text"); + } + switch (setting) { + case "photo": + action = SendButtonAction.TAKE_PHOTO; + break; + case "location": + action = SendButtonAction.SEND_LOCATION; + break; + case "voice": + action = SendButtonAction.RECORD_VOICE; break; default: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + action = SendButtonAction.TEXT; break; } - } else if (c.getMode() == Conversation.MODE_MULTI) { - if (c.getMucOptions().online()) { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - } } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + action = SendButtonAction.TEXT; + } + } + if (activity.useSendButtonToIndicateStatus() && c != null + && c.getAccount().getStatus() == Account.State.ONLINE) { + if (c.getMode() == Conversation.MODE_SINGLE) { + status = c.getContact().getMostAvailableStatus(); + } else { + status = c.getMucOptions().online() ? Presences.ONLINE : Presences.OFFLINE; } } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + status = Presences.OFFLINE; } + this.mSendButton.setTag(action); + this.mSendButton.setImageResource(getSendButtonImageResource(action, status)); } protected void updateStatusMessages() { @@ -865,7 +938,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } protected void showSnackbar(final int message, final int action, - final OnClickListener clickListener) { + final OnClickListener clickListener) { snackbar.setVisibility(View.VISIBLE); snackbar.setOnClickListener(null); snackbarMessage.setText(message); @@ -897,7 +970,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void userInputRequried(PendingIntent pi, - Contact contact) { + Contact contact) { activity.runIntent( pi, ConversationActivity.REQUEST_ENCRYPT_MESSAGE); @@ -921,11 +994,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(DialogInterface dialog, - int which) { + int which) { conversation - .setNextEncryption(Message.ENCRYPTION_NONE); + .setNextEncryption(Message.ENCRYPTION_NONE); xmppService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.sendMessage(message); messageSent(); @@ -936,9 +1009,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMucOptions().pgpKeysInUse()) { if (!conversation.getMucOptions().everybodyHasKeys()) { Toast warning = Toast - .makeText(getActivity(), - R.string.missing_public_keys, - Toast.LENGTH_LONG); + .makeText(getActivity(), + R.string.missing_public_keys, + Toast.LENGTH_LONG); warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0); warning.show(); } @@ -950,12 +1023,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(DialogInterface dialog, - int which) { + int which) { conversation - .setNextEncryption(Message.ENCRYPTION_NONE); + .setNextEncryption(Message.ENCRYPTION_NONE); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); xmppService.sendMessage(message); messageSent(); } @@ -968,7 +1041,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } public void showNoPGPKeyDialog(boolean plural, - DialogInterface.OnClickListener listener) { + DialogInterface.OnClickListener listener) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setIconAttribute(android.R.attr.alertDialogIcon); if (plural) { @@ -1026,6 +1099,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (status == Account.State.ONLINE && conversation.setOutgoingChatState(ChatState.COMPOSING)) { activity.xmppConnectionService.sendChatState(conversation); } + updateSendButton(); } @Override @@ -1042,6 +1116,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (status == Account.State.ONLINE && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { activity.xmppConnectionService.sendChatState(conversation); } + updateSendButton(); } } diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_away.png b/src/main/res/drawable-hdpi/ic_action_send_now_away.png deleted file mode 100644 index 505cbe63..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a376524d..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_offline.png b/src/main/res/drawable-hdpi/ic_action_send_now_offline.png deleted file mode 100644 index d4d2d510..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_online.png b/src/main/res/drawable-hdpi/ic_action_send_now_online.png deleted file mode 100644 index 48676f7b..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_launcher.png b/src/main/res/drawable-hdpi/ic_launcher.png index bffc1c65..25fc8591 100644 Binary files a/src/main/res/drawable-hdpi/ic_launcher.png and b/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-hdpi/ic_notification.png b/src/main/res/drawable-hdpi/ic_notification.png index c466a7b1..31c0ee1a 100644 Binary files a/src/main/res/drawable-hdpi/ic_notification.png and b/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/src/main/res/drawable-hdpi/ic_received_indicator.png b/src/main/res/drawable-hdpi/ic_received_indicator.png index b1e3f274..4d2eab56 100644 Binary files a/src/main/res/drawable-hdpi/ic_received_indicator.png and b/src/main/res/drawable-hdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_away.png b/src/main/res/drawable-hdpi/ic_send_location_away.png new file mode 100644 index 00000000..d139818b Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_dnd.png b/src/main/res/drawable-hdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..3bcbe18a Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_offline.png b/src/main/res/drawable-hdpi/ic_send_location_offline.png new file mode 100644 index 00000000..4aec18af Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_online.png b/src/main/res/drawable-hdpi/ic_send_location_online.png new file mode 100644 index 00000000..19ddc51e Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_away.png b/src/main/res/drawable-hdpi/ic_send_photo_away.png new file mode 100644 index 00000000..f6beb23c Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..2eb85679 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_offline.png b/src/main/res/drawable-hdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..046f989b Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_online.png b/src/main/res/drawable-hdpi/ic_send_photo_online.png new file mode 100644 index 00000000..3fd20d10 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_away.png b/src/main/res/drawable-hdpi/ic_send_text_away.png new file mode 100644 index 00000000..d9ef99c5 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_dnd.png b/src/main/res/drawable-hdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..706b6505 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_offline.png b/src/main/res/drawable-hdpi/ic_send_text_offline.png new file mode 100644 index 00000000..0f23fdbb Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_online.png b/src/main/res/drawable-hdpi/ic_send_text_online.png new file mode 100644 index 00000000..305f1ec2 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_away.png b/src/main/res/drawable-hdpi/ic_send_voice_away.png new file mode 100644 index 00000000..e87d9751 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..50184ee8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_offline.png b/src/main/res/drawable-hdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..68ce48b8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_online.png b/src/main/res/drawable-hdpi/ic_send_voice_online.png new file mode 100644 index 00000000..bfd7dfa7 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_away.png b/src/main/res/drawable-mdpi/ic_action_send_now_away.png deleted file mode 100644 index 0fdca901..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png deleted file mode 100644 index c0aef36c..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_offline.png b/src/main/res/drawable-mdpi/ic_action_send_now_offline.png deleted file mode 100644 index 7723f4aa..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_online.png b/src/main/res/drawable-mdpi/ic_action_send_now_online.png deleted file mode 100644 index 39d00ee4..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_launcher.png b/src/main/res/drawable-mdpi/ic_launcher.png index 063ee15d..733e9615 100644 Binary files a/src/main/res/drawable-mdpi/ic_launcher.png and b/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-mdpi/ic_notification.png b/src/main/res/drawable-mdpi/ic_notification.png index fa35b7c1..aafc54f5 100644 Binary files a/src/main/res/drawable-mdpi/ic_notification.png and b/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/src/main/res/drawable-mdpi/ic_received_indicator.png b/src/main/res/drawable-mdpi/ic_received_indicator.png index 88ff1efb..2ba92b69 100644 Binary files a/src/main/res/drawable-mdpi/ic_received_indicator.png and b/src/main/res/drawable-mdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_away.png b/src/main/res/drawable-mdpi/ic_send_location_away.png new file mode 100644 index 00000000..821e80d2 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_dnd.png b/src/main/res/drawable-mdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..92e68ee3 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_offline.png b/src/main/res/drawable-mdpi/ic_send_location_offline.png new file mode 100644 index 00000000..ff11a080 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_online.png b/src/main/res/drawable-mdpi/ic_send_location_online.png new file mode 100644 index 00000000..a0eb4018 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_away.png b/src/main/res/drawable-mdpi/ic_send_photo_away.png new file mode 100644 index 00000000..d9c1f266 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..7b6700d6 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_offline.png b/src/main/res/drawable-mdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..f3e6e1fa Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_online.png b/src/main/res/drawable-mdpi/ic_send_photo_online.png new file mode 100644 index 00000000..0aaab38d Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_away.png b/src/main/res/drawable-mdpi/ic_send_text_away.png new file mode 100644 index 00000000..ddd983b5 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_dnd.png b/src/main/res/drawable-mdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..92df9d3d Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_offline.png b/src/main/res/drawable-mdpi/ic_send_text_offline.png new file mode 100644 index 00000000..72b9da27 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_online.png b/src/main/res/drawable-mdpi/ic_send_text_online.png new file mode 100644 index 00000000..86d1e330 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_away.png b/src/main/res/drawable-mdpi/ic_send_voice_away.png new file mode 100644 index 00000000..943f690f Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..ef25b1c4 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_offline.png b/src/main/res/drawable-mdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..e6b2355f Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_online.png b/src/main/res/drawable-mdpi/ic_send_voice_online.png new file mode 100644 index 00000000..bd0e1f87 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_away.png b/src/main/res/drawable-xhdpi/ic_action_send_now_away.png deleted file mode 100644 index bb999d85..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a0bf5561..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png b/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 6da9ff7b..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_online.png b/src/main/res/drawable-xhdpi/ic_action_send_now_online.png deleted file mode 100644 index 348ba657..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_launcher.png b/src/main/res/drawable-xhdpi/ic_launcher.png index fd9937f1..c9e48859 100644 Binary files a/src/main/res/drawable-xhdpi/ic_launcher.png and b/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xhdpi/ic_notification.png b/src/main/res/drawable-xhdpi/ic_notification.png index 43daff65..042d2cda 100644 Binary files a/src/main/res/drawable-xhdpi/ic_notification.png and b/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xhdpi/ic_received_indicator.png b/src/main/res/drawable-xhdpi/ic_received_indicator.png index 2c871933..cf7c2bb8 100644 Binary files a/src/main/res/drawable-xhdpi/ic_received_indicator.png and b/src/main/res/drawable-xhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_away.png b/src/main/res/drawable-xhdpi/ic_send_location_away.png new file mode 100644 index 00000000..0a5f3d54 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..90ce346c Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_offline.png b/src/main/res/drawable-xhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..114ce01b Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_online.png b/src/main/res/drawable-xhdpi/ic_send_location_online.png new file mode 100644 index 00000000..17204eea Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_away.png b/src/main/res/drawable-xhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..7ac674ea Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..2c37db74 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..6ef1e16a Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_online.png b/src/main/res/drawable-xhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..f585ef98 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_away.png b/src/main/res/drawable-xhdpi/ic_send_text_away.png new file mode 100644 index 00000000..41f223f6 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..0a749f8d Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_offline.png b/src/main/res/drawable-xhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..d0a98e5d Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_online.png b/src/main/res/drawable-xhdpi/ic_send_text_online.png new file mode 100644 index 00000000..91d240d2 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_away.png b/src/main/res/drawable-xhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..34f8ea86 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..cea4212a Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..fc4cff1f Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_online.png b/src/main/res/drawable-xhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..d2f03dd5 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png deleted file mode 100644 index 12ec4d33..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index 7719f81a..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 18895813..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png deleted file mode 100644 index 29bde36e..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_launcher.png b/src/main/res/drawable-xxhdpi/ic_launcher.png index 0e06656f..e69b9c8d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_launcher.png and b/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_notification.png b/src/main/res/drawable-xxhdpi/ic_notification.png index c2ee5dec..42c62d32 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_notification.png and b/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxhdpi/ic_received_indicator.png index 039a9ef9..5d1c9b87 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_received_indicator.png and b/src/main/res/drawable-xxhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_away.png b/src/main/res/drawable-xxhdpi/ic_send_location_away.png new file mode 100644 index 00000000..4fb370ff Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..ea3d1502 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_offline.png b/src/main/res/drawable-xxhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..b4317aae Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_online.png b/src/main/res/drawable-xxhdpi/ic_send_location_online.png new file mode 100644 index 00000000..10dfed81 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_away.png b/src/main/res/drawable-xxhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..78eea39e Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..09c11a81 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..6b41c3bd Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_online.png b/src/main/res/drawable-xxhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..1c8992c5 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_away.png b/src/main/res/drawable-xxhdpi/ic_send_text_away.png new file mode 100644 index 00000000..2b2b0793 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..0d7e7053 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_offline.png b/src/main/res/drawable-xxhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..6bd9c414 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_online.png b/src/main/res/drawable-xxhdpi/ic_send_text_online.png new file mode 100644 index 00000000..cb6a2dba Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_away.png b/src/main/res/drawable-xxhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..b8b9e807 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..a5151331 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..3d58f699 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_online.png b/src/main/res/drawable-xxhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..600371eb Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_launcher.png b/src/main/res/drawable-xxxhdpi/ic_launcher.png index b6dcb0b9..668504df 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_launcher.png and b/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_notification.png b/src/main/res/drawable-xxxhdpi/ic_notification.png index ee2f3a43..c3439f1a 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_notification.png and b/src/main/res/drawable-xxxhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxxhdpi/ic_received_indicator.png index 86db9890..f35c8b44 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_received_indicator.png and b/src/main/res/drawable-xxxhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_away.png b/src/main/res/drawable-xxxhdpi/ic_send_location_away.png new file mode 100644 index 00000000..0fab2554 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..08e2b39b Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..2af75cde Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_online.png b/src/main/res/drawable-xxxhdpi/ic_send_location_online.png new file mode 100644 index 00000000..2e54ef89 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..ba171ce1 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..fccb32dc Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..e94e930d Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..1bf680eb Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_away.png b/src/main/res/drawable-xxxhdpi/ic_send_text_away.png new file mode 100644 index 00000000..afcfa89d Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..929a33a4 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..b9122e45 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_online.png b/src/main/res/drawable-xxxhdpi/ic_send_text_online.png new file mode 100644 index 00000000..abec2e0b Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..de1375e2 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..8ac667be Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..eec3d8f2 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..fcdfcb43 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml index f9aae10a..5aa7dffa 100644 --- a/src/main/res/layout/fragment_conversation.xml +++ b/src/main/res/layout/fragment_conversation.xml @@ -57,7 +57,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:src="@drawable/ic_action_send_now_offline" /> + android:src="@drawable/ic_send_text_offline" /> -1 + + @string/none + @string/recently_used + @string/attach_take_picture + @string/attach_record_voice + @string/send_location + + + + none + recent + photo + voice + location + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index cc7727d2..4631bd60 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1,397 +1,397 @@ - Conversations - Settings - New conversation - Manage accounts - End this conversation - Contact details - Conference details - Secure conversation - Add account - Edit name - Add to phone book - Delete from roster - Block contact - Unblock contact - Block domain - Unblock domain - Manage Accounts - Settings - Conference Details - Contact Details - Share with Conversation - Start Conversation - Choose contact - Block list - just now - 1 min ago - %d mins ago - unread Conversations - sending… - Decrypting message. Please wait… - Nickname is already in use - Admin - Owner - Moderator - Participant - Visitor - Would you like to remove %s from your roster? The conversation associated with this contact will not be removed. - Would you like to block %s from sending you messages? - Would you like to unblock %s and allow them to send you messages? - Block all contacts from %s? - Unblock all contacts from %s? - Contact blocked - Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed. - Register new account on server - Change password on server - Share with… - Start Conversation - Invite Contact - Contacts - Cancel - Set - Add - Edit - Delete - Block - Unblock - Save - OK - Conversations has crashed - By sending in stack traces you are helping the ongoing development of Conversations\nWarning: This will use your XMPP account to send the stack trace to the developer. - Send now - Never ask again - Unable to connect to account - Unable to connect to multiple accounts - Touch here to manage your accounts - Attach file - The contact is not in your roster. Would you like to add it? - Add contact - delivery failed - rejected - Preparing image for transmission - Clear history - Clear Conversation History - Do you want to delete all messages within this Conversation?\n\nWarning: This will not influence messages stored on other devices or servers. - Delete messages - End this conversations afterwards - Choose presence to contact - Send plain text message - Send OTR encrypted message - Send OpenPGP encrypted message - Your nickname has been changed - Download Image - Send unencrypted - Decryption failed. Maybe you don’t have the proper private key. - OpenKeychain - Conversations utilizes a third party app called OpenKeychain to encrypt and decrypt messages and to manage your public keys.\n\nOpenKeychain is licensed under GPLv3 and available on F-Droid and Google Play.\n\n(Please restart Conversations afterwards.) - Restart - Install - offering… - waiting… - No OpenPGP Key found - Conversations is unable to encrypt your messages because your contact is not announcing his or hers public key.\n\nPlease ask your contact to setup OpenPGP. - No OpenPGP Keys found - Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\nPlease ask your contacts to setup OpenPGP. - Encrypted message received. Touch to view and decrypt. - General - XMPP resource - The name this client identifies itself with - Accept files - Automatically accept files smaller than… - Notification Settings - Notifications - Notify when a new message arrives - Vibrate - Also vibrate when a new message arrives - Sound - Play ringtone with notification - Conference notifications - Always notify when a new conference message arrives instead of only when highlighted - Notification grace period - Disable notifications for a short time after a carbon copy was received - Advanced Options - Never send crash reports - By sending in stack traces you are helping the ongoing development of Conversations - Confirm Messages - Let your contact know when you have received and read a message - UI Options - OpenKeychain reported an error - I/O Error decrypting file - Accept - An error has occurred - Grant presence updates - Preemptively grant and ask for presence subscription for contacts you created - Subscriptions - Your account - Keys - Send presence updates - Receive presence updates - Ask for presence updates - Choose picture - Take picture - Preemptively grant subscription request - The file you selected is not an image - Error while converting the image file - File not found - General I/O error. Maybe you ran out of storage space? - The app you used to select this image did not provide us with enough permissions to read the file.\n\nUse a different file manager to choose an image - Unknown - Temporarily disabled - Online - Connecting\u2026 - Offline - Unauthorized - Server not found - No connectivity - Registration failed - Username already in use - Registration completed - Server does not support registration - Security error - Incompatible server - Plain text - OTR - OpenPGP - Edit account - Delete account - Temporarily disable - Publish avatar - Publish OpenPGP public key - Enable account - Are you sure? - If you delete your account your entire conversation history will be lost - Record voice - Jabber ID - Password - username@example.com - Confirm password - Password - Confirm password - Passwords do not match - This is not a valid Jabber ID - Out of memory. Image is too large - Do you want to add %s to your phones contact list? - online - free to chat - away - extended away - do not disturb - offline - Conference - Other Members - Server info - XEP-0313: MAM - XEP-0280: Message Carbons - XEP-0352: Client State Indication - XEP-0191: Blocking Command - XEP-0237: Roster Versioning - XEP-0198: Stream Management - XEP-0163: PEP (Avatars) - available - unavailable - Missing public key announcements - last seen just now - last seen 1 minute ago - last seen %d minutes ago - last seen 1 hour ago - last seen %d hours ago - last seen 1 day ago - last seen %d days ago - never seen - Encrypted message. Please install OpenKeychain to decrypt. - Unknown OTR fingerprint - OpenPGP encrypted messages found - Reception failed - Your fingerprint - OTR fingerprint - Verify - Decrypt - Conferences - Search - Create Contact - Join Conference - Delete Contact - View contact details - Block contact - Unblock contact - Create - The contact already exists - Join - Conference address - room@conference.example.com - Save as bookmark - Delete bookmark - This bookmark already exists - You - Edit conference subject - Conference not found - Leave - Contact added you to contact list - Add back - %s has read up to this point - Publish - Touch avatar to select picture from gallery - Please note: Everyone subscribed to your presence updates will be allowed to see this picture. - Publishing… - The server rejected your publication - Something went wrong while converting your picture - Could not save avatar to disk - (Or long press to bring back default) - Your server does not support the publication of avatars - whispered - to %s - Send private message to %s - Connect - This account already exists - Next - Current session established - Additional Information - Skip - Disable notifications - Disable notifications for this conversation - Notifications are disabled - Enable - Conference requires password - Enter password - Missing presence updates from contact - Please request presence updates from your contact first.\n\nThis will be used to determine what client(s) your contact is using. - Request now - Delete Fingerprint - Are you sure you would like to delete this fingerprint? - Ignore - Warning: Sending this without mutual presence updates could cause unexpected problems.\n\nGo to contact details to verify your presence subscriptions. - Encryption settings - Force end-to-end encryption - Always send messages encrypted (except for conferences) - Don’t save encrypted messages - Warning: This could lead to message loss - Expert options - Please be careful with these - About Conversations - Build and licensing information - - Conversations • the very last word in instant messaging. - \n\nCopyright © 2014 Daniel Gultsch - \n\nThis program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - \n\nThis program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - \n\nYou should have received a copy of the GNU General Public License - along with this program. If not, see https://www.gnu.org/licenses - \n\nDownload the full source code at https://github.com/siacs/Conversations - \n\n\nLibraries - \n\nhttps://www.bouncycastle.org\n(The MIT License (MIT)) - \n\nhttps://www.gnu.org/software/libidn\n(Apache License, Version 2.0) - \n\nhttps://github.com/ge0rg/MemorizingTrustManager\n(The MIT License (MIT)) - \n\nhttps://github.com/rtreffer/minidns\n(WTFPL) - \n\nhttps://github.com/open-keychain/openkeychain-api-lib\n(Apache License, Version 2.0) - \n\nhttps://github.com/jitsi/otr4j\n(LGPL-3.0) - \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) - \n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0) - \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) - \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0) - - Quiet Hours - Start time - End time - Enable quiet hours - Notifications will be silenced during quiet hours - Increase font size - Use larger font sizes across the entire app - Send button indicates status - Request message receipts - Received messages will be marked with a green tick if supported - Colorize send button to indicate contact status - Other - Conference name - Use room’s subject instead of JID to identify conferences - OTR fingerprint copied to clipboard! - You are banned from this conference - This conference is members only - You have been kicked from this conference - using account %s - Checking image on HTTP host - The image file has been deleted - You are not connected. Try again later - Check image file size - Message options - Copy text - Copy original URL - Send again - Image URL - Message text - URL copied to clipboard - Message copied to clipboard - Image transmission failed - Scan QR code - Show QR code - Show block list - Account details - Verify OTR - Remote Fingerprint - scan - (or touch phones) - Socialist Millionaire Protocol - Hint or Question - Shared Secret - Confirm - In progress - Respond - Failed - Secrets do not match - Try again - Finish - Verified! - Contact requested SMP verification - No valid OTR session has been found! - Conversations - Keep service in foreground - Prevents the operating system from killing your connection - Choose file - Receiving %1$s (%2$d%% completed) - Download %s - file - Open %s - sending (%1$d%% completed) - Preparing file for transmission - %s offered for download - Cancel transmission - file transmission failed - The file has been deleted - No application found to open file - Could not verify fingerprint - Manually verify - Are you sure that you want to verify your contacts OTR fingerprint? - Show dynamic tags - Display read-only tags underneath contacts - Enable notifications - Create conference with… - No conference server found - Conference creation failed! - Conference created! - Secret accepted! - Reset - Account avatar - Copy OTR fingerprint to clipboard - Fetching history from server - No more history on server - Updating… - Password changed! - Could not change password - Send a message to start an encrypted chat - Ask question - If you and your contact have a secret in common that no one else knows (like an inside joke or simply what you had for lunch the last time you met) you can use that secret to verify each other’s fingerprints.\n\nYou provide a hint or a question for your contact who will respond with a case-sensitive answer. - Your contact would like to verify your fingerprint by challenging you with a shared secret. Your contact provided the following hint or question for that secret. - Your hint should not be empty - Your shared secret can not be empty - Carefully compare the fingerprint shown below with the fingerprint of your contact.\nYou can use any trusted form of communication like an encrypted e-mail or a telephone call to exchange those. + Conversations + Settings + New conversation + Manage accounts + End this conversation + Contact details + Conference details + Secure conversation + Add account + Edit name + Add to phone book + Delete from roster + Block contact + Unblock contact + Block domain + Unblock domain + Manage Accounts + Settings + Conference Details + Contact Details + Share with Conversation + Start Conversation + Choose contact + Block list + just now + 1 min ago + %d mins ago + unread Conversations + sending… + Decrypting message. Please wait… + Nickname is already in use + Admin + Owner + Moderator + Participant + Visitor + Would you like to remove %s from your roster? The conversation associated with this contact will not be removed. + Would you like to block %s from sending you messages? + Would you like to unblock %s and allow them to send you messages? + Block all contacts from %s? + Unblock all contacts from %s? + Contact blocked + Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed. + Register new account on server + Change password on server + Share with… + Start Conversation + Invite Contact + Contacts + Cancel + Set + Add + Edit + Delete + Block + Unblock + Save + OK + Conversations has crashed + By sending in stack traces you are helping the ongoing development of Conversations\nWarning: This will use your XMPP account to send the stack trace to the developer. + Send now + Never ask again + Unable to connect to account + Unable to connect to multiple accounts + Touch here to manage your accounts + Attach file + The contact is not in your roster. Would you like to add it? + Add contact + delivery failed + rejected + Preparing image for transmission + Clear history + Clear Conversation History + Do you want to delete all messages within this Conversation?\n\nWarning: This will not influence messages stored on other devices or servers. + Delete messages + End this conversations afterwards + Choose presence to contact + Send plain text message + Send OTR encrypted message + Send OpenPGP encrypted message + Your nickname has been changed + Download Image + Send unencrypted + Decryption failed. Maybe you don’t have the proper private key. + OpenKeychain + Conversations utilizes a third party app called OpenKeychain to encrypt and decrypt messages and to manage your public keys.\n\nOpenKeychain is licensed under GPLv3 and available on F-Droid and Google Play.\n\n(Please restart Conversations afterwards.) + Restart + Install + offering… + waiting… + No OpenPGP Key found + Conversations is unable to encrypt your messages because your contact is not announcing his or hers public key.\n\nPlease ask your contact to setup OpenPGP. + No OpenPGP Keys found + Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\nPlease ask your contacts to setup OpenPGP. + Encrypted message received. Touch to view and decrypt. + General + XMPP resource + The name this client identifies itself with + Accept files + Automatically accept files smaller than… + Notification Settings + Notifications + Notify when a new message arrives + Vibrate + Also vibrate when a new message arrives + Sound + Play ringtone with notification + Conference notifications + Always notify when a new conference message arrives instead of only when highlighted + Notification grace period + Disable notifications for a short time after a carbon copy was received + Advanced Options + Never send crash reports + By sending in stack traces you are helping the ongoing development of Conversations + Confirm Messages + Let your contact know when you have received and read a message + UI Options + OpenKeychain reported an error + I/O Error decrypting file + Accept + An error has occurred + Grant presence updates + Preemptively grant and ask for presence subscription for contacts you created + Subscriptions + Your account + Keys + Send presence updates + Receive presence updates + Ask for presence updates + Choose picture + Take picture + Preemptively grant subscription request + The file you selected is not an image + Error while converting the image file + File not found + General I/O error. Maybe you ran out of storage space? + The app you used to select this image did not provide us with enough permissions to read the file.\n\nUse a different file manager to choose an image + Unknown + Temporarily disabled + Online + Connecting\u2026 + Offline + Unauthorized + Server not found + No connectivity + Registration failed + Username already in use + Registration completed + Server does not support registration + Security error + Incompatible server + Plain text + OTR + OpenPGP + Edit account + Delete account + Temporarily disable + Publish avatar + Publish OpenPGP public key + Enable account + Are you sure? + If you delete your account your entire conversation history will be lost + Record voice + Jabber ID + Password + username@example.com + Confirm password + Password + Confirm password + Passwords do not match + This is not a valid Jabber ID + Out of memory. Image is too large + Do you want to add %s to your phones contact list? + online + free to chat + away + extended away + do not disturb + offline + Conference + Other Members + Server info + XEP-0313: MAM + XEP-0280: Message Carbons + XEP-0352: Client State Indication + XEP-0191: Blocking Command + XEP-0237: Roster Versioning + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) + available + unavailable + Missing public key announcements + last seen just now + last seen 1 minute ago + last seen %d minutes ago + last seen 1 hour ago + last seen %d hours ago + last seen 1 day ago + last seen %d days ago + never seen + Encrypted message. Please install OpenKeychain to decrypt. + Unknown OTR fingerprint + OpenPGP encrypted messages found + Reception failed + Your fingerprint + OTR fingerprint + Verify + Decrypt + Conferences + Search + Create Contact + Join Conference + Delete Contact + View contact details + Block contact + Unblock contact + Create + The contact already exists + Join + Conference address + room@conference.example.com + Save as bookmark + Delete bookmark + This bookmark already exists + You + Edit conference subject + Conference not found + Leave + Contact added you to contact list + Add back + %s has read up to this point + Publish + Touch avatar to select picture from gallery + Please note: Everyone subscribed to your presence updates will be allowed to see this picture. + Publishing… + The server rejected your publication + Something went wrong while converting your picture + Could not save avatar to disk + (Or long press to bring back default) + Your server does not support the publication of avatars + whispered + to %s + Send private message to %s + Connect + This account already exists + Next + Current session established + Additional Information + Skip + Disable notifications + Disable notifications for this conversation + Notifications are disabled + Enable + Conference requires password + Enter password + Missing presence updates from contact + Please request presence updates from your contact first.\n\nThis will be used to determine what client(s) your contact is using. + Request now + Delete Fingerprint + Are you sure you would like to delete this fingerprint? + Ignore + Warning: Sending this without mutual presence updates could cause unexpected problems.\n\nGo to contact details to verify your presence subscriptions. + Encryption settings + Force end-to-end encryption + Always send messages encrypted (except for conferences) + Don’t save encrypted messages + Warning: This could lead to message loss + Expert options + Please be careful with these + About Conversations + Build and licensing information + + Conversations • the very last word in instant messaging. + \n\nCopyright © 2014 Daniel Gultsch + \n\nThis program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + \n\nThis program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + \n\nYou should have received a copy of the GNU General Public License + along with this program. If not, see https://www.gnu.org/licenses + \n\nDownload the full source code at https://github.com/siacs/Conversations + \n\n\nLibraries + \n\nhttps://www.bouncycastle.org\n(The MIT License (MIT)) + \n\nhttps://www.gnu.org/software/libidn\n(Apache License, Version 2.0) + \n\nhttps://github.com/ge0rg/MemorizingTrustManager\n(The MIT License (MIT)) + \n\nhttps://github.com/rtreffer/minidns\n(WTFPL) + \n\nhttps://github.com/open-keychain/openkeychain-api-lib\n(Apache License, Version 2.0) + \n\nhttps://github.com/jitsi/otr4j\n(LGPL-3.0) + \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) + \n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0) + \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) + \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0) + + Quiet Hours + Start time + End time + Enable quiet hours + Notifications will be silenced during quiet hours + Increase font size + Use larger font sizes across the entire app + Send button indicates status + Request message receipts + Received messages will be marked with a green tick if supported + Colorize send button to indicate contact status + Other + Conference name + Use room’s subject instead of JID to identify conferences + OTR fingerprint copied to clipboard! + You are banned from this conference + This conference is members only + You have been kicked from this conference + using account %s + Checking image on HTTP host + The image file has been deleted + You are not connected. Try again later + Check image file size + Message options + Copy text + Copy original URL + Send again + Image URL + Message text + URL copied to clipboard + Message copied to clipboard + Image transmission failed + Scan QR code + Show QR code + Show block list + Account details + Verify OTR + Remote Fingerprint + scan + (or touch phones) + Socialist Millionaire Protocol + Hint or Question + Shared Secret + Confirm + In progress + Respond + Failed + Secrets do not match + Try again + Finish + Verified! + Contact requested SMP verification + No valid OTR session has been found! + Conversations + Keep service in foreground + Prevents the operating system from killing your connection + Choose file + Receiving %1$s (%2$d%% completed) + Download %s + file + Open %s + sending (%1$d%% completed) + Preparing file for transmission + %s offered for download + Cancel transmission + file transmission failed + The file has been deleted + No application found to open file + Could not verify fingerprint + Manually verify + Are you sure that you want to verify your contacts OTR fingerprint? + Show dynamic tags + Display read-only tags underneath contacts + Enable notifications + Create conference with… + No conference server found + Conference creation failed! + Conference created! + Secret accepted! + Reset + Account avatar + Copy OTR fingerprint to clipboard + Fetching history from server + No more history on server + Updating… + Password changed! + Could not change password + Send a message to start an encrypted chat + Ask question + If you and your contact have a secret in common that no one else knows (like an inside joke or simply what you had for lunch the last time you met) you can use that secret to verify each other’s fingerprints.\n\nYou provide a hint or a question for your contact who will respond with a case-sensitive answer. + Your contact would like to verify your fingerprint by challenging you with a shared secret. Your contact provided the following hint or question for that secret. + Your hint should not be empty + Your shared secret can not be empty + Carefully compare the fingerprint shown below with the fingerprint of your contact.\nYou can use any trusted form of communication like an encrypted e-mail or a telephone call to exchange those. Change password Current password New password @@ -442,19 +442,19 @@ Disable foreground service Touch to open Conversations Avatar has been published! - Sending %s - Offering %s - Hide offline - Disable Account - %s is typing... - %s has stopped typing - Typing notifications - Let your contact know when you are writing a new message - Send location - Show location - No application found to display location - Location - Received location + Sending %s + Offering %s + Hide offline + Disable Account + %s is typing... + %s has stopped typing + Typing notifications + Let your contact know when you are writing a new message + Send location + Show location + No application found to display location + Location + Received location Conversation closed Left conference Certificate options @@ -474,4 +474,9 @@ Select %d contact Select %d contacts + Replace send button with quick action + Quick Action + None + Most recently used + Choose quick action diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 417e60a4..5b7d6904 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -105,6 +105,14 @@ android:key="send_button_status" android:summary="@string/pref_use_send_button_to_indicate_status_summary" android:title="@string/pref_use_send_button_to_indicate_status" /> + Date: Sat, 2 May 2015 11:58:19 +0200 Subject: shut up linter. fixed build --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a4062ec3..7b8742c9 100644 --- a/build.gradle +++ b/build.gradle @@ -92,7 +92,7 @@ android { } lintOptions { - disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage' + disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage', 'MissingQuantity' } subprojects { -- cgit v1.2.3 From 48e8e0f1fc1afd8f50e4ac17f235f9f587f637dc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:00:27 +0200 Subject: version bump to 1.4.0-alpha (in development) --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 7b8742c9..610b8818 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 60 - versionName "1.3.0" + versionCode 61 + versionName "1.4.0-alpha" } compileOptions { -- cgit v1.2.3 From c4bfffe6a9027d041cccf610b448cb6c1367c83d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:10:56 +0200 Subject: mark account with incompatible server when no sasl mechansim could be found --- .../siacs/conversations/xmpp/XmppConnection.java | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0b6bb15b..a2b58a14 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -581,26 +581,31 @@ public class XmppConnection implements Runnable { } else if (mechanisms.contains("DIGEST-MD5")) { saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); } - final JSONObject keys = account.getKeys(); - try { - if (keys.has(Account.PINNED_MECHANISM_KEY) && - keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority() ) { - Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + - " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + - ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + - "). Possible downgrade attack?"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); - } - } catch (final JSONException e) { - Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); - } - Log.d(Config.LOGTAG,account.getJid().toString()+": Authenticating with " + saslMechanism.getMechanism()); - auth.setAttribute("mechanism", saslMechanism.getMechanism()); - if (!saslMechanism.getClientFirstMessage().isEmpty()) { - auth.setContent(saslMechanism.getClientFirstMessage()); + if (saslMechanism != null) { + final JSONObject keys = account.getKeys(); + try { + if (keys.has(Account.PINNED_MECHANISM_KEY) && + keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { + Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + + " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + + "). Possible downgrade attack?"); + disconnect(true); + changeStatus(Account.State.SECURITY_ERROR); + } + } catch (final JSONException e) { + Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); + } + Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); + auth.setAttribute("mechanism", saslMechanism.getMechanism()); + if (!saslMechanism.getClientFirstMessage().isEmpty()) { + auth.setContent(saslMechanism.getClientFirstMessage()); + } + tagWriter.writeElement(auth); + } else { + disconnect(true); + changeStatus(Account.State.INCOMPATIBLE_SERVER); } - tagWriter.writeElement(auth); } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { -- cgit v1.2.3 From ecd3634c91bb9c6773f8cbb8d9950b6e935f5c6d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 11:58:19 +0200 Subject: shut up linter. fixed build --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a4062ec3..7b8742c9 100644 --- a/build.gradle +++ b/build.gradle @@ -92,7 +92,7 @@ android { } lintOptions { - disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage' + disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage', 'MissingQuantity' } subprojects { -- cgit v1.2.3 From 9cc8ba320fac565e6779f129ee4658e43aa36bf6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:10:56 +0200 Subject: mark account with incompatible server when no sasl mechansim could be found --- .../siacs/conversations/xmpp/XmppConnection.java | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0b6bb15b..a2b58a14 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -581,26 +581,31 @@ public class XmppConnection implements Runnable { } else if (mechanisms.contains("DIGEST-MD5")) { saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); } - final JSONObject keys = account.getKeys(); - try { - if (keys.has(Account.PINNED_MECHANISM_KEY) && - keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority() ) { - Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + - " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + - ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + - "). Possible downgrade attack?"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); - } - } catch (final JSONException e) { - Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); - } - Log.d(Config.LOGTAG,account.getJid().toString()+": Authenticating with " + saslMechanism.getMechanism()); - auth.setAttribute("mechanism", saslMechanism.getMechanism()); - if (!saslMechanism.getClientFirstMessage().isEmpty()) { - auth.setContent(saslMechanism.getClientFirstMessage()); + if (saslMechanism != null) { + final JSONObject keys = account.getKeys(); + try { + if (keys.has(Account.PINNED_MECHANISM_KEY) && + keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { + Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + + " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + + "). Possible downgrade attack?"); + disconnect(true); + changeStatus(Account.State.SECURITY_ERROR); + } + } catch (final JSONException e) { + Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); + } + Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); + auth.setAttribute("mechanism", saslMechanism.getMechanism()); + if (!saslMechanism.getClientFirstMessage().isEmpty()) { + auth.setContent(saslMechanism.getClientFirstMessage()); + } + tagWriter.writeElement(auth); + } else { + disconnect(true); + changeStatus(Account.State.INCOMPATIBLE_SERVER); } - tagWriter.writeElement(auth); } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { -- cgit v1.2.3 From fbf81f59dbc17951faea945cca979312201d00fe Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:12:44 +0200 Subject: version bump to 1.3.1 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 7b8742c9..afc7bb4b 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 60 - versionName "1.3.0" + versionCode 61 + versionName "1.3.1" } compileOptions { -- cgit v1.2.3 From 43db9cdf4b300183cfd58ad9c7b3ad57ee63ad31 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 3 May 2015 09:30:30 +0200 Subject: turn send button in cancel button while in whisper mode --- art/ic_send_cancel_away.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_dnd.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_offline.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_online.svg | 54 +++++++++++++++++++++ art/render.rb | 4 ++ .../conversations/ui/ConversationFragment.java | 42 +++++++++++----- src/main/res/drawable-hdpi/ic_send_cancel_away.png | Bin 0 -> 1396 bytes src/main/res/drawable-hdpi/ic_send_cancel_dnd.png | Bin 0 -> 1559 bytes .../res/drawable-hdpi/ic_send_cancel_offline.png | Bin 0 -> 1206 bytes .../res/drawable-hdpi/ic_send_cancel_online.png | Bin 0 -> 1531 bytes src/main/res/drawable-mdpi/ic_send_cancel_away.png | Bin 0 -> 901 bytes src/main/res/drawable-mdpi/ic_send_cancel_dnd.png | Bin 0 -> 1040 bytes .../res/drawable-mdpi/ic_send_cancel_offline.png | Bin 0 -> 837 bytes .../res/drawable-mdpi/ic_send_cancel_online.png | Bin 0 -> 1052 bytes .../res/drawable-xhdpi/ic_send_cancel_away.png | Bin 0 -> 1724 bytes src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png | Bin 0 -> 1940 bytes .../res/drawable-xhdpi/ic_send_cancel_offline.png | Bin 0 -> 1519 bytes .../res/drawable-xhdpi/ic_send_cancel_online.png | Bin 0 -> 1978 bytes .../res/drawable-xxhdpi/ic_send_cancel_away.png | Bin 0 -> 2583 bytes .../res/drawable-xxhdpi/ic_send_cancel_dnd.png | Bin 0 -> 2911 bytes .../res/drawable-xxhdpi/ic_send_cancel_offline.png | Bin 0 -> 2290 bytes .../res/drawable-xxhdpi/ic_send_cancel_online.png | Bin 0 -> 2998 bytes .../res/drawable-xxxhdpi/ic_send_cancel_away.png | Bin 0 -> 3377 bytes .../res/drawable-xxxhdpi/ic_send_cancel_dnd.png | Bin 0 -> 3791 bytes .../drawable-xxxhdpi/ic_send_cancel_offline.png | Bin 0 -> 2956 bytes .../res/drawable-xxxhdpi/ic_send_cancel_online.png | Bin 0 -> 3835 bytes 26 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 art/ic_send_cancel_away.svg create mode 100644 art/ic_send_cancel_dnd.svg create mode 100644 art/ic_send_cancel_offline.svg create mode 100644 art/ic_send_cancel_online.svg create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png diff --git a/art/ic_send_cancel_away.svg b/art/ic_send_cancel_away.svg new file mode 100644 index 00000000..1ee9c40f --- /dev/null +++ b/art/ic_send_cancel_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_dnd.svg b/art/ic_send_cancel_dnd.svg new file mode 100644 index 00000000..54e02a91 --- /dev/null +++ b/art/ic_send_cancel_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_offline.svg b/art/ic_send_cancel_offline.svg new file mode 100644 index 00000000..b88ade09 --- /dev/null +++ b/art/ic_send_cancel_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_online.svg b/art/ic_send_cancel_online.svg new file mode 100644 index 00000000..40946af6 --- /dev/null +++ b/art/ic_send_cancel_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 32d06f8f..ad53b1f4 100755 --- a/art/render.rb +++ b/art/render.rb @@ -26,6 +26,10 @@ images = { 'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36], 'ic_send_voice_away.svg' => ['ic_send_voice_away', 36], 'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36], + 'ic_send_cancel_online.svg' => ['ic_send_cancel_online', 36], + 'ic_send_cancel_offline.svg' => ['ic_send_cancel_offline', 36], + 'ic_send_cancel_away.svg' => ['ic_send_cancel_away', 36], + 'ic_send_cancel_dnd.svg' => ['ic_send_cancel_dnd', 36], } images.each do |source, result| resolutions.each do |name, factor| diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 37ae00a3..6b11d310 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -245,6 +245,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa case RECORD_VOICE: activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_RECORD_VOICE); break; + case CANCEL: + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setNextCounterpart(null); + updateChatMsgHint(); + updateSendButton(); + } + break; default: sendMessage(); } @@ -257,8 +264,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - Intent intent = new Intent(getActivity(), - ConferenceDetailsActivity.class); + Intent intent = new Intent(getActivity(), ConferenceDetailsActivity.class); intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); intent.putExtra("uuid", conversation.getUuid()); startActivity(intent); @@ -271,13 +277,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (this.conversation == null) { return; } - if (mEditMessage.getText().length() < 1) { - if (this.conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setNextCounterpart(null); - updateChatMsgHint(); - } - return; - } Message message = new Message(conversation, mEditMessage.getText() .toString(), conversation.getNextEncryption(activity .forceEncryption())); @@ -558,6 +557,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa this.mEditMessage.setText(""); this.conversation.setNextCounterpart(counterpart); updateChatMsgHint(); + updateSendButton(); } protected void highlightInConference(String nick) { @@ -808,7 +808,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateChatMsgHint(); } - enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE} + enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE, CANCEL} private int getSendButtonImageResource(SendButtonAction action, int status) { switch (action) { @@ -864,6 +864,19 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa default: return R.drawable.ic_send_location_offline; } + case CANCEL: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_cancel_online; + case Presences.AWAY: + return R.drawable.ic_send_cancel_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_cancel_dnd; + default: + return R.drawable.ic_send_cancel_offline; + } } return R.drawable.ic_send_text_offline; } @@ -872,10 +885,15 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final Conversation c = this.conversation; final SendButtonAction action; final int status; + final boolean empty = this.mEditMessage == null || this.mEditMessage.getText().length() == 0; if (c.getMode() == Conversation.MODE_MULTI) { - action = SendButtonAction.TEXT; + if (empty && c.getNextCounterpart() != null) { + action = SendButtonAction.CANCEL; + } else { + action = SendButtonAction.TEXT; + } } else { - if (this.mEditMessage == null || this.mEditMessage.getText().length() == 0) { + if (empty) { String setting = activity.getPreferences().getString("quick_action","recent"); if (setting.equals("recent")) { setting = activity.getPreferences().getString("recently_used_quick_action","text"); diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_away.png b/src/main/res/drawable-hdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..9525c040 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..cbfd8e76 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_offline.png b/src/main/res/drawable-hdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..2cb4f4f3 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_online.png b/src/main/res/drawable-hdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..cb3bc3b5 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_away.png b/src/main/res/drawable-mdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..bbc86b45 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..e4fa38a3 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_offline.png b/src/main/res/drawable-mdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..604dfefa Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_online.png b/src/main/res/drawable-mdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..1b0d1811 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..44b5f096 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..276ad024 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..53a9ac90 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..23a5f263 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..07113f02 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..93fbc44d Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..10412fab Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..6fa18239 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..a9340a88 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..02ab1d0f Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..abd3af2c Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..80be8edf Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png differ -- cgit v1.2.3 From d15da64c5df63584d55a994d568345059a1f1c20 Mon Sep 17 00:00:00 2001 From: Alexander Groshev Date: Sun, 3 May 2015 20:53:27 +0300 Subject: Fix typos in URL to the project --- src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java index 526005f3..c40c6d05 100644 --- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java @@ -49,7 +49,7 @@ public class PresenceGenerator extends AbstractGenerator { Element cap = packet.addChild("c", "http://jabber.org/protocol/caps"); cap.setAttribute("hash", "sha-1"); - cap.setAttribute("node", "http://conversions.im"); + cap.setAttribute("node", "http://conversations.im"); cap.setAttribute("ver", capHash); } return packet; @@ -61,4 +61,4 @@ public class PresenceGenerator extends AbstractGenerator { packet.setAttribute("type","unavailable"); return packet; } -} \ No newline at end of file +} -- cgit v1.2.3 From 2582ece2105f98a7a20d72d8c8dc70772a48286f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 04:38:12 +0200 Subject: open market if share location plugin isn't installed --- .../eu/siacs/conversations/ui/ConversationActivity.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a76efbc3..349d8ffe 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -409,6 +409,7 @@ public class ConversationActivity extends XmppActivity public void onPresenceSelected() { Intent intent = new Intent(); boolean chooser = false; + String fallbackPackageId = null; switch (attachmentChoice) { case ATTACHMENT_CHOICE_CHOOSE_IMAGE: intent.setAction(Intent.ACTION_GET_CONTENT); @@ -436,6 +437,7 @@ public class ConversationActivity extends XmppActivity break; case ATTACHMENT_CHOICE_LOCATION: intent.setAction("eu.siacs.conversations.location.request"); + fallbackPackageId = "eu.siacs.conversations.sharelocation"; break; } if (intent.resolveActivity(getPackageManager()) != null) { @@ -446,12 +448,25 @@ public class ConversationActivity extends XmppActivity } else { startActivityForResult(intent, attachmentChoice); } + } else if (fallbackPackageId != null) { + startActivity(getInstallApkIntent(fallbackPackageId)); } } }); } } + private Intent getInstallApkIntent(final String packageId) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("market://details?id="+packageId)); + if (intent.resolveActivity(getPackageManager()) != null) { + return intent; + } else { + intent.setData(Uri.parse("http://play.google.com/store/apps/details?id="+packageId)); + return intent; + } + } + public void attachFile(final int attachmentChoice) { switch (attachmentChoice) { case ATTACHMENT_CHOICE_LOCATION: -- cgit v1.2.3 From 32593cff87e913522078bf41ac9c3bdd36e61801 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:07:59 +0200 Subject: updated contributor list in README.md * added BrianBlade to list * linked Pull Requests for each Contributor --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5519e47f..e7221eab 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,13 @@ run your own XMPP server for you and your friends. These XEP's are: (In order of appearance) -* [Rene Treffer](https://github.com/rtreffer) -* [Andreas Straub](https://github.com/strb) -* [Alethea Butler](https://github.com/alethea) -* [M. Dietrich](https://github.com/emdete) -* [betheg](https://github.com/betheg) -* [Sam Whited](https://github.com/SamWhited) +* [Rene Treffer](https://github.com/rtreffer) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Artreffer+is%3Amerged)) +* [Andreas Straub](https://github.com/strb) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Astrb+is%3Amerged)) +* [Alethea Butler](https://github.com/alethea) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Aalethea+is%3Amerged)) +* [M. Dietrich](https://github.com/emdete) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Aemdete+is%3Amerged)) +* [betheg](https://github.com/betheg) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Abetheg+is%3Amerged)) +* [Sam Whited](https://github.com/SamWhited) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3ASamWhited+is%3Amerged)) +* [BrianBlade](https://github.com/BrianBlade) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3ABrianBlade+is%3Amerged)) #### Logo * [Ilia Rostovtsev](https://github.com/qooob) (Progress) -- cgit v1.2.3 From 768f1ef237a0b6d8f1577add3cb17fc2c4dea287 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:40:41 +0200 Subject: update build tools and target api --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 610b8818..b312725e 100644 --- a/build.gradle +++ b/build.gradle @@ -38,8 +38,8 @@ dependencies { } android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" + compileSdkVersion 22 + buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 14 -- cgit v1.2.3 From e388c75452788160501735a965ada9003e2a7dcb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:49:28 +0200 Subject: update travis config --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f147a61..a2959e0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ android: components: - platform-tools - tools + - build-tools-22.0.1 - build-tools-21.1.2 - build-tools-19.1.0 - - android-21 + - android-22 - extra-android-m2repository -- cgit v1.2.3 From 61fd5d669651042c553f9782492d7d2c4035a54f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 09:54:10 +0200 Subject: clean up in attachment chooser code. fixed #1168 --- .../conversations/ui/ConversationActivity.java | 102 ++++++++++----------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 349d8ffe..b11ff002 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -398,61 +398,61 @@ public class ConversationActivity extends XmppActivity } private void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) { - if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) { - getSelectedConversation().setNextCounterpart(null); - Intent intent = new Intent("eu.siacs.conversations.location.request"); - startActivityForResult(intent,attachmentChoice); - } else { - selectPresence(getSelectedConversation(), new OnPresenceSelected() { + final OnPresenceSelected callback = new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - Intent intent = new Intent(); - boolean chooser = false; - String fallbackPackageId = null; - switch (attachmentChoice) { - case ATTACHMENT_CHOICE_CHOOSE_IMAGE: - intent.setAction(Intent.ACTION_GET_CONTENT); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); - } - intent.setType("image/*"); - chooser = true; - break; - case ATTACHMENT_CHOICE_TAKE_PHOTO: - Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri(); - intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); - mPendingImageUris.clear(); - mPendingImageUris.add(uri); - break; - case ATTACHMENT_CHOICE_CHOOSE_FILE: - chooser = true; - intent.setType("*/*"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setAction(Intent.ACTION_GET_CONTENT); - break; - case ATTACHMENT_CHOICE_RECORD_VOICE: - intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); - break; - case ATTACHMENT_CHOICE_LOCATION: - intent.setAction("eu.siacs.conversations.location.request"); - fallbackPackageId = "eu.siacs.conversations.sharelocation"; - break; - } - if (intent.resolveActivity(getPackageManager()) != null) { - if (chooser) { - startActivityForResult( - Intent.createChooser(intent, getString(R.string.perform_action_with)), - attachmentChoice); - } else { - startActivityForResult(intent, attachmentChoice); + @Override + public void onPresenceSelected() { + Intent intent = new Intent(); + boolean chooser = false; + String fallbackPackageId = null; + switch (attachmentChoice) { + case ATTACHMENT_CHOICE_CHOOSE_IMAGE: + intent.setAction(Intent.ACTION_GET_CONTENT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); } - } else if (fallbackPackageId != null) { - startActivity(getInstallApkIntent(fallbackPackageId)); + intent.setType("image/*"); + chooser = true; + break; + case ATTACHMENT_CHOICE_TAKE_PHOTO: + Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri(); + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mPendingImageUris.clear(); + mPendingImageUris.add(uri); + break; + case ATTACHMENT_CHOICE_CHOOSE_FILE: + chooser = true; + intent.setType("*/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setAction(Intent.ACTION_GET_CONTENT); + break; + case ATTACHMENT_CHOICE_RECORD_VOICE: + intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + break; + case ATTACHMENT_CHOICE_LOCATION: + intent.setAction("eu.siacs.conversations.location.request"); + fallbackPackageId = "eu.siacs.conversations.sharelocation"; + break; + } + if (intent.resolveActivity(getPackageManager()) != null) { + if (chooser) { + startActivityForResult( + Intent.createChooser(intent, getString(R.string.perform_action_with)), + attachmentChoice); + } else { + startActivityForResult(intent, attachmentChoice); } + } else if (fallbackPackageId != null) { + startActivity(getInstallApkIntent(fallbackPackageId)); } - }); + } + }; + if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) { + getSelectedConversation().setNextCounterpart(null); + callback.onPresenceSelected(); + } else { + selectPresence(getSelectedConversation(),callback); } } -- cgit v1.2.3 From e6aa604aded25c304816164624b94bb8abe3d69f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 06:10:47 +0200 Subject: enabled sm logging by default at least for development branch --- src/main/java/eu/siacs/conversations/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 5cca6c0b..5bf320a1 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -28,7 +28,7 @@ public final class Config { public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance - public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts + public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; -- cgit v1.2.3 From 5136bf9832b9a7aeb59926b42fe6a6632452c1ef Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 06:17:34 +0200 Subject: r/o support for vcard avatars. pep avatars will be prefered --- .../eu/siacs/conversations/entities/Contact.java | 26 ++++++++--- .../siacs/conversations/generator/IqGenerator.java | 9 +++- .../siacs/conversations/parser/MessageParser.java | 2 +- .../siacs/conversations/parser/PresenceParser.java | 15 ++++++ .../services/XmppConnectionService.java | 53 ++++++++++++++++++---- .../eu/siacs/conversations/xmpp/pep/Avatar.java | 50 ++++++++++++++++---- 6 files changed, 127 insertions(+), 28 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index cef03ebe..4ad105b1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -15,6 +15,7 @@ import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.pep.Avatar; public class Contact implements ListItem, Blockable { public static final String TABLENAME = "contacts"; @@ -40,11 +41,11 @@ public class Contact implements ListItem, Blockable { protected int subscription = 0; protected String systemAccount; protected String photoUri; - protected String avatar; protected JSONObject keys = new JSONObject(); protected JSONArray groups = new JSONArray(); protected Presences presences = new Presences(); protected Account account; + protected Avatar avatar; public Contact(final String account, final String systemName, final String serverName, final Jid jid, final int subscription, final String photoUri, @@ -61,7 +62,11 @@ public class Contact implements ListItem, Blockable { } catch (JSONException e) { this.keys = new JSONObject(); } - this.avatar = avatar; + if (avatar != null) { + this.avatar = new Avatar(); + this.avatar.sha1sum = avatar; + this.avatar.origin = Avatar.Origin.VCARD; //always assume worst + } try { this.groups = (groups == null ? new JSONArray() : new JSONArray(groups)); } catch (JSONException e) { @@ -187,7 +192,7 @@ public class Contact implements ListItem, Blockable { values.put(SYSTEMACCOUNT, systemAccount); values.put(PHOTOURI, photoUri); values.put(KEYS, keys.toString()); - values.put(AVATAR, avatar); + values.put(AVATAR, avatar == null ? null : avatar.getFilename()); values.put(LAST_PRESENCE, lastseen.presence); values.put(LAST_TIME, lastseen.time); values.put(GROUPS, groups.toString()); @@ -411,17 +416,20 @@ public class Contact implements ListItem, Blockable { return getJid().toDomainJid(); } - public boolean setAvatar(String filename) { - if (this.avatar != null && this.avatar.equals(filename)) { + public boolean setAvatar(Avatar avatar) { + if (this.avatar != null && this.avatar.equals(avatar)) { return false; } else { - this.avatar = filename; + if (this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) { + return false; + } + this.avatar = avatar; return true; } } public String getAvatar() { - return this.avatar; + return avatar == null ? null : avatar.getFilename(); } public boolean deleteOtrFingerprint(String fingerprint) { @@ -478,6 +486,10 @@ public class Contact implements ListItem, Blockable { } } + public boolean isSelf() { + return account.getJid().toBareJid().equals(getJid().toBareJid()); + } + public static class Lastseen { public long time; public String presence; diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 6bc629b5..d7366daa 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -91,7 +91,7 @@ public class IqGenerator extends AbstractGenerator { return publish("urn:xmpp:avatar:metadata", item); } - public IqPacket retrieveAvatar(final Avatar avatar) { + public IqPacket retrievePepAvatar(final Avatar avatar) { final Element item = new Element("item"); item.setAttribute("id", avatar.sha1sum); final IqPacket packet = retrieve("urn:xmpp:avatar:data", item); @@ -99,6 +99,13 @@ public class IqGenerator extends AbstractGenerator { return packet; } + public IqPacket retrieveVcardAvatar(final Avatar avatar) { + final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); + packet.setTo(avatar.owner); + packet.addChild("vCard","vcard-temp"); + return packet; + } + public IqPacket retrieveAvatarMetaData(final Jid to) { final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null); if (to != null) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 76d01468..7870fdbf 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -494,7 +494,7 @@ public class MessageParser extends AbstractParser implements } else { Contact contact = account.getRoster().getContact( from); - contact.setAvatar(avatar.getFilename()); + contact.setAvatar(avatar); mXmppConnectionService.getAvatarService().clear( contact); mXmppConnectionService.updateConversationUi(); diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 7505b091..f7872210 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -13,6 +13,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; public class PresenceParser extends AbstractParser implements @@ -101,6 +102,20 @@ public class PresenceParser extends AbstractParser implements if (nick != null) { contact.setPresenceName(nick.getContent()); } + Element x = packet.findChild("x","vcard-temp:x:update"); + Avatar avatar = Avatar.parsePresence(x); + if (avatar != null && !contact.isSelf()) { + avatar.owner = from.toBareJid(); + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + if (contact.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(contact); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateRosterUi(); + } + } else { + mXmppConnectionService.fetchAvatar(account,avatar); + } + } mXmppConnectionService.updateRosterUi(); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ec0b3f92..9cee3538 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1893,9 +1893,19 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchAvatar(account, avatar, null); } - public void fetchAvatar(Account account, final Avatar avatar, - final UiCallback callback) { - IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); + public void fetchAvatar(Account account, final Avatar avatar, final UiCallback callback) { + switch (avatar.origin) { + case PEP: + fetchAvatarPep(account,avatar,callback); + break; + case VCARD: + fetchAvatarVcard(account, avatar, callback); + break; + } + } + + private void fetchAvatarPep(Account account, final Avatar avatar, final UiCallback callback) { + IqPacket packet = this.mIqGenerator.retrievePepAvatar(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @Override @@ -1916,7 +1926,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { Contact contact = account.getRoster() .getContact(avatar.owner); - contact.setAvatar(avatar.getFilename()); + contact.setAvatar(avatar); getAvatarService().clear(contact); updateConversationUi(); updateRosterUi(); @@ -1925,8 +1935,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.success(avatar); } Log.d(Config.LOGTAG, account.getJid().toBareJid() - + ": succesfully fetched avatar for " - + avatar.owner); + + ": succesfuly fetched pep avatar for " + avatar.owner); return; } } else { @@ -1949,8 +1958,34 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - public void checkForAvatar(Account account, - final UiCallback callback) { + private void fetchAvatarVcard(final Account account, final Avatar avatar, final UiCallback callback) { + IqPacket packet = this.mIqGenerator.retrieveVcardAvatar(avatar); + this.sendIqPacket(account,packet,new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element vCard = packet.findChild("vCard","vcard-temp"); + Element photo = vCard != null ? vCard.findChild("PHOTO") : null; + Element binval = photo != null ? photo.findChild("BINVAL") : null; + if (binval != null) { + avatar.image = binval.getContent(); + if (getFileBackend().save(avatar)) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + + ": successfully fetched vCard avatar for " + avatar.owner); + Contact contact = account.getRoster() + .getContact(avatar.owner); + contact.setAvatar(avatar); + getAvatarService().clear(contact); + updateConversationUi(); + updateRosterUi(); + } + } + } + } + }); + } + + public void checkForAvatar(Account account, final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); this.sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1972,7 +2007,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa getAvatarService().clear(account); callback.success(avatar); } else { - fetchAvatar(account, avatar, callback); + fetchAvatarPep(account, avatar, callback); } return; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java index 9f5ac988..04d55bbe 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java +++ b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java @@ -6,6 +6,9 @@ import eu.siacs.conversations.xmpp.jid.Jid; import android.util.Base64; public class Avatar { + + public enum Origin { PEP, VCARD }; + public String type; public String sha1sum; public String image; @@ -13,21 +16,14 @@ public class Avatar { public int width; public long size; public Jid owner; + public Origin origin = Origin.PEP; //default to maintain compat public byte[] getImageAsBytes() { return Base64.decode(image, Base64.DEFAULT); } public String getFilename() { - if (type == null) { - return sha1sum; - } else if (type.equalsIgnoreCase("image/webp")) { - return sha1sum + ".webp"; - } else if (type.equalsIgnoreCase("image/png")) { - return sha1sum + ".png"; - } else { - return sha1sum; - } + return sha1sum; } public static Avatar parseMetadata(Element items) { @@ -64,10 +60,44 @@ public class Avatar { return null; } avatar.type = child.getAttribute("type"); - avatar.sha1sum = child.getAttribute("id"); + String hash = child.getAttribute("id"); + if (!isValidSHA1(hash)) { + return null; + } + avatar.sha1sum = hash; + avatar.origin = Origin.PEP; return avatar; } } return null; } + + @Override + public boolean equals(Object object) { + if (object != null && object instanceof Avatar) { + Avatar other = (Avatar) object; + return other.getFilename().equals(this.getFilename()); + } else { + return false; + } + } + + public static Avatar parsePresence(Element x) { + Element photo = x != null ? x.findChild("photo") : null; + String hash = photo != null ? photo.getContent() : null; + if (hash == null) { + return null; + } + if (!isValidSHA1(hash)) { + return null; + } + Avatar avatar = new Avatar(); + avatar.sha1sum = hash; + avatar.origin = Origin.VCARD; + return avatar; + } + + private static boolean isValidSHA1(String s) { + return s != null && s.matches("[a-fA-F0-9]{40}"); + } } -- cgit v1.2.3 From 9eaa6800cae844b15df7b727d476fc9392f0f4bf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 08:10:16 +0200 Subject: bumped version code --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b312725e..a8b32a6b 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 61 + versionCode 62 versionName "1.4.0-alpha" } -- cgit v1.2.3 From b7c672e10e974a5eee19fb50556851e1c8d4635b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 10:29:41 +0200 Subject: avoid fetching avatars multiple times in parallel --- .../services/XmppConnectionService.java | 47 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9cee3538..6b53b758 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -41,6 +41,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -210,6 +211,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( this); private AvatarService mAvatarService = new AvatarService(this); + private final List mInProgressAvatarFetches = new ArrayList<>(); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private Integer convChangedListenerCount = 0; @@ -328,7 +330,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa message.setCounterpart(conversation.getNextCounterpart()); } if (encryption == Message.ENCRYPTION_DECRYPTED) { - getPgpEngine().encrypt(message,callback); + getPgpEngine().encrypt(message, callback); } else { callback.success(message); } @@ -1893,14 +1895,27 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchAvatar(account, avatar, null); } + private static String generateFetchKey(Account account, final Avatar avatar) { + return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum; + } + public void fetchAvatar(Account account, final Avatar avatar, final UiCallback callback) { - switch (avatar.origin) { - case PEP: - fetchAvatarPep(account,avatar,callback); - break; - case VCARD: - fetchAvatarVcard(account, avatar, callback); - break; + final String KEY = generateFetchKey(account, avatar); + synchronized(this.mInProgressAvatarFetches) { + if (this.mInProgressAvatarFetches.contains(KEY)) { + return; + } else { + switch (avatar.origin) { + case PEP: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarPep(account, avatar, callback); + break; + case VCARD: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarVcard(account, avatar, callback); + break; + } + } } } @@ -1910,6 +1925,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket result) { + synchronized (mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); + } final String ERROR = account.getJid().toBareJid() + ": fetching avatar for " + avatar.owner + " failed "; if (result.getType() == IqPacket.TYPE.RESULT) { @@ -1963,6 +1981,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.sendIqPacket(account,packet,new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { + synchronized(mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account,avatar)); + } if (packet.getType() == IqPacket.TYPE.RESULT) { Element vCard = packet.findChild("vCard","vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; @@ -2043,6 +2064,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa disconnect(account, force); } if (!account.isOptionSet(Account.OPTION_DISABLED)) { + + synchronized (this.mInProgressAvatarFetches) { + for(Iterator iterator = this.mInProgressAvatarFetches.iterator(); iterator.hasNext();) { + final String KEY = iterator.next(); + if (KEY.startsWith(account.getJid().toBareJid()+"_")) { + iterator.remove(); + } + } + } + if (account.getXmppConnection() == null) { account.setXmppConnection(createConnection(account)); } -- cgit v1.2.3 From db726a59b85146c583432bd9da58a34641356f0c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 6 May 2015 04:29:45 +0200 Subject: fwiw don't allow stanza count to go over MAX_INT --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index a2b58a14..0af6045f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -437,6 +437,10 @@ public class XmppConnection implements Runnable { throw new IOException("interrupted mid tag"); } } + if (stanzasReceived == Integer.MAX_VALUE) { + resetStreamId(); + throw new IOException("time to restart the session. cant handle >2 billion pcks"); + } ++stanzasReceived; lastPacketReceived = SystemClock.elapsedRealtime(); return element; @@ -901,6 +905,11 @@ public class XmppConnection implements Runnable { } private synchronized void sendPacket(final AbstractStanza packet) { + if (stanzasSent == Integer.MAX_VALUE) { + resetStreamId(); + disconnect(true); + return; + } final String name = packet.getName(); if (name.equals("iq") || name.equals("message") || name.equals("presence")) { ++stanzasSent; -- cgit v1.2.3 From d74e8a8a0ea20258e9e0eefbea75f94b7559f9b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 6 May 2015 04:33:21 +0200 Subject: fixed npe when missing instructions on failed register --- .../java/eu/siacs/conversations/xmpp/XmppConnection.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0af6045f..0aa67da2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -647,10 +647,8 @@ public class XmppConnection implements Runnable { if (packet.query().hasChild("username") && (packet.query().hasChild("password"))) { final IqPacket register = new IqPacket(IqPacket.TYPE.SET); - final Element username = new Element("username") - .setContent(account.getUsername()); - final Element password = new Element("password") - .setContent(account.getPassword()); + final Element username = new Element("username").setContent(account.getUsername()); + final Element password = new Element("password").setContent(account.getPassword()); register.query("jabber:iq:register").addChild(username); register.query().addChild(password); sendIqPacket(register, new OnIqPacketReceived() { @@ -663,7 +661,7 @@ public class XmppConnection implements Runnable { changeStatus(Account.State.REGISTRATION_SUCCESSFUL); } else if (packet.hasChild("error") && (packet.findChild("error") - .hasChild("conflict"))) { + .hasChild("conflict"))) { changeStatus(Account.State.REGISTRATION_CONFLICT); } else { changeStatus(Account.State.REGISTRATION_FAILED); @@ -677,7 +675,7 @@ public class XmppConnection implements Runnable { disconnect(true); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not register. instructions are" - + instructions.getContent()); + + instructions != null ? instructions.getContent() : ""); } } }); @@ -692,7 +690,7 @@ public class XmppConnection implements Runnable { } final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind") - .addChild("resource").setContent(account.getResource()); + .addChild("resource").setContent(account.getResource()); this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { -- cgit v1.2.3 From 05f0aa614f5af638c6d6da5a4c6a119e1ec6eda8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 11:07:15 +0200 Subject: fixed npe when binval value of vcard avatar is null --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 6b53b758..e58f760e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1988,8 +1988,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Element vCard = packet.findChild("vCard","vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; Element binval = photo != null ? photo.findChild("BINVAL") : null; - if (binval != null) { - avatar.image = binval.getContent(); + String image = binval != null ? binval.getContent() : null; + if (image != null) { + avatar.image = image; if (getFileBackend().save(avatar)) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": successfully fetched vCard avatar for " + avatar.owner); -- cgit v1.2.3 From e0653c03713efe0e4f2f5438b31d1417b059761b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 14:19:51 +0200 Subject: fixed encrypted ibb file transfer which was broken with ART. fixes #1172 --- .../xmpp/jingle/JingleConnection.java | 2 +- .../xmpp/jingle/JingleInbandTransport.java | 57 ++++++++++++---------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index e448f947..4847d5f1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -99,7 +99,7 @@ public class JingleConnection implements Downloadable { file.delete(); } } - Log.d(Config.LOGTAG,"sucessfully transmitted file:" + file.getAbsolutePath()); + Log.d(Config.LOGTAG,"successfully transmitted file:" + file.getAbsolutePath()+" ("+file.getSha1Sum()+")"); if (message.getEncryption() != Message.ENCRYPTION_PGP) { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 9866af03..4e039ad8 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -8,7 +8,9 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import android.util.Base64; +import android.util.Log; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.persistance.FileBackend; @@ -110,7 +112,11 @@ public class JingleInbandTransport extends JingleTransport { this.onFileTransmissionStatusChanged = callback; this.file = file; try { - this.remainingSize = this.file.getSize(); + if (this.file.getKey() != null) { + this.remainingSize = (this.file.getSize() / 16 + 1) * 16; + } else { + this.remainingSize = this.file.getSize(); + } this.fileSize = this.remainingSize; this.digest = MessageDigest.getInstance("SHA-1"); this.digest.reset(); @@ -150,29 +156,33 @@ public class JingleInbandTransport extends JingleTransport { byte[] buffer = new byte[this.bufferSize]; try { int count = fileInputStream.read(buffer); - if (count == -1) { + this.remainingSize -= count; + if (count != buffer.length && count != -1) { + int rem = fileInputStream.read(buffer,count,buffer.length-count); + if (rem > 0) { + count += rem; + } + } + this.digest.update(buffer,0,count); + String base64 = Base64.encodeToString(buffer,0,count, Base64.NO_WRAP); + IqPacket iq = new IqPacket(IqPacket.TYPE.SET); + iq.setTo(this.counterpart); + Element data = iq.addChild("data", "http://jabber.org/protocol/ibb"); + data.setAttribute("seq", Integer.toString(this.seq)); + data.setAttribute("block-size", Integer.toString(this.blockSize)); + data.setAttribute("sid", this.sessionId); + data.setContent(base64); + this.account.getXmppConnection().sendIqPacket(iq, this.onAckReceived); + this.seq++; + if (this.remainingSize > 0) { + connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); + } else { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - fileInputStream.close(); this.onFileTransmissionStatusChanged.onFileTransmitted(file); - } else { - this.remainingSize -= count; - this.digest.update(buffer); - String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP); - IqPacket iq = new IqPacket(IqPacket.TYPE.SET); - iq.setTo(this.counterpart); - Element data = iq.addChild("data", - "http://jabber.org/protocol/ibb"); - data.setAttribute("seq", Integer.toString(this.seq)); - data.setAttribute("block-size", - Integer.toString(this.blockSize)); - data.setAttribute("sid", this.sessionId); - data.setContent(base64); - this.account.getXmppConnection().sendIqPacket(iq, - this.onAckReceived); - this.seq++; - connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); + fileInputStream.close(); } } catch (IOException e) { + Log.d(Config.LOGTAG,e.getMessage()); FileBackend.close(fileInputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } @@ -182,14 +192,10 @@ public class JingleInbandTransport extends JingleTransport { try { byte[] buffer = Base64.decode(data, Base64.NO_WRAP); if (this.remainingSize < buffer.length) { - buffer = Arrays - .copyOfRange(buffer, 0, (int) this.remainingSize); + buffer = Arrays.copyOfRange(buffer, 0, (int) this.remainingSize); } this.remainingSize -= buffer.length; - - this.fileOutputStream.write(buffer); - this.digest.update(buffer); if (this.remainingSize <= 0) { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); @@ -200,6 +206,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { + Log.d(Config.LOGTAG,e.getMessage()); FileBackend.close(fileOutputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } -- cgit v1.2.3 From 90b74d4b800d936c270d922eaab98eaa8a1864fa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 14:24:40 +0200 Subject: version code bumped --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a8b32a6b..0bde37f5 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 62 + versionCode 63 versionName "1.4.0-alpha" } -- cgit v1.2.3 From c4a4dd239207d95647e50f3132277e2371078d0d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2015 06:30:06 +0200 Subject: throw proper exception before changing account into error state --- .../siacs/conversations/xmpp/XmppConnection.java | 42 ++++++++++++++++------ 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0aa67da2..6c67c072 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -167,7 +167,7 @@ public class XmppConnection implements Runnable { try { String srvRecordServer; try { - srvRecordServer=IDN.toASCII(namePort.getString("name")); + srvRecordServer = IDN.toASCII(namePort.getString("name")); } catch (final IllegalArgumentException e) { // TODO: Handle me?` srvRecordServer = ""; @@ -224,6 +224,12 @@ public class XmppConnection implements Runnable { if (socket.isConnected()) { socket.close(); } + } catch (final IncompatibleServerException e) { + this.changeStatus(Account.State.INCOMPATIBLE_SERVER); + } catch (final SecurityException e) { + this.changeStatus(Account.State.SECURITY_ERROR); + } catch (final UnauthorizedException e) { + this.changeStatus(Account.State.UNAUTHORIZED); } catch (final UnknownHostException | ConnectException e) { this.changeStatus(Account.State.SERVER_NOT_FOUND); } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { @@ -231,6 +237,13 @@ public class XmppConnection implements Runnable { this.changeStatus(Account.State.OFFLINE); this.attempt--; //don't count attempt when reconnecting instantly anyway } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + + } + } if (wakeLock.isHeld()) { try { wakeLock.release(); @@ -279,8 +292,7 @@ public class XmppConnection implements Runnable { processStream(tagReader.readTag()); break; } else if (nextTag.isStart("failure")) { - tagReader.readElement(nextTag); - changeStatus(Account.State.UNAUTHORIZED); + throw new UnauthorizedException(); } else if (nextTag.isStart("challenge")) { final String challenge = tagReader.readElement(nextTag).getContent(); final Element response = new Element("response"); @@ -542,8 +554,7 @@ public class XmppConnection implements Runnable { if (!verifier.verify(account.getServer().getDomainpart(),sslSocket.getSession())) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } tagReader.setInputStream(sslSocket.getInputStream()); tagWriter.setOutputStream(sslSocket.getOutputStream()); @@ -554,8 +565,7 @@ public class XmppConnection implements Runnable { sslSocket.close(); } catch (final NoSuchAlgorithmException | KeyManagementException e1) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } } @@ -594,8 +604,7 @@ public class XmppConnection implements Runnable { " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + "). Possible downgrade attack?"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } } catch (final JSONException e) { Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); @@ -607,8 +616,7 @@ public class XmppConnection implements Runnable { } tagWriter.writeElement(auth); } else { - disconnect(true); - changeStatus(Account.State.INCOMPATIBLE_SERVER); + throw new IncompatibleServerException(); } } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) @@ -1098,6 +1106,18 @@ public class XmppConnection implements Runnable { public final ArrayList> identities = new ArrayList<>(); } + private class UnauthorizedException extends IOException { + + } + + private class SecurityException extends IOException { + + } + + private class IncompatibleServerException extends IOException { + + } + public class Features { XmppConnection connection; private boolean carbonsEnabled = false; -- cgit v1.2.3 From d9e5035c084a5bf307d88fb4b69c585ffb5e859b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2015 06:50:28 +0200 Subject: config option to reset attempt counts when changing network (default=true) --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../services/XmppConnectionService.java | 26 +++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 5bf320a1..9f5d14fd 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -29,6 +29,7 @@ public final class Config { public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts + public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e58f760e..34c0a5d1 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -424,6 +424,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final String action = intent == null ? null : intent.getAction(); if (action != null) { switch (action) { + case ConnectivityManager.CONNECTIVITY_ACTION: + if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) { + resetAllAttemptCounts(true); + } + break; case ACTION_MERGE_PHONE_CONTACTS: if (mRestoredFromDatabase) { PhoneHelper.loadPhoneContacts(getApplicationContext(), @@ -442,14 +447,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa toggleForegroundService(); break; case ACTION_TRY_AGAIN: - for(Account account : accounts) { - if (account.hasErrorStatus()) { - final XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.resetAttemptCount(); - } - } - } + resetAllAttemptCounts(false); break; case ACTION_DISABLE_ACCOUNT: try { @@ -531,6 +529,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return START_STICKY; } + private void resetAllAttemptCounts(boolean reallyAll) { + Log.d(Config.LOGTAG,"resetting all attepmt counts"); + for(Account account : accounts) { + if (account.hasErrorStatus() || reallyAll) { + final XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.resetAttemptCount(); + } + } + } + } + public boolean hasInternetConnection() { ConnectivityManager cm = (ConnectivityManager) getApplicationContext() .getSystemService(Context.CONNECTIVITY_SERVICE); -- cgit v1.2.3 From 9e78e3e09da47463d97a25acd051a8218fa98e54 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 8 May 2015 21:36:20 +0200 Subject: only forward incoming chat messages to Pebble App and Gadgetbridge --- .../java/eu/siacs/conversations/services/NotificationService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index fc40ce75..e111da95 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -85,7 +85,11 @@ public class NotificationService { i.putExtra("messageType", "PEBBLE_ALERT"); i.putExtra("sender", "Conversations"); /* XXX: Shouldn't be hardcoded, e.g., AbstractGenerator.APP_NAME); */ i.putExtra("notificationData", notificationData); - + // notify Pebble App + i.setPackage("com.getpebble.android"); + mXmppConnectionService.sendBroadcast(i); + // notify Gadgetbridge + i.setPackage("nodomain.freeyourgadget.gadgetbridge"); mXmppConnectionService.sendBroadcast(i); } -- cgit v1.2.3 From 4c486f5e583ddfc1f53f296d8a6fa9672981440a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 03:12:44 +0200 Subject: paint single unicode hearts as red and slightly larger --- .../eu/siacs/conversations/entities/Message.java | 72 ++++++++++++---------- .../conversations/ui/adapter/MessageAdapter.java | 26 ++++++-- .../eu/siacs/conversations/utils/UIHelper.java | 4 ++ 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 7ea3d60b..95e27c79 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -9,6 +9,7 @@ import java.util.Arrays; import eu.siacs.conversations.Config; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -95,9 +96,9 @@ public class Message extends AbstractEntity { } private Message(final String uuid, final String conversationUUid, final Jid counterpart, - final Jid trueCounterpart, final String body, final long timeSent, - final int encryption, final int status, final int type, final String remoteMsgId, - final String relativeFilePath, final String serverMsgId) { + final Jid trueCounterpart, final String body, final long timeSent, + final int encryption, final int status, final int type, final String remoteMsgId, + final String relativeFilePath, final String serverMsgId) { this.uuid = uuid; this.conversationUuid = conversationUUid; this.counterpart = counterpart; @@ -179,7 +180,7 @@ public class Message extends AbstractEntity { values.put(TYPE, type); values.put(REMOTE_MSG_ID, remoteMsgId); values.put(RELATIVE_FILE_PATH, relativeFilePath); - values.put(SERVER_MSG_ID,serverMsgId); + values.put(SERVER_MSG_ID, serverMsgId); return values; } @@ -211,7 +212,7 @@ public class Message extends AbstractEntity { return null; } else { return this.conversation.getAccount().getRoster() - .getContactFromRoster(this.trueCounterpart); + .getContactFromRoster(this.trueCounterpart); } } } @@ -359,34 +360,36 @@ public class Message extends AbstractEntity { public boolean mergeable(final Message message) { return message != null && - (message.getType() == Message.TYPE_TEXT && - this.getDownloadable() == null && - message.getDownloadable() == null && - message.getEncryption() != Message.ENCRYPTION_PGP && - this.getType() == message.getType() && - //this.getStatus() == message.getStatus() && - isStatusMergeable(this.getStatus(),message.getStatus()) && - this.getEncryption() == message.getEncryption() && - this.getCounterpart() != null && - this.getCounterpart().equals(message.getCounterpart()) && - (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && - !GeoHelper.isGeoUri(message.getBody()) && - !GeoHelper.isGeoUri(this.body) && - !message.bodyContainsDownloadable() && - !this.bodyContainsDownloadable() && - !message.getBody().startsWith(ME_COMMAND) && - !this.getBody().startsWith(ME_COMMAND) - ); + (message.getType() == Message.TYPE_TEXT && + this.getDownloadable() == null && + message.getDownloadable() == null && + message.getEncryption() != Message.ENCRYPTION_PGP && + this.getType() == message.getType() && + //this.getStatus() == message.getStatus() && + isStatusMergeable(this.getStatus(), message.getStatus()) && + this.getEncryption() == message.getEncryption() && + this.getCounterpart() != null && + this.getCounterpart().equals(message.getCounterpart()) && + (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && + !GeoHelper.isGeoUri(message.getBody()) && + !GeoHelper.isGeoUri(this.body) && + !message.bodyContainsDownloadable() && + !this.bodyContainsDownloadable() && + !message.getBody().startsWith(ME_COMMAND) && + !this.getBody().startsWith(ME_COMMAND) && + !this.bodyIsHeart() && + !message.bodyIsHeart() + ); } private static boolean isStatusMergeable(int a, int b) { return a == b || ( - ( a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND_RECEIVED) - || (a == Message.STATUS_SEND && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND && b == Message.STATUS_SEND_RECEIVED) + (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_UNSEND) + || (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_SEND) + || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND) + || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND_RECEIVED) + || (a == Message.STATUS_SEND && b == Message.STATUS_UNSEND) + || (a == Message.STATUS_SEND && b == Message.STATUS_SEND_RECEIVED) ); } @@ -443,7 +446,7 @@ public class Message extends AbstractEntity { if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { return false; - } + } String sUrlPath = url.getPath(); if (sUrlPath == null || sUrlPath.isEmpty()) { @@ -457,14 +460,14 @@ public class Message extends AbstractEntity { String[] extensionParts = sLastUrlPath.split("\\."); if (extensionParts.length == 2 && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 1])) { + extensionParts[extensionParts.length - 1])) { return true; } else if (extensionParts.length == 3 && Arrays .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) .contains(extensionParts[extensionParts.length - 1]) && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 2])) { + extensionParts[extensionParts.length - 2])) { return true; } else { return false; @@ -474,6 +477,11 @@ public class Message extends AbstractEntity { } } + public boolean bodyIsHeart() { + return body != null && + (body.trim().equals(UIHelper.BLACK_HEART_SUIT) || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT)); + } + public ImageParams getImageParams() { ImageParams params = getLegacyImageParams(); if (params != null) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index da92fb18..89618dfc 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -7,7 +7,9 @@ import android.graphics.Typeface; import android.net.Uri; import android.text.Spannable; import android.text.SpannableString; +import android.text.Spanned; import android.text.style.ForegroundColorSpan; +import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; import android.util.Log; @@ -207,12 +209,24 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); + R.string.decryption_failed)); viewHolder.messageBody.setTextColor(activity.getWarningTextColor()); viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); viewHolder.messageBody.setTextIsSelectable(false); } + private void displayHeartMesage(final ViewHolder viewHolder, final String body) { + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + Spannable span = new SpannableString(body); + span.setSpan(new RelativeSizeSpan(4.0f),0,body.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()),0,body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); + } + private void displayTextMessage(final ViewHolder viewHolder, final Message message) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); @@ -289,7 +303,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity,message))); + viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message))); viewHolder.download_button.setOnClickListener(new OnClickListener() { @Override @@ -334,7 +348,7 @@ public class MessageAdapter extends ArrayAdapter { scalledH = (int) (params.height / ((double) params.width / target)); } viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams( - scalledW, scalledH)); + scalledW, scalledH)); activity.loadBitmap(message, viewHolder.image); viewHolder.image.setOnClickListener(new OnClickListener() { @@ -528,7 +542,11 @@ public class MessageAdapter extends ArrayAdapter { if (GeoHelper.isGeoUri(message.getBody())) { displayLocationMessage(viewHolder,message); } else { - displayTextMessage(viewHolder, message); + if (message.bodyIsHeart()) { + displayHeartMesage(viewHolder," "+message.getBody().trim()+" "); + } else { + displayTextMessage(viewHolder, message); + } } } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index c3195d86..49354753 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -17,6 +17,10 @@ import android.text.format.DateUtils; import android.util.Pair; public class UIHelper { + + public static String BLACK_HEART_SUIT = "\u2665"; + public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME -- cgit v1.2.3 From 1e28f600386f1f1dcd734363c932d5ccbd6267fb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 03:14:13 +0200 Subject: changed conversation red to material red --- art/ic_send_cancel_dnd.svg | 2 +- art/ic_send_location_dnd.svg | 2 +- art/ic_send_photo_dnd.svg | 4 ++-- art/ic_send_text_dnd.svg | 2 +- art/ic_send_voice_dnd.svg | 2 +- .../java/eu/siacs/conversations/entities/Contact.java | 4 ++-- src/main/res/drawable-hdpi/ic_send_cancel_dnd.png | Bin 1559 -> 1587 bytes src/main/res/drawable-hdpi/ic_send_location_dnd.png | Bin 1333 -> 1333 bytes src/main/res/drawable-hdpi/ic_send_photo_dnd.png | Bin 1381 -> 1383 bytes src/main/res/drawable-hdpi/ic_send_text_dnd.png | Bin 1126 -> 1128 bytes src/main/res/drawable-hdpi/ic_send_voice_dnd.png | Bin 1149 -> 1161 bytes src/main/res/drawable-mdpi/ic_send_cancel_dnd.png | Bin 1040 -> 1025 bytes src/main/res/drawable-mdpi/ic_send_location_dnd.png | Bin 908 -> 917 bytes src/main/res/drawable-mdpi/ic_send_photo_dnd.png | Bin 909 -> 915 bytes src/main/res/drawable-mdpi/ic_send_text_dnd.png | Bin 769 -> 781 bytes src/main/res/drawable-mdpi/ic_send_voice_dnd.png | Bin 774 -> 795 bytes src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png | Bin 1940 -> 1958 bytes src/main/res/drawable-xhdpi/ic_send_location_dnd.png | Bin 1721 -> 1753 bytes src/main/res/drawable-xhdpi/ic_send_photo_dnd.png | Bin 1723 -> 1756 bytes src/main/res/drawable-xhdpi/ic_send_text_dnd.png | Bin 1395 -> 1430 bytes src/main/res/drawable-xhdpi/ic_send_voice_dnd.png | Bin 1426 -> 1419 bytes src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png | Bin 2911 -> 2983 bytes src/main/res/drawable-xxhdpi/ic_send_location_dnd.png | Bin 2578 -> 2589 bytes src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png | Bin 2588 -> 2618 bytes src/main/res/drawable-xxhdpi/ic_send_text_dnd.png | Bin 2004 -> 2005 bytes src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png | Bin 2152 -> 2200 bytes src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png | Bin 3791 -> 3862 bytes .../res/drawable-xxxhdpi/ic_send_location_dnd.png | Bin 3456 -> 3514 bytes src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png | Bin 3544 -> 3569 bytes src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png | Bin 2597 -> 2592 bytes src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png | Bin 2811 -> 2849 bytes src/main/res/values/colors.xml | 2 +- 32 files changed, 9 insertions(+), 9 deletions(-) diff --git a/art/ic_send_cancel_dnd.svg b/art/ic_send_cancel_dnd.svg index 54e02a91..67a562b2 100644 --- a/art/ic_send_cancel_dnd.svg +++ b/art/ic_send_cancel_dnd.svg @@ -50,5 +50,5 @@ + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_location_dnd.svg b/art/ic_send_location_dnd.svg index d91fa913..705cdb6f 100644 --- a/art/ic_send_location_dnd.svg +++ b/art/ic_send_location_dnd.svg @@ -50,5 +50,5 @@ + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_photo_dnd.svg b/art/ic_send_photo_dnd.svg index 0e406ede..9ef8b782 100644 --- a/art/ic_send_photo_dnd.svg +++ b/art/ic_send_photo_dnd.svg @@ -52,9 +52,9 @@ cy="24" r="6.4" id="circle4" - style="fill:#e51c23;fill-opacity:0.627451" /> + style="fill:#f44336;fill-opacity:0.627451" /> + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_text_dnd.svg b/art/ic_send_text_dnd.svg index b594f319..1b7ad51f 100644 --- a/art/ic_send_text_dnd.svg +++ b/art/ic_send_text_dnd.svg @@ -58,7 +58,7 @@ id="grid3631" /> + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index 4ad105b1..9dbca59a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -140,10 +140,10 @@ public class Contact implements ListItem, Blockable { tags.add(new Tag("away", 0xffff9800)); break; case Presences.XA: - tags.add(new Tag("not available", 0xffe51c23)); + tags.add(new Tag("not available", 0xfff44336)); break; case Presences.DND: - tags.add(new Tag("dnd", 0xffe51c23)); + tags.add(new Tag("dnd", 0xfff44336)); break; } if (isBlocked()) { diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png index cbfd8e76..83a7b94b 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_dnd.png b/src/main/res/drawable-hdpi/ic_send_location_dnd.png index 3bcbe18a..a9c51317 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_location_dnd.png and b/src/main/res/drawable-hdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png index 2eb85679..15b1eb7a 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_dnd.png b/src/main/res/drawable-hdpi/ic_send_text_dnd.png index 706b6505..b43428de 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_text_dnd.png and b/src/main/res/drawable-hdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png index 50184ee8..26a89e8e 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png index e4fa38a3..75006446 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_dnd.png b/src/main/res/drawable-mdpi/ic_send_location_dnd.png index 92e68ee3..3f4d6aa4 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_location_dnd.png and b/src/main/res/drawable-mdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png index 7b6700d6..08033f63 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_dnd.png b/src/main/res/drawable-mdpi/ic_send_text_dnd.png index 92df9d3d..c3d9e79a 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_text_dnd.png and b/src/main/res/drawable-mdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png index ef25b1c4..aaf8ff32 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png index 276ad024..dde1b707 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png index 90ce346c..99c8ce36 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png index 2c37db74..fc69cb41 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png index 0a749f8d..8b93ec10 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png index cea4212a..66b0c677 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png index 93fbc44d..e68a912d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png index ea3d1502..1773e62d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png index 09c11a81..fe33a1d0 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png index 0d7e7053..32f5e29c 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png index a5151331..4a5b4104 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png index 02ab1d0f..307ca8a0 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png index 08e2b39b..e7f6fde7 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png index fccb32dc..8a9b0700 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png index 929a33a4..b11cd6b6 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png index 8ac667be..4ad9d389 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index c21650a5..753a56df 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -11,7 +11,7 @@ #ffeeeeee #ff323232 #1f000000 - #ffe51c23 + #fff44336 #ffff9800 #ff259b24 -- cgit v1.2.3 From 33d1621e3b2c9a34689dfddc71eeb9ee4d91c348 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 11:56:23 +0200 Subject: added white heart to new rendering as well --- src/main/java/eu/siacs/conversations/entities/Message.java | 4 +++- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 95e27c79..4dac0b98 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -479,7 +479,9 @@ public class Message extends AbstractEntity { public boolean bodyIsHeart() { return body != null && - (body.trim().equals(UIHelper.BLACK_HEART_SUIT) || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT)); + (body.trim().equals(UIHelper.BLACK_HEART_SUIT) + || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT) + || body.trim().equals(UIHelper.WHITE_HEART_SUIT)); } public ImageParams getImageParams() { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 49354753..2cfd5823 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -20,6 +20,7 @@ public class UIHelper { public static String BLACK_HEART_SUIT = "\u2665"; public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + public static String WHITE_HEART_SUIT = "\u2661"; private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 239e86a98a4af8ab7ce7f6b96bed0bb4dc9e4bb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 12:04:11 +0200 Subject: optimized heart render code a bit --- src/main/java/eu/siacs/conversations/entities/Message.java | 5 +---- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 10 +++++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 4dac0b98..c87e5518 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -478,10 +478,7 @@ public class Message extends AbstractEntity { } public boolean bodyIsHeart() { - return body != null && - (body.trim().equals(UIHelper.BLACK_HEART_SUIT) - || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT) - || body.trim().equals(UIHelper.WHITE_HEART_SUIT)); + return body != null && UIHelper.HEARTS.contains(body.trim()); } public ImageParams getImageParams() { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2cfd5823..9c62dcbf 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.utils; import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -18,9 +20,11 @@ import android.util.Pair; public class UIHelper { - public static String BLACK_HEART_SUIT = "\u2665"; - public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; - public static String WHITE_HEART_SUIT = "\u2661"; + private static String BLACK_HEART_SUIT = "\u2665"; + private static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static String WHITE_HEART_SUIT = "\u2661"; + + public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 22b12091a103a164a1d54874ad376d02dfee1519 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 07:57:52 +0200 Subject: rewrote parts of message adapter to avoid using NULL views --- .../siacs/conversations/entities/Conversation.java | 6 +++ .../conversations/ui/ConversationFragment.java | 48 +++++++++++++--------- .../conversations/ui/adapter/MessageAdapter.java | 41 +++--------------- src/main/res/layout/message_null.xml | 7 ---- 4 files changed, 41 insertions(+), 61 deletions(-) delete mode 100644 src/main/res/layout/message_null.xml diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index bfee5007..95a8c957 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -16,6 +16,7 @@ import java.security.interfaces.DSAPublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import eu.siacs.conversations.Config; @@ -218,6 +219,11 @@ public class Conversation extends AbstractEntity implements Blockable { messages.clear(); messages.addAll(this.messages); } + for(Iterator iterator = messages.iterator(); iterator.hasNext();) { + if (iterator.next().wasMergedIntoPrevious()) { + iterator.remove(); + } + } } @Override diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 6b11d310..b6a7dc76 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -117,6 +117,27 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } + private int getIndexOf(String uuid, List messages) { + if (uuid == null) { + return 0; + } + for(int i = 0; i < messages.size(); ++i) { + if (uuid.equals(messages.get(i).getUuid())) { + return i; + } else { + Message next = messages.get(i); + while(next != null && next.wasMergedIntoPrevious()) { + if (uuid.equals(next.getUuid())) { + return i; + } + next = next.next(); + } + + } + } + return 0; + } + @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { @@ -126,7 +147,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa messagesLoaded = false; activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() { @Override - public void onMoreMessagesLoaded(final int count, Conversation conversation) { + public void onMoreMessagesLoaded(final int c, Conversation conversation) { if (ConversationFragment.this.conversation != conversation) { return; } @@ -134,29 +155,18 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void run() { final int oldPosition = messagesView.getFirstVisiblePosition(); + Message message = messageList.get(oldPosition); + String uuid = message != null ? message.getUuid() : null; View v = messagesView.getChildAt(0); final int pxOffset = (v == null) ? 0 : v.getTop(); ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList); updateStatusMessages(); messageListAdapter.notifyDataSetChanged(); - if (count != 0) { - final int newPosition = oldPosition + count; - int offset = 0; - try { - Message tmpMessage = messageList.get(newPosition); - - while (tmpMessage.wasMergedIntoPrevious()) { - offset++; - tmpMessage = tmpMessage.prev(); - } - } catch (final IndexOutOfBoundsException ignored) { - - } - messagesView.setSelectionFromTop(newPosition - offset, pxOffset); - messagesLoaded = true; - if (messageLoaderToast != null) { - messageLoaderToast.cancel(); - } + int pos = getIndexOf(uuid,messageList); + messagesView.setSelectionFromTop(pos, pxOffset); + messagesLoaded = true; + if (messageLoaderToast != null) { + messageLoaderToast.cancel(); } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 89618dfc..b23709fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -12,7 +12,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; @@ -26,7 +25,6 @@ import android.widget.Toast; import java.util.List; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; @@ -44,7 +42,6 @@ public class MessageAdapter extends ArrayAdapter { private static final int SENT = 0; private static final int RECEIVED = 1; private static final int STATUS = 2; - private static final int NULL = 3; private ConversationActivity activity; @@ -79,14 +76,12 @@ public class MessageAdapter extends ArrayAdapter { @Override public int getViewTypeCount() { - return 4; + return 3; } @Override public int getItemViewType(int position) { - if (getItem(position).wasMergedIntoPrevious()) { - return NULL; - } else if (getItem(position).getType() == Message.TYPE_STATUS) { + if (getItem(position).getType() == Message.TYPE_STATUS) { return STATUS; } else if (getItem(position).getStatus() <= Message.STATUS_RECEIVED) { return RECEIVED; @@ -222,8 +217,8 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); Spannable span = new SpannableString(body); - span.setSpan(new RelativeSizeSpan(4.0f),0,body.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()),0,body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); viewHolder.messageBody.setText(span); } @@ -235,8 +230,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); - final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND, - nick + " "); + final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { final Spannable span = new SpannableString(formattedBody); @@ -244,7 +238,7 @@ public class MessageAdapter extends ArrayAdapter { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); viewHolder.messageBody.setText(span); } else { - viewHolder.messageBody.setText(message.getMergedBody()); + viewHolder.messageBody.setText(formattedBody); } } else { String privateMarker; @@ -373,10 +367,6 @@ public class MessageAdapter extends ArrayAdapter { if (view == null) { viewHolder = new ViewHolder(); switch (type) { - case NULL: - view = activity.getLayoutInflater().inflate( - R.layout.message_null, parent, false); - break; case SENT: view = activity.getLayoutInflater().inflate( R.layout.message_sent, parent, false); @@ -443,25 +433,6 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.status_message.setText(message.getBody()); } return view; - } else if (type == NULL) { - if (viewHolder.message_box != null) { - Log.e(Config.LOGTAG, "detected type=NULL but with wrong cached view"); - view = activity.getLayoutInflater().inflate(R.layout.message_null, parent, false); - view.setTag(new ViewHolder()); - } - if (position == getCount() - 1) { - view.getLayoutParams().height = 1; - } else { - view.getLayoutParams().height = 0; - - } - view.setLayoutParams(view.getLayoutParams()); - return view; - } else if (message.wasMergedIntoPrevious()) { - Log.e(Config.LOGTAG,"detected wasMergedIntoPrevious with wrong type"); - return view; - } else if (viewHolder.messageBody == null || viewHolder.image == null) { - return view; //avoiding weird platform bugs } else if (type == RECEIVED) { Contact contact = message.getContact(); if (contact != null) { diff --git a/src/main/res/layout/message_null.xml b/src/main/res/layout/message_null.xml deleted file mode 100644 index 0e0f1c92..00000000 --- a/src/main/res/layout/message_null.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file -- cgit v1.2.3 From 21deda7b0029b729c94af9f1551278859b78f119 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 08:45:38 +0200 Subject: no font padding on red hearts --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index b23709fc..060bef71 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -210,12 +210,13 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setTextIsSelectable(false); } - private void displayHeartMesage(final ViewHolder viewHolder, final String body) { + private void displayHeartMessage(final ViewHolder viewHolder, final String body) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(false); Spannable span = new SpannableString(body); span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -228,6 +229,7 @@ public class MessageAdapter extends ArrayAdapter { } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(true); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); @@ -514,7 +516,7 @@ public class MessageAdapter extends ArrayAdapter { displayLocationMessage(viewHolder,message); } else { if (message.bodyIsHeart()) { - displayHeartMesage(viewHolder," "+message.getBody().trim()+" "); + displayHeartMessage(viewHolder, message.getBody().trim()); } else { displayTextMessage(viewHolder, message); } -- cgit v1.2.3 From 53e43daa0d8143d9a5abcd1391153b88a4702914 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 09:08:56 +0200 Subject: add a little bit of space between merged messages. --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- .../java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index c87e5518..3c144f5c 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -396,7 +396,7 @@ public class Message extends AbstractEntity { public String getMergedBody() { final Message next = this.next(); if (this.mergeable(next)) { - return getBody().trim() + '\n' + next.getMergedBody(); + return getBody().trim() + "\n\n" + next.getMergedBody(); } return getBody().trim(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 060bef71..0730f0e1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -232,7 +232,13 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setIncludeFontPadding(true); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); - final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); + final String body = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); + final SpannableString formattedBody = new SpannableString(body); + int i = body.indexOf("\n\n"); + while(i >= 0) { + formattedBody.setSpan(new RelativeSizeSpan(0.2f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + i = body.indexOf("\n\n",i+2); + } if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { final Spannable span = new SpannableString(formattedBody); -- cgit v1.2.3 From 9156665addb5541cacf640f033f03cec0937f052 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 09:20:08 +0200 Subject: increased space between merged messages a bit --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 0730f0e1..ec351622 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -236,7 +236,7 @@ public class MessageAdapter extends ArrayAdapter { final SpannableString formattedBody = new SpannableString(body); int i = body.indexOf("\n\n"); while(i >= 0) { - formattedBody.setSpan(new RelativeSizeSpan(0.2f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); i = body.indexOf("\n\n",i+2); } if (message.getType() != Message.TYPE_PRIVATE) { -- cgit v1.2.3 From b6f85ba0dd765e72a89a85461b3f8c48f038270c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 14:18:30 +0200 Subject: avoid using paragraph style breaks by accident --- src/main/java/eu/siacs/conversations/entities/Message.java | 4 +++- .../java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 3c144f5c..217b82bb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -17,6 +17,8 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; + public static final String MERGE_SEPARATOR = "\u2029\n\n"; + public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; public static final int STATUS_SEND = 2; @@ -396,7 +398,7 @@ public class Message extends AbstractEntity { public String getMergedBody() { final Message next = this.next(); if (this.mergeable(next)) { - return getBody().trim() + "\n\n" + next.getMergedBody(); + return getBody().trim() + MERGE_SEPARATOR + next.getMergedBody(); } return getBody().trim(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index ec351622..29dfced2 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -234,10 +234,11 @@ public class MessageAdapter extends ArrayAdapter { final String nick = UIHelper.getMessageDisplayName(message); final String body = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); final SpannableString formattedBody = new SpannableString(body); - int i = body.indexOf("\n\n"); + int i = body.indexOf(Message.MERGE_SEPARATOR); while(i >= 0) { - formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - i = body.indexOf("\n\n",i+2); + final int end = i + Message.MERGE_SEPARATOR.length(); + formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + i = body.indexOf(Message.MERGE_SEPARATOR,end); } if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { -- cgit v1.2.3 From ceadf2f6fb67666abb0d8f9b84a91841396cfc0a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 14:28:36 +0200 Subject: pulled updated translations from transifex --- src/main/res/values-ru/strings.xml | 2 ++ src/main/res/values-sr/strings.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 2fc257f7..7b104820 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -441,11 +441,13 @@ Удалён %d сертификат Удалено %d сертификатов + Удалено %d сертификатов Выбран %d контакт Выбрано %d контактов + Выбрано %d контактов diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index bcf420ba..ea5cbdb8 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -97,8 +97,8 @@ Опште ИксМПП ресурс Име са којим се овај клијент идентификује - Прихваћај фајлове - Аутоматски прихваћај фајлове мање од… + Прихватај фајлове + Аутоматски прихватај фајлове мање од… Поставке обавештења Обавештења Обавести кад стигне нова порука -- cgit v1.2.3 From fe5c4cab4608a6b3ded682f4a69da14916cc1d37 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 03:56:13 +0200 Subject: don't reinit conversation when coming back to activity. avoids unnecessary scrolling --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index b11ff002..6e175d8e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -927,9 +927,7 @@ public class ConversationActivity extends XmppActivity } this.mConversationFragment.reInit(getSelectedConversation()); mOpenConverstaion = null; - } else if (getSelectedConversation() != null) { - this.mConversationFragment.reInit(getSelectedConversation()); - } else { + } else if (getSelectedConversation() == null) { showConversationsOverview(); mPendingImageUris.clear(); mPendingFileUris.clear(); -- cgit v1.2.3 From 93e444ac3ad4b39415d7097566c319904ff14bcd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 03:57:05 +0200 Subject: don't set unknown error in muc --- src/main/java/eu/siacs/conversations/entities/MucOptions.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index addee8db..d867a370 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -343,8 +343,6 @@ public class MucOptions { setError(ERROR_BANNED); } else if (error != null && error.hasChild("registration-required")) { setError(ERROR_MEMBERS_ONLY); - } else { - setError(ERROR_UNKNOWN); } } } -- cgit v1.2.3 From d3a6aa9f7a3132f8f67f2de99b4afbaba7823abb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 04:33:04 +0200 Subject: handle conference invites differently to deal with killed activities. fixes #1188 --- .../services/XmppConnectionService.java | 1 + .../ui/ConferenceDetailsActivity.java | 4 + .../conversations/ui/ConversationActivity.java | 6 ++ .../eu/siacs/conversations/ui/XmppActivity.java | 87 ++++++++++++++-------- 4 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 34c0a5d1..0ed89206 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2108,6 +2108,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void invite(Conversation conversation, Jid contact) { + Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+": inviting "+contact+" to "+conversation.getJid().toBareJid()); MessagePacket packet = mMessageGenerator.invite(conversation, contact); sendMessagePacket(conversation.getAccount(), packet); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 8c4f6eaf..07b8819d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -385,6 +385,10 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override void onBackendConnected() { + if (mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } if (getIntent().getAction().equals(ACTION_VIEW_MUC)) { this.uuid = getIntent().getExtras().getString("uuid"); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 6e175d8e..a2a405c3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -901,6 +901,12 @@ public class ConversationActivity extends XmppActivity void onBackendConnected() { this.xmppConnectionService.getNotificationService().setIsInForeground(true); updateConversationList(); + + if (mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } + if (xmppConnectionService.getAccounts().size() == 0) { if (!mRedirected) { this.mRedirected = true; diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 392e57a7..71fb62b5 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -113,6 +113,8 @@ public abstract class XmppActivity extends Activity { } }; + protected ConferenceInvite mPendingConferenceInvite = null; + protected void refreshUi() { final long diff = SystemClock.elapsedRealtime() - mLastUiRefresh; @@ -367,7 +369,7 @@ public abstract class XmppActivity extends Activity { } public void highlightInMuc(Conversation conversation, String nick) { - switchToConversation(conversation,null,nick,false); + switchToConversation(conversation, null, nick, false); } private void switchToConversation(Conversation conversation, String text, String nick, boolean newTask) { @@ -435,7 +437,7 @@ public abstract class XmppActivity extends Activity { @Override public void userInputRequried(PendingIntent pi, - Account account) { + Account account) { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); @@ -446,13 +448,13 @@ public abstract class XmppActivity extends Activity { @Override public void success(Account account) { xmppConnectionService.databaseBackend - .updateAccount(account); + .updateAccount(account); xmppConnectionService.sendPresence(account); if (conversation != null) { conversation - .setNextEncryption(Message.ENCRYPTION_PGP); + .setNextEncryption(Message.ENCRYPTION_PGP); xmppConnectionService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); } } @@ -665,32 +667,13 @@ public abstract class XmppActivity extends Activity { protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_INVITE_TO_CONVERSATION - && resultCode == RESULT_OK) { - try { - String conversationUuid = data.getStringExtra("conversation"); - Conversation conversation = xmppConnectionService - .findConversationByUuid(conversationUuid); - List jids = new ArrayList(); - if (data.getBooleanExtra("multiple", false)) { - String[] toAdd = data.getStringArrayExtra("contacts"); - for (String item : toAdd) { - jids.add(Jid.fromString(item)); - } - } else { - jids.add(Jid.fromString(data.getStringExtra("contact"))); - } - - if (conversation.getMode() == Conversation.MODE_MULTI) { - for (Jid jid : jids) { - xmppConnectionService.invite(conversation, jid); - } - } else { - jids.add(conversation.getJid().toBareJid()); - xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback); - } - } catch (final InvalidJidException ignored) { - + if (requestCode == REQUEST_INVITE_TO_CONVERSATION && resultCode == RESULT_OK) { + mPendingConferenceInvite = ConferenceInvite.parse(data); + if (xmppConnectionServiceBound && mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } else { + Log.d(Config.LOGTAG,"putting invite on pending"); } } } @@ -855,6 +838,48 @@ public abstract class XmppActivity extends Activity { } } + public static class ConferenceInvite { + private String uuid; + private List jids = new ArrayList<>(); + + public static ConferenceInvite parse(Intent data) { + ConferenceInvite invite = new ConferenceInvite(); + invite.uuid = data.getStringExtra("conversation"); + if (invite.uuid == null) { + return null; + } + try { + if (data.getBooleanExtra("multiple", false)) { + String[] toAdd = data.getStringArrayExtra("contacts"); + for (String item : toAdd) { + invite.jids.add(Jid.fromString(item)); + } + } else { + invite.jids.add(Jid.fromString(data.getStringExtra("contact"))); + } + } catch (final InvalidJidException ignored) { + return null; + } + return invite; + } + + public void execute(XmppActivity activity) { + XmppConnectionService service = activity.xmppConnectionService; + Conversation conversation = service.findConversationByUuid(this.uuid); + if (conversation == null) { + return; + } + if (conversation.getMode() == Conversation.MODE_MULTI) { + for (Jid jid : jids) { + service.invite(conversation, jid); + } + } else { + jids.add(conversation.getJid().toBareJid()); + service.createAdhocConference(conversation.getAccount(), jids, activity.adhocCallback); + } + } + } + public AvatarService avatarService() { return xmppConnectionService.getAvatarService(); } -- cgit v1.2.3 From 93e620d6858cd713c8895256f3233e9d0bd75d74 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 04:40:57 +0200 Subject: removed debug logging --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 71fb62b5..934c696f 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -672,8 +672,6 @@ public abstract class XmppActivity extends Activity { if (xmppConnectionServiceBound && mPendingConferenceInvite != null) { mPendingConferenceInvite.execute(this); mPendingConferenceInvite = null; - } else { - Log.d(Config.LOGTAG,"putting invite on pending"); } } } -- cgit v1.2.3 From f84ccbe1fa3efe3463f0e18ed98c7124a8b4806b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 11:56:25 +0200 Subject: version bump to 1.4.0-alpha3 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0bde37f5..c47e6ee1 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 63 - versionName "1.4.0-alpha" + versionCode 64 + versionName "1.4.0-alpha3" } compileOptions { -- cgit v1.2.3 From 51aeeb766c5c0ad649abad7777bb5e194a6ae997 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 11:56:59 +0200 Subject: use zero width white space as message seperator --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 217b82bb..a8bb9c55 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -17,7 +17,7 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; - public static final String MERGE_SEPARATOR = "\u2029\n\n"; + public static final String MERGE_SEPARATOR = "\u200B\n\n"; public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; -- cgit v1.2.3 From 6489ddac6c6d3d6eced35ab4640963eb15667bb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 14:33:52 +0200 Subject: clear avatar cache when uploading new avatar --- src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0ed89206..4f2697a3 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1879,6 +1879,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa IqPacket result) { if (result.getType() == IqPacket.TYPE.RESULT) { if (account.setAvatar(avatar.getFilename())) { + getAvatarService().clear(account); databaseBackend.updateAccount(account); } callback.success(avatar); -- cgit v1.2.3 From 82878cded1007331e953908dee11c66557e9ae20 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 16:23:20 +0200 Subject: show location quick action after receiving a question about the users location --- .../conversations/ui/ConversationFragment.java | 5 ++++- .../eu/siacs/conversations/utils/UIHelper.java | 24 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index b6a7dc76..20fc1750 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -59,6 +59,7 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jid.Jid; @@ -905,7 +906,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } else { if (empty) { String setting = activity.getPreferences().getString("quick_action","recent"); - if (setting.equals("recent")) { + if (!setting.equals("none") && UIHelper.receivedLocationQuestion(conversation.getLatestMessage())) { + setting = "location"; + } else if (setting.equals("recent")) { setting = activity.getPreferences().getString("recently_used_quick_action","text"); } switch (setting) { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 9c62dcbf..e289e0e5 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; @@ -26,6 +27,19 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); + private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( + "where are you?", //en + "where r u?", //en + "whats your 20?", //en + "what is your 20?", //en + "what's your 20?", //en + "whats your twenty?", //en + "what is your twenty?", //en + "what's your twenty?", //en + "wo bist du?", //de + "wo sind sie?" //de + )); + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME @@ -234,4 +248,14 @@ public class UIHelper { return counterpart.toString().trim(); } } + + public static boolean receivedLocationQuestion(Message message) { + if (message == null + || message.getStatus() != Message.STATUS_RECEIVED + || message.getType() != Message.TYPE_TEXT) { + return false; + } + String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + return LOCATION_QUESTIONS.contains(body); + } } -- cgit v1.2.3 From 4414cf3b277ec7a0a015e23eab197374f3714da6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 17:10:11 +0200 Subject: ignore question marks in location question --- .../eu/siacs/conversations/utils/UIHelper.java | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index e289e0e5..51984c91 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -28,16 +28,18 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( - "where are you?", //en - "where r u?", //en - "whats your 20?", //en - "what is your 20?", //en - "what's your 20?", //en - "whats your twenty?", //en - "what is your twenty?", //en - "what's your twenty?", //en - "wo bist du?", //de - "wo sind sie?" //de + "where are you", //en + "where r u", //en + "whats your 20", //en + "what is your 20", //en + "what's your 20", //en + "whats your twenty", //en + "what is your twenty", //en + "what's your twenty", //en + "wo bist du", //de + "wo sind sie", //de + "wo seid ihr", //de + "dónde estás" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE @@ -256,6 +258,7 @@ public class UIHelper { return false; } String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } } -- cgit v1.2.3 From 8d472157a4b706ef0c5fc422325f0c1ad47e96bd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 11:57:51 +0200 Subject: always log reason for failed file transfer --- .../conversations/xmpp/jingle/JingleInbandTransport.java | 8 ++++++-- .../conversations/xmpp/jingle/JingleSocks5Transport.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 4e039ad8..29efcf8f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -97,11 +97,13 @@ public class JingleInbandTransport extends JingleTransport { file.createNewFile(); this.fileOutputStream = file.createOutputStream(); if (this.fileOutputStream == null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not create output stream"); callback.onFileTransferAborted(); return; } this.remainingSize = this.fileSize = file.getExpectedSize(); } catch (final NoSuchAlgorithmException | IOException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+" "+e.getMessage()); callback.onFileTransferAborted(); } } @@ -122,6 +124,7 @@ public class JingleInbandTransport extends JingleTransport { this.digest.reset(); fileInputStream = this.file.createInputStream(); if (fileInputStream == null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could no create input stream"); callback.onFileTransferAborted(); return; } @@ -130,6 +133,7 @@ public class JingleInbandTransport extends JingleTransport { } } catch (NoSuchAlgorithmException e) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); } } @@ -182,7 +186,7 @@ public class JingleInbandTransport extends JingleTransport { fileInputStream.close(); } } catch (IOException e) { - Log.d(Config.LOGTAG,e.getMessage()); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); FileBackend.close(fileInputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } @@ -206,7 +210,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { - Log.d(Config.LOGTAG,e.getMessage()); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); FileBackend.close(fileOutputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 72015a05..35375a5d 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.xmpp.jingle; +import android.util.Log; + import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -10,6 +12,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.CryptoHelper; @@ -102,6 +105,7 @@ public class JingleSocks5Transport extends JingleTransport { digest.reset(); fileInputStream = file.createInputStream(); if (fileInputStream == null) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create input stream"); callback.onFileTransferAborted(); return; } @@ -121,10 +125,13 @@ public class JingleSocks5Transport extends JingleTransport { callback.onFileTransmitted(file); } } catch (FileNotFoundException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (IOException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } finally { FileBackend.close(fileInputStream); @@ -150,6 +157,7 @@ public class JingleSocks5Transport extends JingleTransport { fileOutputStream = file.createOutputStream(); if (fileOutputStream == null) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create output stream"); return; } double size = file.getExpectedSize(); @@ -160,6 +168,7 @@ public class JingleSocks5Transport extends JingleTransport { count = inputStream.read(buffer); if (count == -1) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": file ended prematurely with "+remainingSize+" bytes remaining"); return; } else { fileOutputStream.write(buffer, 0, count); @@ -173,10 +182,13 @@ public class JingleSocks5Transport extends JingleTransport { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); callback.onFileTransmitted(file); } catch (FileNotFoundException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (IOException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } finally { FileBackend.close(fileOutputStream); -- cgit v1.2.3 From 8dfa701043d6e442f24edeb4fec48e9d07377a90 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 12:08:43 +0200 Subject: added a few location questions --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 51984c91..2f96a83a 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -29,7 +29,8 @@ public class UIHelper { private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( "where are you", //en - "where r u", //en + "where are you now", //en + "where are you right now", //en "whats your 20", //en "what is your 20", //en "what's your 20", //en @@ -37,9 +38,13 @@ public class UIHelper { "what is your twenty", //en "what's your twenty", //en "wo bist du", //de - "wo sind sie", //de + "wo bist du jetzt", //de + "wo bist du gerade", //de "wo seid ihr", //de - "dónde estás" //es + "wo seid ihr jetzt", //de + "wo seid ihr gerade", //de + "dónde estás", //es + "donde estas" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE -- cgit v1.2.3 From b69ee7125d49493bea86c6e3095f1236ad895980 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 14 May 2015 15:25:52 +0200 Subject: Force Nameprepping of JID domain parts The IDN.toAscii()/IDN.toUnicode() family only namepreps the original domain passed to it if it contained non-ASCII characters. This means that for all-ASCII domains, no canonicalization is performed, which leads to issues like case-sensitivity. This workaround explicitly namepreps domain parts before calling IDN.toAscii() on them, in order to get a canonicalized representation (most notably, case invariance). A basic DB migration is also included. --- .../conversations/persistance/DatabaseBackend.java | 87 +++++++++++++++++++++- .../java/eu/siacs/conversations/xmpp/jid/Jid.java | 13 +++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 28e1c47e..ed88e434 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -4,11 +4,13 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Roster; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import android.content.Context; @@ -16,13 +18,14 @@ import android.database.Cursor; import android.database.sqlite.SQLiteCantOpenDatabaseException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 13; + private static final int DATABASE_VERSION = 14; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -130,6 +133,88 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("delete from "+Contact.TABLENAME); db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); } + if (oldVersion < 14 && newVersion >= 14) { + // migrate db to new, canonicalized JID domainpart representation + + // Conversation table + Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID " + +cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Conversation.UUID)), + }; + db.execSQL("update " + Conversation.TABLENAME + + " set " + Conversation.CONTACTJID + " = ? " + + " where " + Conversation.UUID + " = ?", updateArgs); + } + cursor.close(); + + // Contact table + cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Contact.JID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Contact JID " + +cursor.getString(cursor.getColumnIndex(Contact.JID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Contact.ACCOUNT)), + cursor.getString(cursor.getColumnIndex(Contact.JID)), + }; + db.execSQL("update " + Contact.TABLENAME + + " set " + Contact.JID + " = ? " + + " where " + Contact.ACCOUNT + " = ? " + + " AND " + Contact.JID + " = ?", updateArgs); + } + cursor.close(); + + // Account table + cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newServer; + try { + newServer = Jid.fromParts( + cursor.getString(cursor.getColumnIndex(Account.USERNAME)), + cursor.getString(cursor.getColumnIndex(Account.SERVER)), + "mobile" + ).getDomainpart(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Account SERVER " + +cursor.getString(cursor.getColumnIndex(Account.SERVER)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newServer, + cursor.getString(cursor.getColumnIndex(Account.UUID)), + }; + db.execSQL("update " + Account.TABLENAME + + " set " + Account.SERVER + " = ? " + + " where " + Account.UUID + " = ?", updateArgs); + } + cursor.close(); + } } public static synchronized DatabaseBackend getInstance(Context context) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java index 295e067a..f989c0c2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java @@ -130,12 +130,19 @@ public final class Jid { if (resourcepart.isEmpty() || resourcepart.length() > 1023) { throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH); } - dp = IDN.toUnicode(jid.substring(domainpartStart, slashLoc), IDN.USE_STD3_ASCII_RULES); + try { + dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, slashLoc)), IDN.USE_STD3_ASCII_RULES); + } catch (final StringprepException e) { + throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); + } finaljid = finaljid + dp + "/" + rp; } else { resourcepart = ""; - dp = IDN.toUnicode(jid.substring(domainpartStart, jid.length()), - IDN.USE_STD3_ASCII_RULES); + try{ + dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, jid.length())), IDN.USE_STD3_ASCII_RULES); + } catch (final StringprepException e) { + throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); + } finaljid = finaljid + dp; } -- cgit v1.2.3 From b6a7e56bf667cfc0845ca0d50d88a77c43d9a27d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 13:58:11 +0200 Subject: call StartConversationActivity in init mode only after adding the first account --- src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java | 4 +++- .../java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 7aa7b1c2..931a1a2f 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -223,7 +223,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (avatar != null) { intent = new Intent(getApplicationContext(), StartConversationActivity.class); - intent.putExtra("init",true); + if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { + intent.putExtra("init", true); + } } else { intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index e8ab8dae..4333dbdb 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -116,7 +116,9 @@ public class PublishProfilePictureActivity extends XmppActivity { if (mInitialAccountSetup) { Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class); - intent.putExtra("init",true); + if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { + intent.putExtra("init", true); + } startActivity(intent); } finish(); -- cgit v1.2.3 From 4151b72a6e68faff45e3d166823459eaa07c63a3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 04:12:53 +0200 Subject: let jingle connection and manager handle message status --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 ---- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 4 ++++ .../eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4f2697a3..63d9ba7a 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -349,7 +349,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_FILE); - message.setStatus(Message.STATUS_OFFERED); String path = getFileBackend().getOriginalPath(uri); if (path!=null) { message.setRelativeFilePath(path); @@ -392,7 +391,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_OFFERED); new Thread(new Runnable() { @Override @@ -813,7 +811,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Presences presences = contact.getPresences(); if ((message.getCounterpart() != null) && (presences.has(message.getCounterpart().getResourcepart()))) { - markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } else { if (presences.size() == 1) { @@ -823,7 +820,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } catch (InvalidJidException e) { return; } - markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 4847d5f1..6c42d3d2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -271,6 +271,9 @@ public class JingleConnection implements Downloadable { this.mergeCandidates(JingleCandidate.parse(content.socks5transport() .getChildren())); this.fileOffer = packet.getJingleContent().getFileOffer(); + + mXmppConnectionService.sendIqPacket(account,packet.generateResponse(IqPacket.TYPE.RESULT),null); + if (fileOffer != null) { Element fileSize = fileOffer.findChild("size"); Element fileNameElement = fileOffer.findChild("name"); @@ -381,6 +384,7 @@ public class JingleConnection implements Downloadable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() != IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer"); mJingleStatus = JINGLE_STATUS_INITIATED; mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED); } else { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 5dfa3ff4..c19dd04c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -9,6 +9,7 @@ import android.annotation.SuppressLint; import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; @@ -58,7 +59,12 @@ public class JingleConnectionManager extends AbstractConnectionManager { } public JingleConnection createNewConnection(Message message) { + Downloadable old = message.getDownloadable(); + if (old != null) { + old.cancel(); + } JingleConnection connection = new JingleConnection(this); + mXmppConnectionService.markMessage(message,Message.STATUS_WAITING); connection.init(message); this.connections.add(connection); return connection; -- cgit v1.2.3 From b4a8984b18bed5673284d5fa4a5fcc256386d542 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 10:19:05 +0200 Subject: pulled new translations from transifex --- src/main/res/values-ca/strings.xml | 34 +++- src/main/res/values-pl/strings.xml | 25 +++ src/main/res/values-zh-rCN/strings.xml | 295 +++++++++++++++++++++++++++------ 3 files changed, 302 insertions(+), 52 deletions(-) diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml index a0861b16..9583932b 100644 --- a/src/main/res/values-ca/strings.xml +++ b/src/main/res/values-ca/strings.xml @@ -24,8 +24,8 @@ Escollir un contacte LLista bloqueix Ara - 1 min avans - %de minuts avans + 1 min abans + %de minuts abans Converses sense llegir o no llegides enviant… Desxifrant missatge. Espera si us plau… @@ -359,6 +359,7 @@ No s\'ha pogut canviar la contrasenya Començar a enviar un missatge de conversació xifrat Fer una pregunta + Si vosté i el seu contacte tenen un secret en comú que ningú més sap (com una broma o simplement el que vau dinar l\'última vegada que es van trobar) pot utilitzar aquest secret per comprovar les empremtes de cadascú.\n\nProporcionaràs una pista o una pregunta a la que el seu contacte donarà una resposta, que distingeix entre majúscules i minúscules. El seu contacte l\'hi agradaria verificar la seva empremta digital per un repte amb un secret compartit.El seu contacte proporciona el següent suggeriment o pregunta per aquest secret. El seu suggeriment no pot estar buit El teu secret compartit no pot estar buit @@ -416,4 +417,33 @@ Enviant %s Oferint %s Amaga el fora de línia + Deshabilita el compte + %s està escrivint... + %s ha deixat d\'escriure + Notificacions d\'escriptura + Permet el teu contacte saber quan estàs escrivint un missatge nou + Enviar localització + Mostrar localització + No s\'ha trobat cap aplicació per mostrar la localització + Localització + Localització rebuda + Conversa tancada + S\'ha sortit de la conferència + Opcions de certificats + No confiar en les CAs del sistema + Tots els certificats han de ser aprovats manualment + Eliminar certificats + Esborrar certificats aprovats manualment + No hi ha certificats aprovats manualment + Esborrar certificats + Esborrar selecció + Cancel·lar + + %d certificat esborrat + %d certificats esborrats + + + Seleccionar %d contacte + Seleccionar %d contactes + diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index e1849357..70c3a49d 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -202,6 +202,7 @@ Wiadomość zaszyfrowana. Zainstaluj OpenKeychain, żeby odszyfrować. Nieznany odcisk klucza OTR Znaleziono wiadomości zaszyfrowane przez OpenPGP + Odbiór nieudany Twój odcisk klucza Odcisk klucza OTR Weryfikuj @@ -236,7 +237,9 @@ Serwer odrzucił żądanie publikacji Wystąpił błąd podczas konwersji obrazu Nie udało się zapisać obrazu w pamięci urządzenia + (lub przytrzymaj długo, aby ustawić domyślny) Serwer nie udostępnia możliwości publikacji awatarów + szepcze do %s Wyślij prywatną wiadomość do %s Połącz @@ -252,10 +255,12 @@ Konferencja jest zabezpieczona hasłem Wprowadź hasło Kontakt nie udostępnia powiadomień o obecności + Poproś kontakt o udostępnienie powiadomień o obecności.\n\nPozwoli to na ustalenie klienta, z którego korzysta rozmówca. Zażądaj teraz Usuń odcisk klucza Czy na pewno chcesz usunąć odcisk klucza? Ignoruj + Uwaga: Wysyłanie bez obustronnych powiadomień o obecności może powodować nieoczekiwane problemy.\n\nSprawdź subskrypcję powiadomień w szczegółach kontaktu. Ustawienia szyfrowania Wymuszaj szyfrowanie typu end-to-end Szyfruj wszystkie wiadomości (poza konferencjami) @@ -283,6 +288,7 @@ Zbanowano cię w konferencji To jest zamknięty pokój Wyrzucono cię z konferencji + używając konta %s Sprawdzanie obrazka na hoście HTTP Obraz został usunięty Brak połączenia. Spróbuj ponownie później @@ -302,6 +308,7 @@ Szczegóły konta Weryfikuj OTR Zdalny odcisk klucza + skanuj (lub zetknij telefony) Protokół socialist millionaire Podpowiedź lub pytanie @@ -309,6 +316,7 @@ Potwierdź W toku Odpowiedz + Operacja nieudana Sekrety są niezgodne Spróbuj ponownie Zakończ @@ -382,6 +390,7 @@ Konferencja prywatna, dla zaakceptowanych uczestników Opcje konferencji Prywatna (tylko zaakceptowani) + Nieanonimowa Opcje konferencji zostały zmienione! Nie udało się zmienić opcji konferencji Nigdy @@ -420,7 +429,23 @@ Otrzymano lokalizację Zamknięto konwersację Opuszczono konferencję + Ustawienia certyfikatów Nie ufaj certyfikatom systemowym Wymagaj ręcznego potwierdzania certyfikatów + Usuń certyfikat + Wybierz zaufane certyfikaty do usunięcia + Brak ręcznie zaufanych certyfikatów + Usuń certyfikaty + Usuń zaznaczone Anuluj + + Usunięto %d certyfikat + Usunięto %d certyfikaty + Usunięto %d certyfikatów + + + %d kontakt wybrany + %d kontakty wybrane + %d kontaktów wybranych + diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 49ca9b97..2f80e064 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -11,6 +11,10 @@ 编辑姓名 添加到手机通讯录 从列表中删除 + 屏蔽联系人 + 解除联系人屏蔽 + 屏蔽域名 + 解除域名屏蔽 管理账户 设置 讨论组详情 @@ -18,6 +22,7 @@ 分享会话 开始会话 选择联系人 + 屏蔽列表 刚刚 1 分钟前 %d分钟前 @@ -30,56 +35,65 @@ 版主 参与者 访客 - 将 %s从列表中移除? 与该联系人的会话消息不会清除. - 从书签中移除 %s?相关会话消息不会被清除 . + 将 %s 从列表中移除? 与该联系人的会话消息不会清除. + 你想屏蔽 %s 将不能发送信息给你? + 你想解除对 %s 的屏蔽吗,他们将可以发送信息给你? + 屏蔽 %s 中的所有联系人? + 解除对 %s 中所有联系人的屏蔽? + 联系人已屏蔽 + 从书签中移除 %s ?相关会话消息不会被清除 . 在服务器上注册新账户 + 在服务器上改变密码 分享 开始会话 邀请联系人 联系人 取消 + 设置 添加 编辑 删除 + 屏蔽 + 解除屏蔽 保存 完成 - Conversations停止运行 - 发送堆栈跟踪到正在开发Conversations的人员\n警告: 该操作将用您的 XMPP账户发送堆栈跟踪到开发人员. + Conversations 崩溃 + 发送堆栈跟踪信息到 Conversations 的开发人员\n警告: 该操作将用您的 XMPP 账户发送堆栈跟踪给开发人员。 现在发送 不再询问 无法连接至账户 无法连接至多个账户 点击此处管理账户 - 附件 - 该联系人不在您的列表.需要加为联系人吗 ? + 附加文件 + 该联系人不在您的列表。需要加为联系人吗 ? 添加联系人 传递失败 拒绝 准备传输图像 清除历史记录 清除会话记录 - 删除该会话中所有信息?\n\n注: 该操作不会影响其他设备或服务器保存的信息. + 删除该会话中所有信息?\n\n注: 该操作不会影响其他设备或服务器保存的信息。 删除消息 之后结束该会话 添加在线用户至联系人 发送纯文本信息 发送 OTR 加密信息 发送 OpenPGP 加密信息 - 用户名修改成功 + 昵称修改成功 下载图片 不加密发送 - 解密失败,可能是私钥不正确. + 解密失败,可能是私钥不正确。 OpenKeychain - 会话运用了第三方app,名为 OpenKeychain 用来加密、解码信息以及管理您的公钥.\n\nOpenKeychain 遵循 GPLv3 并且在 F-Droid和Google Play上可操作.\n\n(之后请重启conversations.) + 会话运用了第三方app,名为 OpenKeychain 用来加密、解密信息以及管理您的密钥。\n\nOpenKeychain 遵循 GPLv3 并且可以在 F-Droid 和 Google Play 上获取。\n\n(之后请重启 conversations) 重启 安装 输入… 等待… - 未发现OpenPGP 密码 - 会话加密信息失败,因为联系人未告知他/她的公钥.\n\n请通知联系人设置 OpenPGP. - 未找到 OpenPGP 密码 + 未发现 OpenPGP 密钥 + 会话加密信息失败,因为联系人未提供他/她的公钥。\n\n请通知联系人设置 OpenPGP。 + 未找到 OpenPGP 密钥 因您的联系人未公布公钥,Conversations未能成功加密您的信息.\n\n请通知联系人设置OpenPGP. - 加密信息已接收.点击进行解密和查看. + 加密信息已接收。点击解密并查看。 常规 XMPP 资源 客户端标识名称 @@ -91,41 +105,41 @@ 震动 收到新消息时震动 声音 - 收到新消息时播放铃声 + 收到新消息时的铃声 讨论组通知 当有新的消息时总是通知而不是亮屏时才通知 通知限期 接收副本短时间内关闭通知 高级选项 - 总不发送故障报告 - 发送堆栈跟踪帮助Conversations开发人员 + 总不发送崩溃报告 + 发送堆栈跟踪帮助 Conversations 开发人员 确认消息 当你已收到消息并且已阅时通知好友 - UI选项 + UI 选项 OpenKeychain 报告了一个错误 - 解码文件时出现I/O错误 + 解密文件时出现 I/O 错误 接受 产生了一个错误 同意更新在线联系人 - 预先同意并请求您的联系人进行更新 + 预先同意并请求更新您的联系人 关注 你的账号 - Keys - 发送在线联系人更新列表 - 接收在线联系人更新列表 - 请求在线联系人更新列表 + 密钥 + 发送在线联系人列表更新 + 接收在线联系人列表更新 + 请求在线联系人列表更新 选择图片 照相 预先同意订阅请求 您选择的文件不是图像文件 转换图像出错 未找到文件 - 常规的I/O错误.可能是存储空间不足的原因? - 您用来选择图片的app没有给予足够权限支持我们读取文件.\n\n请使用另一文件管理器选择图片 + 常规的 I/O 错误。可能是存储空间不足? + 您用来选择图片的 app 没有给予足够权限支持我们读取文件。\n\n请使用另一文件管理器选择图片 未知 暂时不可用 在线 - Connecting\u2026 + 连接中\u2026 离线 未授权 未找到服务器 @@ -134,6 +148,8 @@ 用户名已存在 注册完成 服务器不支持注册 + 安全错误 + 服务器不兼容 纯文本内容 OTR OpenPGP @@ -141,11 +157,11 @@ 删除账号 暂时不可用 发布头像 - 发布 OpenPGP 公共秘钥 + 发布 OpenPGP 公钥 启用账户 确定? 如果删除用户,所有会话信息将会丢失 - Record voice 录音 + 录音 Jabber ID 密码 username@example.com @@ -153,23 +169,28 @@ 密码 确认密码 密码不一致 - 该Jabber ID 无效 - 空间不足,图片过大 + 该 Jabber ID 无效 + 空间不足。图片过大 您将添加 %s 至手机联系人列表? 在线 - 免费对话 + 自由畅聊 离开 长时间离开 请勿打扰 离线 讨论组 其他成员 + 服务器信息 + XEP-0313: MAM XEP-0280: 消息碳 + XEP-0352: 客户端状态指示 + XEP-0191: 屏蔽指令 + XEP-0237: 花名册版本 XEP-0198: 流管理 XEP-0163: PEP (头像) 有效 无效 - 缺少公共秘钥公告 + 缺少公钥通知 最近一次查看为刚刚 最近一次查看为一分钟前 最近一次查看为 %d 分钟前 @@ -178,9 +199,9 @@ 最近一次查看为一天前 最近一次查看为 %d天前 未曾查看 - 加密信息. 请安装OpenKeychain进行解码. - 未知 OTR指纹 - OpenPGP 发现加密信息 + 加密信息. 请安装 OpenKeychain 以解密。 + 未知 OTR 指纹 + 发现 OpenPGP 加密信息 接收失败 你的指纹 OTR 指纹 @@ -192,6 +213,8 @@ 加入讨论组 删除联系人 查看联系人详细信息 + 屏蔽联系人 + 解除联系人屏蔽 创建 联系人已存在 加入 @@ -200,26 +223,26 @@ 保存为书签 删除书签 该书签已存在 - 你的 + 编辑讨论组主题 讨论组未找到 离开 联系人已添加你到联系人列表 反向添加 - 目前读到%s 处 + 目前读到 %s 处 发布 - 点击头像可选择头像 - 请注意: 所有关注您最新动态的人将看到该图像. - 发布… + 点击头像可从相册中选择头像 + 请注意: 所有关注您最新动态的人将看到该图像。 + 正在发布… 服务器拒绝了您的发布请求 - 转换头像出错 - 不能将头像保存至disk + 转换头像图片出错 + 不能将头像保存至磁盘 (或长按按钮将返回默认头像) 您的服务器不支持发布头像 密谈 至 %s - 发送私密消息到%s - Connect + 发送私密消息到 %s + 连接 该账号已存在 下一步 当前会话已建立 @@ -232,21 +255,193 @@ 讨论组设有密码 输入密码 缺少在线联系人更新 - 请先发送更新在线联系人请求.\n\n这将用来判断您的联系人所用的客户端类型人. + 请先发送更新在线联系人的请求。\n\n以判断您的联系人所用的客户端类型。 现在发送请求 删除指纹 是否确定删除该指纹? 忽略 - 警告:在没有相互更新在线联系人的情况下发送将会出现未知问题.\n\n到联系人详情确认您订阅的在线联系人. + 警告:在没有相互更新在线联系人的情况下发送将会出现未知问题。\n\n前往联系人详情以验证您订阅的在线联系人。 加密设置 - 强制要求 end-to-end 加密 + 强制要求端对端加密 总是发送加密信息(讨论组信息除外) 不保存加密信息 警告:此操作将会导致信息丢失 - Expert 选项 + 导出选项 请谨慎使用 + 关于 Conversations + 构建及许可证信息 + 静默时间段 + 开始时间 + 结束时间 + 启用静默时间段 + 在静默时间段内通知将保持静音 放大字体 - 整个app界面使用更大号的字体 + 整个 app 界面使用较大的字体 发送按钮显示状态 + 请求消息回复 + 如果支持消息将会以绿色对勾标识 发送按钮采用其他颜色以示发送状态的区别 + 其他 + 讨论组名称 + 用讨论组的主题来标示讨论组而不是 JID + OTR 指纹已拷贝到剪贴板! + 你被此讨论组屏蔽 + 此讨论组只允许成员加入 + 你被从此讨论组踢出 + 用账户 %s + 正在 HTTP 托管中检查图片 + 此图片已经被删除 + 你没有连接。请稍后重试 + 检查图片文件尺寸 + 消息选项 + 拷贝文本 + 拷贝原始URL + 再次发送 + 图片 URL + 消息文本 + 已经拷贝 URL 到剪贴板 + 消息已经拷贝到剪贴板 + 图片传送失败 + 扫描二维码 + 显示二维码 + 显示屏蔽列表 + 账户详情 + 验证 OTR + 远程指纹 + 扫描 + (或轻触手机) + Socialist Millionaire Protocol + 提示或问题 + 共知的秘密 + 确认 + 处理中 + 回应 + 失败 + 秘密不符 + 再试一遍 + 完成 + 验证通过! + 联系人请求 SMP 验证 + 没有找到 OTR 会话 + Conversations + 保持前台服务 + 防止操作系统中断你的连接 + 关闭文件 + 接收中 %1$s (已完成 %2$d%%) + 下载 %s + 文件 + 打开 %s + 发送中 (已完成 %1$d%%) + 准备传送文件 + 可以下载 %s + 取消传送 + 文件传送失败 + 文件已经删除 + 没有可以打开此文件的应用 + 不能验证指纹 + 手工验证 + 你确认验证你的联系人的 OTR 指纹? + 现实动态标签 + 在联系人下方显示只读标签 + 启用通知 + 与…创建讨论组 + 无法找到讨论组服务器 + 讨论组创建失败! + 讨论组已创建! + 秘密被接受! + 重置 + 账户头像 + 拷贝 OTR 指纹到剪贴板 + 从服务器获取历史记录 + 服务器上没有更多历史记录 + 更新中… + 密码已修改! + 不能修改密码 + 要启动加密聊天先发送一条消息 + 提出问题 + 如果你和你的联系人有一个共知的秘密(比如一个内部笑话或者仅仅只是上次见面时吃的午餐) 你可以使用这个秘密来验证彼此的指纹。\n\n你的联系人将以大小写敏感的方式给出答案,你可以给出提示或问题。 + 你的联系人可以通过一个你们共知的秘密来验证指纹。你的联系人给出了如下的提示或问题。 + 你的提示不能为空 + 你共知的秘密不能为空 + 请仔细核对下面显示出来的你的联系人的指纹。\n你可以使用任何可信赖的联系方式,比如加密邮件或电话,来交换这些指纹信息。 + 修改密码 + 当前密码 + 新密码 + 密码不能为空 + 启用所有账户 + 禁用所有账户 + 做一个动作和 + 没有从属关系 + 没有角色 + 抛弃 + 成员 + 高级模式 + 已授予的成员 + 吊销的成员 + 授予管理员权限 + 吊销管理员权限 + 从讨论组移出 + 不能修改 %s 的从属关系 + 屏蔽出讨论组 + 你正尝试将 %s 移出一个公共的讨论组。唯一的方式是永远屏蔽这个用户 + 现在屏蔽 + 不能修改 %s 的角色 + 公开访问的讨论组 + 私密,只有成员可以加入的讨论组 + 讨论组选项 + 私密(只对成员开放) + 非匿名 + 讨论组选项已修改! + 不能修改讨论组选项 + 从不 + 30 分钟 + 1 个小时 + 2 个小时 + 8 个小时 + 直到新的通知 + 输入选项 + 回车是发送 + 用回车键来发送消息 + 显示回车键 + 改变表情键为回车键 + 音频 + 视频 + 图像 + PDF 文档 + Android App + 联系人 + 已经收到 %s + 禁用前端服务 + 轻触打开 Conversations + 头像已经发布! + 发送中 %s + 提供中 %s + 隐藏离线联系人 + 禁用账户 + %s 正在输入… + %s 已停止输入 + 键盘输入通知 + 让对方知道你正在输入新消息 + 发送位置 + 显示位置 + 无法找到显示位置的应用 + 位置 + 位置已收到 + Conversation 已关闭 + 离开讨论组 + 证书选项 + 不相信系统 CA + 所有证书必须人工通过 + 移除证书 + 删除人工通过的证书 + 没有人工通过的证书 + 移除证书 + 删除选项 + 取消 + + %d 个证书已被删除 + + + 选择 %d 个联系人 + -- cgit v1.2.3 From 7ccdc772edccb2cd71150441cf21dbcab7e6e7d9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 10:19:19 +0200 Subject: version bump to 1.4.0-beta --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c47e6ee1..595ff0ee 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 64 - versionName "1.4.0-alpha3" + versionCode 65 + versionName "1.4.0-beta" } compileOptions { -- cgit v1.2.3 From fce30f22c9c75fb4bc12992e6d7e7161ce5148b1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 12:49:04 +0200 Subject: made white space check in bodyContainsDownloadable less aggresive --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index a8bb9c55..38152edb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -440,7 +440,7 @@ public class Message extends AbstractEntity { * "http://example.com/image.jpg text that will not be shown /abc.png" * or more than one image link in one message. */ - if (body.contains(" ")) { + if (body.trim().contains(" ")) { return false; } try { -- cgit v1.2.3 From d672d578c91f54e17b930c4a08d133095a863d52 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 17 May 2015 12:32:04 +0200 Subject: fixed crash on failed account registry --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 6c67c072..b0d8272d 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -683,7 +683,7 @@ public class XmppConnection implements Runnable { disconnect(true); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not register. instructions are" - + instructions != null ? instructions.getContent() : ""); + + (instructions != null ? instructions.getContent() : "")); } } }); -- cgit v1.2.3 From 34545aa96fc3148d7fb038109c99841ee4d16690 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 08:36:37 +0200 Subject: added changelog for upcoming 1.4.0 release --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae267086..61980b61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ###Changelog +####Version 1.4.0 +* send button turns into quick action button to offer faster access to take photo, send location or record audio +* visually seperate merged messages +* faster reconnects of failed accounts after network switches +* r/o vcard avatars for contacts +* various bug fixes + ####Version 1.3.0 * swipe conversations to end them * quickly enable / disable account via slider -- cgit v1.2.3 From fbc43a8d38e62fc2a3b60e7c363c8fe1e2668cc6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 03:17:14 +0200 Subject: don't offer initiator his own candidates --- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 6c42d3d2..c9bb9c93 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -213,7 +213,7 @@ public class JingleConnection implements Downloadable { @Override public void onPrimaryCandidateFound(boolean success, - final JingleCandidate candidate) { + final JingleCandidate candidate) { if (success) { final JingleSocks5Transport socksConnection = new JingleSocks5Transport( JingleConnection.this, candidate); @@ -399,7 +399,9 @@ public class JingleConnection implements Downloadable { private List getCandidatesAsElements() { List elements = new ArrayList<>(); for (JingleCandidate c : this.candidates) { - elements.add(c.toElement()); + if (c.isOurs()) { + elements.add(c.toElement()); + } } return elements; } -- cgit v1.2.3 From 1446a59fa594be49277d1ec9d7fe023949bcfc55 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 04:34:34 +0200 Subject: use a 20s timeout on socks5 connections --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 9f5d14fd..050116b5 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -11,6 +11,7 @@ public final class Config { public static final int PING_MAX_INTERVAL = 300; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 10; + public static final int SOCKET_TIMEOUT = 20; public static final int CONNECT_TIMEOUT = 90; public static final int CARBON_GRACE_PERIOD = 60; public static final int MINI_GRACE_PERIOD = 750; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 35375a5d..8d74f44e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -6,7 +6,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -56,8 +58,9 @@ public class JingleSocks5Transport extends JingleTransport { @Override public void run() { try { - socket = new Socket(candidate.getHost(), - candidate.getPort()); + socket = new Socket(); + SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort()); + socket.connect(address,Config.SOCKET_TIMEOUT * 1000); inputStream = socket.getInputStream(); outputStream = socket.getOutputStream(); byte[] login = { 0x05, 0x01, 0x00 }; -- cgit v1.2.3 From a0575c81abf9b8b56a3b47753b373218a655c608 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 08:48:08 +0200 Subject: use same socket time out for jingle and xmpp connections --- src/main/java/eu/siacs/conversations/Config.java | 2 +- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 050116b5..779cbbe8 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -11,7 +11,7 @@ public final class Config { public static final int PING_MAX_INTERVAL = 300; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 10; - public static final int SOCKET_TIMEOUT = 20; + public static final int SOCKET_TIMEOUT = 15; public static final int CONNECT_TIMEOUT = 90; public static final int CARBON_GRACE_PERIOD = 60; public static final int MINI_GRACE_PERIOD = 750; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index b0d8272d..9bda3c09 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -187,7 +187,7 @@ public class XmppConnection implements Runnable { + srvRecordServer + ":" + srvRecordPort); } socket = new Socket(); - socket.connect(addr, 20000); + socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); socketError = false; } catch (final UnknownHostException e) { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); -- cgit v1.2.3 From bb603644880f0b32d8a7b54d5158f6fac678aa12 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 19 May 2015 08:31:56 +0200 Subject: hide block contact from context menu when server feature is not available fixed #1207 --- .../java/eu/siacs/conversations/ui/StartConversationActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index a556b8b7..7863ff94 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -65,6 +65,7 @@ import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.ListItemAdapter; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -757,14 +758,16 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } else { activity.contact_context_id = acmi.position; final Blockable contact = (Contact) activity.contacts.get(acmi.position); - final MenuItem blockUnblockItem = menu.findItem(R.id.context_contact_block_unblock); - if (blockUnblockItem != null) { + XmppConnection xmpp = contact.getAccount().getXmppConnection(); + if (xmpp != null && xmpp.getFeatures().blocking()) { if (contact.isBlocked()) { blockUnblockItem.setTitle(R.string.unblock_contact); } else { blockUnblockItem.setTitle(R.string.block_contact); } + } else { + blockUnblockItem.setVisible(false); } } } -- cgit v1.2.3 From 73a4ffefdf470be517eb32bc43bb93c3dff72b38 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 03:27:52 +0200 Subject: added fall back package id for voice recorder plugin --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a2a405c3..1b5e5178 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -429,6 +429,7 @@ public class ConversationActivity extends XmppActivity break; case ATTACHMENT_CHOICE_RECORD_VOICE: intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + fallbackPackageId = "eu.siacs.conversations.voicerecorder"; break; case ATTACHMENT_CHOICE_LOCATION: intent.setAction("eu.siacs.conversations.location.request"); -- cgit v1.2.3 From 7824c01748a89688c5f76307cc1f4221a9e2ffb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 03:36:10 +0200 Subject: version bump to 1.4.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 595ff0ee..98b341d5 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 65 - versionName "1.4.0-beta" + versionCode 66 + versionName "1.4.0" } compileOptions { -- cgit v1.2.3 From e32f380dae4913d8152fc92b76193de241089cf8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 14:42:21 +0200 Subject: provide helper function for getting the content of a child directly --- .../eu/siacs/conversations/entities/Bookmark.java | 14 ++----------- .../siacs/conversations/parser/AbstractParser.java | 6 +----- .../services/XmppConnectionService.java | 3 +-- .../java/eu/siacs/conversations/xml/Element.java | 10 ++++++++++ .../eu/siacs/conversations/xmpp/pep/Avatar.java | 3 +-- .../conversations/xmpp/stanzas/MessagePacket.java | 23 ++++++++++++++++++++++ 6 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Bookmark.java b/src/main/java/eu/siacs/conversations/entities/Bookmark.java index f81f1a87..cc6f146b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Bookmark.java +++ b/src/main/java/eu/siacs/conversations/entities/Bookmark.java @@ -75,12 +75,7 @@ public class Bookmark extends Element implements ListItem { } public String getNick() { - Element nick = this.findChild("nick"); - if (nick != null) { - return nick.getContent(); - } else { - return null; - } + return this.findChildContent("nick"); } public void setNick(String nick) { @@ -96,12 +91,7 @@ public class Bookmark extends Element implements ListItem { } public String getPassword() { - Element password = this.findChild("password"); - if (password != null) { - return password.getContent(); - } else { - return null; - } + return this.findChildContent("password"); } public void setPassword(String password) { diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index bfe84440..6f73f24d 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -70,10 +70,6 @@ public abstract class AbstractParser { if (item == null) { return null; } - Element data = item.findChild("data", "urn:xmpp:avatar:data"); - if (data == null) { - return null; - } - return data.getContent(); + return item.findChildContent("data", "urn:xmpp:avatar:data"); } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 63d9ba7a..3a74b82b 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1994,8 +1994,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (packet.getType() == IqPacket.TYPE.RESULT) { Element vCard = packet.findChild("vCard","vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; - Element binval = photo != null ? photo.findChild("BINVAL") : null; - String image = binval != null ? binval.getContent() : null; + String image = photo != null ? photo.findChildContent("BINVAL") : null; if (image != null) { avatar.image = image; if (getFileBackend().save(avatar)) { diff --git a/src/main/java/eu/siacs/conversations/xml/Element.java b/src/main/java/eu/siacs/conversations/xml/Element.java index 51708759..32657c66 100644 --- a/src/main/java/eu/siacs/conversations/xml/Element.java +++ b/src/main/java/eu/siacs/conversations/xml/Element.java @@ -57,6 +57,11 @@ public class Element { return null; } + public String findChildContent(String name) { + Element element = findChild(name); + return element == null ? null : element.getContent(); + } + public Element findChild(String name, String xmlns) { for (Element child : this.children) { if (child.getName().equals(name) @@ -67,6 +72,11 @@ public class Element { return null; } + public String findChildContent(String name, String xmlns) { + Element element = findChild(name,xmlns); + return element == null ? null : element.getContent(); + } + public boolean hasChild(final String name) { return findChild(name) != null; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java index 04d55bbe..74da6a9b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java +++ b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java @@ -83,8 +83,7 @@ public class Avatar { } public static Avatar parsePresence(Element x) { - Element photo = x != null ? x.findChild("photo") : null; - String hash = photo != null ? photo.getContent() : null; + String hash = x == null ? null : x.findChildContent("photo"); if (hash == null) { return null; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java index 93aaa68c..11c3452b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java @@ -66,4 +66,27 @@ public class MessagePacket extends AbstractStanza { return TYPE_NORMAL; } } + + public MessagePacket getForwardedMessagePacket(String name, String namespace) { + Element wrapper = findChild(name, namespace); + if (wrapper == null) { + return null; + } + Element forwarded = wrapper.findChild("forwarded","urn:xmpp:forward:0"); + if (forwarded == null) { + return null; + } + return MessagePacket.create(forwarded.findChild("message")); + } + + + public static MessagePacket create(Element element) { + if (element == null) { + return null; + } + MessagePacket packet = new MessagePacket(); + packet.setAttributes(element.getAttributes()); + packet.setChildren(element.getChildren()); + return packet; + } } -- cgit v1.2.3 From d261feda74ac3bd42d633d83264b14696276ade6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 05:14:15 +0200 Subject: rewrote parser code. mam id and possible other stuff still missing. also massivly untested --- .../siacs/conversations/parser/AbstractParser.java | 41 +- .../siacs/conversations/parser/MessageParser.java | 665 ++++++--------------- .../conversations/xmpp/stanzas/AbstractStanza.java | 4 + .../conversations/xmpp/stanzas/MessagePacket.java | 24 +- 4 files changed, 230 insertions(+), 504 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 6f73f24d..7b3eb7e9 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -11,6 +11,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public abstract class AbstractParser { @@ -20,22 +21,23 @@ public abstract class AbstractParser { this.mXmppConnectionService = service; } - protected long getTimestamp(Element packet) { - long now = System.currentTimeMillis(); - Element delay = packet.findChild("delay"); - if (delay == null) { - return now; - } - String stamp = delay.getAttribute("stamp"); - if (stamp == null) { - return now; - } - try { - long time = parseTimestamp(stamp).getTime(); - return now < time ? now : time; - } catch (ParseException e) { - return now; + public static Long getTimestamp(Element element, Long defaultValue) { + Element delay = element.findChild("delay"); + if (delay != null) { + String stamp = delay.getAttribute("stamp"); + if (stamp != null) { + try { + return AbstractParser.parseTimestamp(delay.getAttribute("stamp")).getTime(); + } catch (ParseException e) { + return defaultValue; + } + } } + return defaultValue; + } + + protected long getTimestamp(Element packet) { + return getTimestamp(packet,System.currentTimeMillis()); } public static Date parseTimestamp(String timestamp) throws ParseException { @@ -46,14 +48,11 @@ public abstract class AbstractParser { return dateFormat.parse(timestamp); } - protected void updateLastseen(final Element packet, final Account account, - final boolean presenceOverwrite) { - final Jid from = packet.getAttributeAsJid("from"); - updateLastseen(packet, account, from, presenceOverwrite); + protected void updateLastseen(final Element packet, final Account account, final boolean presenceOverwrite) { + updateLastseen(packet, account, packet.getAttributeAsJid("from"), presenceOverwrite); } - protected void updateLastseen(final Element packet, final Account account, final Jid from, - final boolean presenceOverwrite) { + protected void updateLastseen(final Element packet, final Account account, final Jid from, final boolean presenceOverwrite) { final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart(); final Contact contact = account.getRoster().getContact(from); final long timestamp = getTimestamp(packet); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 7870fdbf..5a2fcbe1 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -1,8 +1,12 @@ package eu.siacs.conversations.parser; +import android.util.Log; +import android.util.Pair; + import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -25,12 +29,12 @@ public class MessageParser extends AbstractParser implements super(service); } - private boolean extractChatState(Conversation conversation, final Element element) { - ChatState state = ChatState.parse(element); + private boolean extractChatState(Conversation conversation, final MessagePacket packet) { + ChatState state = ChatState.parse(packet); if (state != null && conversation != null) { final Account account = conversation.getAccount(); - Jid from = element.getAttributeAsJid("from"); - if (from != null && from.toBareJid().equals(account.getJid().toBareJid())) { + Jid from = packet.getFrom(); + if (from.toBareJid().equals(account.getJid().toBareJid())) { conversation.setOutgoingChatState(state); return false; } else { @@ -40,86 +44,27 @@ public class MessageParser extends AbstractParser implements return false; } - private Message parseChat(MessagePacket packet, Account account) { - final Jid jid = packet.getFrom(); - if (jid == null) { - return null; - } - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid.toBareJid(), false); - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, - pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECEIVED); - } else { - finishedMessage = new Message(conversation, - packet.getBody(), Message.ENCRYPTION_NONE, - Message.STATUS_RECEIVED); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - if (conversation.getMode() == Conversation.MODE_MULTI - && !jid.isBareJid()) { - final Jid trueCounterpart = conversation.getMucOptions() - .getTrueCounterpart(jid.getResourcepart()); - if (trueCounterpart != null) { - updateLastseen(packet, account, trueCounterpart, false); - } - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setTrueCounterpart(trueCounterpart); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - } else { - updateLastseen(packet, account, true); - } - finishedMessage.setCounterpart(jid); - finishedMessage.setTime(getTimestamp(packet)); - extractChatState(conversation,packet); - return finishedMessage; - } - - private Message parseOtrChat(MessagePacket packet, Account account) { - final Jid to = packet.getTo(); - final Jid from = packet.getFrom(); - if (to == null || from == null) { - return null; - } - boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, from.toBareJid(), false); + private Message parseOtrChat(String body, Jid from, String id, Conversation conversation) { String presence; if (from.isBareJid()) { presence = ""; } else { presence = from.getResourcepart(); } - extractChatState(conversation, packet); - updateLastseen(packet, account, true); - String body = packet.getBody(); if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) { conversation.endOtrIfNeeded(); } if (!conversation.hasValidOtrSession()) { - if (properlyAddressed) { - conversation.startOtrSession(presence,false); - } else { - return null; - } + conversation.startOtrSession(presence,false); } else { - String foreignPresence = conversation.getOtrSession() - .getSessionID().getUserID(); + String foreignPresence = conversation.getOtrSession().getSessionID().getUserID(); if (!foreignPresence.equals(presence)) { conversation.endOtrIfNeeded(); - if (properlyAddressed) { - conversation.startOtrSession(presence, false); - } else { - return null; - } + conversation.startOtrSession(presence, false); } } try { - conversation.setLastReceivedOtrMessageId(packet.getId()); + conversation.setLastReceivedOtrMessageId(id); Session otrSession = conversation.getOtrSession(); SessionStatus before = otrSession.getSessionStatus(); body = otrSession.transformReceiving(body); @@ -140,12 +85,7 @@ public class MessageParser extends AbstractParser implements conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); return null; } - Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, - Message.STATUS_RECEIVED); - finishedMessage.setTime(getTimestamp(packet)); - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - finishedMessage.setCounterpart(from); + Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED); conversation.setLastReceivedOtrMessageId(null); return finishedMessage; } catch (Exception e) { @@ -154,293 +94,6 @@ public class MessageParser extends AbstractParser implements } } - private Message parseGroupchat(MessagePacket packet, Account account) { - int status; - final Jid from = packet.getFrom(); - if (from == null) { - return null; - } - if (mXmppConnectionService.find(account.pendingConferenceLeaves, - account, from.toBareJid()) != null) { - return null; - } - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, from.toBareJid(), true); - final Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(from.getResourcepart()); - if (trueCounterpart != null) { - updateLastseen(packet, account, trueCounterpart, false); - } - if (packet.hasChild("subject")) { - conversation.setHasMessagesLeftOnServer(true); - conversation.getMucOptions().setSubject(packet.findChild("subject").getContent()); - mXmppConnectionService.updateConversationUi(); - return null; - } - - final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); - if (from.isBareJid() && (x == null || !x.hasChild("status"))) { - return null; - } else if (from.isBareJid() && x.hasChild("status")) { - for(Element child : x.getChildren()) { - if (child.getName().equals("status")) { - String code = child.getAttribute("code"); - if (code.contains(MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED)) { - mXmppConnectionService.fetchConferenceConfiguration(conversation); - } - } - } - return null; - } - - if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { - if (mXmppConnectionService.markMessage(conversation, - packet.getId(), Message.STATUS_SEND_RECEIVED)) { - return null; - } else if (packet.getId() == null) { - Message message = conversation.findSentMessageWithBody(packet.getBody()); - if (message != null) { - mXmppConnectionService.markMessage(message,Message.STATUS_SEND_RECEIVED); - return null; - } else { - status = Message.STATUS_SEND; - } - } else { - status = Message.STATUS_SEND; - } - } else { - status = Message.STATUS_RECEIVED; - } - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody == null) { - finishedMessage = new Message(conversation, - packet.getBody(), Message.ENCRYPTION_NONE, status); - } else { - finishedMessage = new Message(conversation, pgpBody, - Message.ENCRYPTION_PGP, status); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - finishedMessage.setCounterpart(from); - if (status == Message.STATUS_RECEIVED) { - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(from.getResourcepart())); - } - if (packet.hasChild("delay") - && conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - finishedMessage.setTime(getTimestamp(packet)); - return finishedMessage; - } - - private Message parseCarbonMessage(final MessagePacket packet, final Account account) { - int status; - final Jid fullJid; - Element forwarded; - if (packet.hasChild("received", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("received", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_RECEIVED; - } else if (packet.hasChild("sent", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("sent", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_SEND; - } else { - return null; - } - if (forwarded == null) { - return null; - } - Element message = forwarded.findChild("message"); - if (message == null) { - return null; - } - if (!message.hasChild("body")) { - if (status == Message.STATUS_RECEIVED - && message.getAttribute("from") != null) { - parseNonMessage(message, account); - } else if (status == Message.STATUS_SEND - && message.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - final Jid to = message.getAttributeAsJid("to"); - if (to != null) { - final Conversation conversation = mXmppConnectionService.find( - mXmppConnectionService.getConversations(), account, - to.toBareJid()); - if (conversation != null) { - mXmppConnectionService.markRead(conversation); - } - } - } - return null; - } - if (status == Message.STATUS_RECEIVED) { - fullJid = message.getAttributeAsJid("from"); - if (fullJid == null) { - return null; - } else { - updateLastseen(message, account, true); - } - } else { - fullJid = message.getAttributeAsJid("to"); - if (fullJid == null) { - return null; - } - } - if (message.hasChild("x","http://jabber.org/protocol/muc#user") - && "chat".equals(message.getAttribute("type"))) { - return null; - } - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, fullJid.toBareJid(), false); - String pgpBody = getPgpBody(message); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, pgpBody, - Message.ENCRYPTION_PGP, status); - } else { - String body = message.findChild("body").getContent(); - finishedMessage = new Message(conversation, body, - Message.ENCRYPTION_NONE, status); - } - extractChatState(conversation,message); - finishedMessage.setTime(getTimestamp(message)); - finishedMessage.setRemoteMsgId(message.getAttribute("id")); - finishedMessage.markable = isMarkable(message); - finishedMessage.setCounterpart(fullJid); - if (conversation.getMode() == Conversation.MODE_MULTI - && !fullJid.isBareJid()) { - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(fullJid.getResourcepart())); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - } - return finishedMessage; - } - - private Message parseMamMessage(MessagePacket packet, final Account account) { - final Element result = packet.findChild("result","urn:xmpp:mam:0"); - if (result == null ) { - return null; - } - final MessageArchiveService.Query query = this.mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); - if (query!=null) { - query.incrementTotalCount(); - } - final Element forwarded = result.findChild("forwarded","urn:xmpp:forward:0"); - if (forwarded == null) { - return null; - } - final Element message = forwarded.findChild("message"); - if (message == null) { - return null; - } - final Element body = message.findChild("body"); - if (body == null || message.hasChild("private","urn:xmpp:carbons:2") || message.hasChild("no-copy","urn:xmpp:hints")) { - return null; - } - int encryption; - String content = getPgpBody(message); - if (content != null) { - encryption = Message.ENCRYPTION_PGP; - } else { - encryption = Message.ENCRYPTION_NONE; - content = body.getContent(); - } - if (content == null) { - return null; - } - final long timestamp = getTimestamp(forwarded); - final Jid to = message.getAttributeAsJid("to"); - final Jid from = message.getAttributeAsJid("from"); - Jid counterpart; - int status; - Conversation conversation; - if (from!=null && to != null && from.toBareJid().equals(account.getJid().toBareJid())) { - status = Message.STATUS_SEND; - conversation = this.mXmppConnectionService.findOrCreateConversation(account,to.toBareJid(),false,query); - counterpart = to; - } else if (from !=null && to != null) { - status = Message.STATUS_RECEIVED; - conversation = this.mXmppConnectionService.findOrCreateConversation(account,from.toBareJid(),false,query); - counterpart = from; - } else { - return null; - } - Message finishedMessage = new Message(conversation,content,encryption,status); - finishedMessage.setTime(timestamp); - finishedMessage.setCounterpart(counterpart); - finishedMessage.setRemoteMsgId(message.getAttribute("id")); - finishedMessage.setServerMsgId(result.getAttribute("id")); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - if (query!=null) { - query.incrementMessageCount(); - } - return finishedMessage; - } - - private void parseError(final MessagePacket packet, final Account account) { - final Jid from = packet.getFrom(); - mXmppConnectionService.markMessage(account, from.toBareJid(), - packet.getId(), Message.STATUS_SEND_FAILED); - } - - private void parseNonMessage(Element packet, Account account) { - final Jid from = packet.getAttributeAsJid("from"); - if (account.getJid().equals(from)) { - return; - } - if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) { - mXmppConnectionService.updateConversationUi(); - } - Invite invite = extractInvite(packet); - if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); - if (!conversation.getMucOptions().online()) { - conversation.getMucOptions().setPassword(invite.password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, from, account); - } else if (from != null && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - String id = packet - .findChild("displayed", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, true); - final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), id, Message.STATUS_SEND_DISPLAYED); - Message message = displayedMessage == null ? null :displayedMessage.prev(); - while (message != null - && message.getStatus() == Message.STATUS_SEND_RECEIVED - && message.getTimeSent() < displayedMessage.getTimeSent()) { - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED); - message = message.prev(); - } - } else if (from != null - && packet.hasChild("received", "urn:xmpp:chat-markers:0")) { - String id = packet.findChild("received", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.toBareJid(), - id, Message.STATUS_SEND_RECEIVED); - } else if (from != null - && packet.hasChild("received", "urn:xmpp:receipts")) { - String id = packet.findChild("received", "urn:xmpp:receipts") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.toBareJid(), - id, Message.STATUS_SEND_RECEIVED); - } - } - private class Invite { Jid jid; String password; @@ -451,7 +104,7 @@ public class MessageParser extends AbstractParser implements } private Invite extractInvite(Element message) { - Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); + Element x = message.findChild("x", "http://jabber.org/protocol/muc#user"); if (x != null) { Element invite = x.findChild("invite"); if (invite != null) { @@ -523,142 +176,208 @@ public class MessageParser extends AbstractParser implements } } - private String getPgpBody(Element message) { - Element child = message.findChild("x", "jabber:x:encrypted"); - if (child == null) { - return null; + @Override + public void onMessagePacketReceived(Account account, MessagePacket original) { + final MessagePacket packet; + Long timestamp = null; + final boolean isForwarded; + boolean carbon = false; //live carbons or mam-sub + if (original.fromServer(account)) { + Pair f; + f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); + f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; + f = f == null ? original.getForwardedMessagePacket("result", "urn:xmpp:mam:0") : f; + packet = f != null ? f.first : original; + timestamp = f != null ? f.second : null; + isForwarded = f != null; + carbon = original.hasChild("received", "urn:xmpp:carbons:2") || original.hasChild("received", "urn:xmpp:carbons:2"); + + Element fin = packet.findChild("fin", "urn:xmpp:mam:0"); + if (fin != null) { + mXmppConnectionService.getMessageArchiveService().processFin(fin); + return; + } + } else { - return child.getContent(); + packet = original; + isForwarded = false; + } + if (timestamp == null) { + timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); + } + final String body = packet.getBody(); + final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); + int status; + final Jid to = packet.getTo(); + final Jid from = packet.getFrom(); + final Jid counterpart; + final String id = packet.getId(); + boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; + boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; + if (packet.fromAccount(account)) { + status = Message.STATUS_SEND; + counterpart = to; + } else { + status = Message.STATUS_RECEIVED; + counterpart = from; } - } - private boolean isMarkable(Element message) { - return message.hasChild("markable", "urn:xmpp:chat-markers:0"); - } + if (from == null || to == null) { + Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + return; + } - @Override - public void onMessagePacketReceived(Account account, MessagePacket packet) { - Message message = null; - this.parseNick(packet, account); - if ((packet.getType() == MessagePacket.TYPE_CHAT || packet.getType() == MessagePacket.TYPE_NORMAL)) { - if ((packet.getBody() != null) - && (packet.getBody().startsWith("?OTR"))) { - message = this.parseOtrChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("body") && extractInvite(packet) == null) { - message = this.parseChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("received", "urn:xmpp:carbons:2") - || (packet.hasChild("sent", "urn:xmpp:carbons:2"))) { - message = this.parseCarbonMessage(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_SEND) { - account.activateGracePeriod(); - mXmppConnectionService.markRead(message.getConversation()); - } else { - message.markUnread(); + Invite invite = extractInvite(packet); + if (invite != null && invite.jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(invite.password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation); + mXmppConnectionService.updateConversationUi(); + } + return; + } + + if (extractChatState(mXmppConnectionService.find(account,from), packet)) { + mXmppConnectionService.updateConversationUi(); + } + + if (body != null || encrypted != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); + if (isTypeGroupChat) { + if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { + status = Message.STATUS_SEND; + if (mXmppConnectionService.markMessage(conversation, id, Message.STATUS_SEND_RECEIVED)) { + return; + } else if (id == null) { + Message message = conversation.findSentMessageWithBody(packet.getBody()); + if (message != null) { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); + return; + } } + } else { + status = Message.STATUS_RECEIVED; } - } else if (packet.hasChild("result","urn:xmpp:mam:0")) { - message = parseMamMessage(packet, account); - if (message != null) { - Conversation conversation = message.getConversation(); - conversation.add(message); - mXmppConnectionService.databaseBackend.createMessage(message); + } + Message message; + if (body != null && body.startsWith("?OTR")) { + if (!isForwarded && !isTypeGroupChat && properlyAddressed) { + message = parseOtrChat(body, from, id, conversation); + if (message == null) { + return; + } + } else { + message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } - return; - } else if (packet.hasChild("fin","urn:xmpp:mam:0")) { - Element fin = packet.findChild("fin","urn:xmpp:mam:0"); - mXmppConnectionService.getMessageArchiveService().processFin(fin); + } else if (encrypted != null) { + message = new Message(conversation, encrypted, Message.ENCRYPTION_PGP, status); } else { - parseNonMessage(packet, account); + message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } - } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { - message = this.parseGroupchat(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_RECEIVED) { - message.markUnread(); - } else { - mXmppConnectionService.markRead(message.getConversation()); - account.activateGracePeriod(); + message.setCounterpart(counterpart); + message.setRemoteMsgId(id); + message.setTime(timestamp); + message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); + if (conversation.getMode() == Conversation.MODE_MULTI) { + message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart())); + if (!isTypeGroupChat) { + message.setType(Message.TYPE_PRIVATE); } } - } else if (packet.getType() == MessagePacket.TYPE_ERROR) { - this.parseError(packet, account); - return; - } else if (packet.getType() == MessagePacket.TYPE_HEADLINE) { - this.parseHeadline(packet, account); - return; - } - if ((message == null) || (message.getBody() == null)) { - return; - } - if ((mXmppConnectionService.confirmMessages()) - && ((packet.getId() != null))) { - if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:chat-markers:0"); - mXmppConnectionService.sendMessagePacket(account, receipt); + updateLastseen(packet,account,true); + conversation.add(message); + if (carbon || status == Message.STATUS_RECEIVED) { + mXmppConnectionService.markRead(conversation); + account.activateGracePeriod(); + } else if (!isForwarded) { + message.markUnread(); } - if (packet.hasChild("request", "urn:xmpp:receipts")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:receipts"); - mXmppConnectionService.sendMessagePacket(account, receipt); + + + if (mXmppConnectionService.confirmMessages() && id != null && !packet.fromAccount(account)) { + if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { + MessagePacket receipt = mXmppConnectionService + .getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0"); + mXmppConnectionService.sendMessagePacket(account, receipt); + } + if (packet.hasChild("request", "urn:xmpp:receipts")) { + MessagePacket receipt = mXmppConnectionService + .getMessageGenerator().received(account, packet, "urn:xmpp:receipts"); + mXmppConnectionService.sendMessagePacket(account, receipt); + } } - } - Conversation conversation = message.getConversation(); - conversation.add(message); - if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) { - if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { - mXmppConnectionService.updateConversation(conversation); + if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) { + if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { + mXmppConnectionService.updateConversation(conversation); + } } - } - if (message.getStatus() == Message.STATUS_RECEIVED - && conversation.getOtrSession() != null - && !conversation.getOtrSession().getSessionID().getUserID() - .equals(message.getCounterpart().getResourcepart())) { - conversation.endOtrIfNeeded(); - } + if (message.getStatus() == Message.STATUS_RECEIVED + && conversation.getOtrSession() != null + && !conversation.getOtrSession().getSessionID().getUserID() + .equals(message.getCounterpart().getResourcepart())) { + conversation.endOtrIfNeeded(); + } - if (packet.getType() != MessagePacket.TYPE_ERROR) { if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) { mXmppConnectionService.databaseBackend.createMessage(message); } + final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); + if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + manager.createNewConnection(message); + } else if (!message.isRead()) { + mXmppConnectionService.getNotificationService().push(message); + } + mXmppConnectionService.updateConversationUi(); + } else { + if (packet.hasChild("subject") && isTypeGroupChat) { + Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setHasMessagesLeftOnServer(true); + conversation.getMucOptions().setSubject(packet.findChildContent("subject")); + mXmppConnectionService.updateConversationUi(); + return; + } + } } - final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); - } else if (!message.isRead()) { - mXmppConnectionService.getNotificationService().push(message); + + Element received = packet.findChild("received", "urn:xmpp:chat-markers:0"); + if (received == null) { + received = packet.findChild("received", "urn:xmpp:receipts"); + } + if (received != null && !packet.fromAccount(account)) { + mXmppConnectionService.markMessage(account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED); + } + Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0"); + if (displayed != null) { + if (packet.fromAccount(account)) { + Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid()); + mXmppConnectionService.markRead(conversation); + } else { + updateLastseen(packet, account, true); + final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED); + Message message = displayedMessage == null ? null : displayedMessage.prev(); + while (message != null + && message.getStatus() == Message.STATUS_SEND_RECEIVED + && message.getTimeSent() < displayedMessage.getTimeSent()) { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED); + message = message.prev(); + } + } } - mXmppConnectionService.updateConversationUi(); - } - private void parseHeadline(MessagePacket packet, Account account) { - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, packet.getFrom(), account); + Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event"); + if (event != null) { + parseEvent(event, from, account); } - } - private void parseNick(MessagePacket packet, Account account) { - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); + String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick"); if (nick != null) { - if (packet.getFrom() != null) { - Contact contact = account.getRoster().getContact( - packet.getFrom()); - contact.setPresenceName(nick.getContent()); - } + Contact contact = account.getRoster().getContact(from); + contact.setPresenceName(nick); } } -} +} \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java index 55256ece..bd706b57 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java @@ -51,4 +51,8 @@ public class AbstractStanza extends Element { || getTo().equals(account.getJid().toBareJid()) || getTo().equals(account.getJid()); } + + public boolean fromAccount(final Account account) { + return getFrom() != null && getFrom().toBareJid().equals(account.getJid().toBareJid()); + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java index 11c3452b..e32811af 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java @@ -1,5 +1,10 @@ package eu.siacs.conversations.xmpp.stanzas; +import android.util.Pair; + +import java.text.ParseException; + +import eu.siacs.conversations.parser.AbstractParser; import eu.siacs.conversations.xml.Element; public class MessagePacket extends AbstractStanza { @@ -14,12 +19,7 @@ public class MessagePacket extends AbstractStanza { } public String getBody() { - Element body = this.findChild("body"); - if (body != null) { - return body.getContent(); - } else { - return null; - } + return findChildContent("body"); } public void setBody(String text) { @@ -67,19 +67,23 @@ public class MessagePacket extends AbstractStanza { } } - public MessagePacket getForwardedMessagePacket(String name, String namespace) { + public Pair getForwardedMessagePacket(String name, String namespace) { Element wrapper = findChild(name, namespace); if (wrapper == null) { return null; } - Element forwarded = wrapper.findChild("forwarded","urn:xmpp:forward:0"); + Element forwarded = wrapper.findChild("forwarded", "urn:xmpp:forward:0"); if (forwarded == null) { return null; } - return MessagePacket.create(forwarded.findChild("message")); + MessagePacket packet = create(forwarded.findChild("message")); + if (packet == null) { + return null; + } + Long timestamp = AbstractParser.getTimestamp(forwarded,null); + return new Pair(packet,timestamp); } - public static MessagePacket create(Element element) { if (element == null) { return null; -- cgit v1.2.3 From b731995a517932d1c86877da13dd69d66cbb23c1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 06:31:27 +0200 Subject: added mam stuff to new message parser --- .../eu/siacs/conversations/entities/Message.java | 2 +- .../siacs/conversations/parser/AbstractParser.java | 2 +- .../siacs/conversations/parser/MessageParser.java | 33 +++++++++++++++++----- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 38152edb..90b74a53 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -328,7 +328,7 @@ public class Message extends AbstractEntity { return this.remoteMsgId == null && this.counterpart.equals(message.getCounterpart()) && this.body.equals(message.getBody()) - && Math.abs(this.getTimeSent() - message.getTimeSent()) < Config.PING_TIMEOUT * 500; + && Math.abs(this.getTimeSent() - message.getTimeSent()) < Config.MESSAGE_MERGE_WINDOW * 1000; } } diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 7b3eb7e9..24e93db1 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -22,7 +22,7 @@ public abstract class AbstractParser { } public static Long getTimestamp(Element element, Long defaultValue) { - Element delay = element.findChild("delay"); + Element delay = element.findChild("delay","urn:xmpp:delay"); if (delay != null) { String stamp = delay.getAttribute("stamp"); if (stamp != null) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a2fcbe1..69f58898 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -182,6 +182,8 @@ public class MessageParser extends AbstractParser implements Long timestamp = null; final boolean isForwarded; boolean carbon = false; //live carbons or mam-sub + MessageArchiveService.Query query = null; + String serverMsgId = null; if (original.fromServer(account)) { Pair f; f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); @@ -198,6 +200,14 @@ public class MessageParser extends AbstractParser implements return; } + final Element result = packet.findChild("result","urn:xmpp:mam:0"); + if (result != null) { + query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); + if (query != null) { + query.incrementTotalCount(); + } + serverMsgId = result.getAttribute("id"); + } } else { packet = original; isForwarded = false; @@ -211,7 +221,7 @@ public class MessageParser extends AbstractParser implements final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final Jid counterpart; - final String id = packet.getId(); + final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; if (packet.fromAccount(account)) { @@ -229,7 +239,7 @@ public class MessageParser extends AbstractParser implements Invite invite = extractInvite(packet); if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true,query); if (!conversation.getMucOptions().online()) { conversation.getMucOptions().setPassword(invite.password); mXmppConnectionService.databaseBackend.updateConversation(conversation); @@ -248,9 +258,9 @@ public class MessageParser extends AbstractParser implements if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { status = Message.STATUS_SEND; - if (mXmppConnectionService.markMessage(conversation, id, Message.STATUS_SEND_RECEIVED)) { + if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { return; - } else if (id == null) { + } else if (remoteMsgId == null) { Message message = conversation.findSentMessageWithBody(packet.getBody()); if (message != null) { mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); @@ -264,7 +274,7 @@ public class MessageParser extends AbstractParser implements Message message; if (body != null && body.startsWith("?OTR")) { if (!isForwarded && !isTypeGroupChat && properlyAddressed) { - message = parseOtrChat(body, from, id, conversation); + message = parseOtrChat(body, from, remoteMsgId, conversation); if (message == null) { return; } @@ -277,7 +287,8 @@ public class MessageParser extends AbstractParser implements message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } message.setCounterpart(counterpart); - message.setRemoteMsgId(id); + message.setRemoteMsgId(remoteMsgId); + message.setServerMsgId(serverMsgId); message.setTime(timestamp); message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); if (conversation.getMode() == Conversation.MODE_MULTI) { @@ -287,6 +298,14 @@ public class MessageParser extends AbstractParser implements } } updateLastseen(packet,account,true); + boolean checkForDuplicates = serverMsgId != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")); + if (checkForDuplicates && conversation.hasDuplicateMessage(message)) { + Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody()); + return; + } + if (query != null) { + query.incrementMessageCount(); + } conversation.add(message); if (carbon || status == Message.STATUS_RECEIVED) { mXmppConnectionService.markRead(conversation); @@ -296,7 +315,7 @@ public class MessageParser extends AbstractParser implements } - if (mXmppConnectionService.confirmMessages() && id != null && !packet.fromAccount(account)) { + if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { MessagePacket receipt = mXmppConnectionService .getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0"); -- cgit v1.2.3 From eeebebe32afef42cb3be07641d0c008a67f766ab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 11:51:20 +0200 Subject: fixed read/unread markers --- .../eu/siacs/conversations/parser/MessageParser.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 69f58898..339aeb7f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -181,7 +181,6 @@ public class MessageParser extends AbstractParser implements final MessagePacket packet; Long timestamp = null; final boolean isForwarded; - boolean carbon = false; //live carbons or mam-sub MessageArchiveService.Query query = null; String serverMsgId = null; if (original.fromServer(account)) { @@ -192,15 +191,14 @@ public class MessageParser extends AbstractParser implements packet = f != null ? f.first : original; timestamp = f != null ? f.second : null; isForwarded = f != null; - carbon = original.hasChild("received", "urn:xmpp:carbons:2") || original.hasChild("received", "urn:xmpp:carbons:2"); - Element fin = packet.findChild("fin", "urn:xmpp:mam:0"); + Element fin = original.findChild("fin", "urn:xmpp:mam:0"); if (fin != null) { mXmppConnectionService.getMessageArchiveService().processFin(fin); return; } - final Element result = packet.findChild("result","urn:xmpp:mam:0"); + final Element result = original.findChild("result","urn:xmpp:mam:0"); if (result != null) { query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); if (query != null) { @@ -307,14 +305,15 @@ public class MessageParser extends AbstractParser implements query.incrementMessageCount(); } conversation.add(message); - if (carbon || status == Message.STATUS_RECEIVED) { - mXmppConnectionService.markRead(conversation); - account.activateGracePeriod(); - } else if (!isForwarded) { - message.markUnread(); + if (serverMsgId == null) { + if (status == Message.STATUS_SEND) { + mXmppConnectionService.markRead(conversation); + account.activateGracePeriod(); + } else { + message.markUnread(); + } } - if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { MessagePacket receipt = mXmppConnectionService -- cgit v1.2.3 From 1b5631c835d34fc9f7a3474b015a21ffc64ed0d2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 12:29:45 +0200 Subject: fixed muc mam. added a few security checks --- .../siacs/conversations/parser/MessageParser.java | 48 +++++++++++----------- .../services/MessageArchiveService.java | 12 +++++- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 339aeb7f..d254a863 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -181,31 +181,34 @@ public class MessageParser extends AbstractParser implements final MessagePacket packet; Long timestamp = null; final boolean isForwarded; - MessageArchiveService.Query query = null; String serverMsgId = null; - if (original.fromServer(account)) { + final Element fin = original.findChild("fin", "urn:xmpp:mam:0"); + if (fin != null) { + mXmppConnectionService.getMessageArchiveService().processFin(fin,original.getFrom()); + return; + } + final Element result = original.findChild("result","urn:xmpp:mam:0"); + final MessageArchiveService.Query query = result == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); + if (query != null && query.validFrom(original.getFrom())) { + Pair f = original.getForwardedMessagePacket("result", "urn:xmpp:mam:0"); + if (f == null) { + return; + } + timestamp = f.second; + packet = f.first; + isForwarded = true; + serverMsgId = result.getAttribute("id"); + query.incrementTotalCount(); + } else if (query != null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received mam result from invalid sender"); + return; + } else if (original.fromServer(account)) { Pair f; f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; - f = f == null ? original.getForwardedMessagePacket("result", "urn:xmpp:mam:0") : f; packet = f != null ? f.first : original; timestamp = f != null ? f.second : null; isForwarded = f != null; - - Element fin = original.findChild("fin", "urn:xmpp:mam:0"); - if (fin != null) { - mXmppConnectionService.getMessageArchiveService().processFin(fin); - return; - } - - final Element result = original.findChild("result","urn:xmpp:mam:0"); - if (result != null) { - query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); - if (query != null) { - query.incrementTotalCount(); - } - serverMsgId = result.getAttribute("id"); - } } else { packet = original; isForwarded = false; @@ -216,9 +219,9 @@ public class MessageParser extends AbstractParser implements final String body = packet.getBody(); final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); int status; + final Jid counterpart; final Jid to = packet.getTo(); final Jid from = packet.getFrom(); - final Jid counterpart; final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; @@ -312,6 +315,7 @@ public class MessageParser extends AbstractParser implements } else { message.markUnread(); } + mXmppConnectionService.updateConversationUi(); } if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { @@ -339,8 +343,7 @@ public class MessageParser extends AbstractParser implements conversation.endOtrIfNeeded(); } - if (message.getEncryption() == Message.ENCRYPTION_NONE - || mXmppConnectionService.saveEncryptedMessages()) { + if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) { mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); @@ -349,8 +352,7 @@ public class MessageParser extends AbstractParser implements } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } - mXmppConnectionService.updateConversationUi(); - } else { + } else { //no body if (packet.hasChild("subject") && isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index f97077c4..0bc428c8 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -166,12 +166,12 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } } - public void processFin(Element fin) { + public void processFin(Element fin, Jid from) { if (fin == null) { return; } Query query = findQuery(fin.getAttribute("queryid")); - if (query == null) { + if (query == null || !query.validFrom(from)) { return; } boolean complete = fin.getAttributeAsBoolean("complete"); @@ -336,6 +336,14 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { return this.messageCount; } + public boolean validFrom(Jid from) { + if (muc()) { + return getWith().equals(from); + } else { + return (from == null) || account.getJid().toBareJid().equals(from.toBareJid()); + } + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); -- cgit v1.2.3 From 9658146575841c402f1492bcc53b02bdddc4d458 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 12:43:38 +0200 Subject: fixed npe in new message parser --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d254a863..d2fa2c24 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -375,7 +375,9 @@ public class MessageParser extends AbstractParser implements if (displayed != null) { if (packet.fromAccount(account)) { Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid()); - mXmppConnectionService.markRead(conversation); + if (conversation != null) { + mXmppConnectionService.markRead(conversation); + } } else { updateLastseen(packet, account, true); final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED); -- cgit v1.2.3 From 201bc158bd9fa77c1ffcea53758280bd830e5710 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 19 May 2015 08:23:12 +0200 Subject: proper error parsing. some clean up --- .../siacs/conversations/parser/MessageParser.java | 90 ++++++++++++---------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d2fa2c24..1e683892 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -101,6 +101,20 @@ public class MessageParser extends AbstractParser implements this.jid = jid; this.password = password; } + + public boolean execute(Account account) { + if (jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation); + mXmppConnectionService.updateConversationUi(); + } + return true; + } + return false; + } } private Invite extractInvite(Element message) { @@ -122,34 +136,23 @@ public class MessageParser extends AbstractParser implements private void parseEvent(final Element event, final Jid from, final Account account) { Element items = event.findChild("items"); - if (items == null) { - return; - } - String node = items.getAttribute("node"); - if (node == null) { - return; - } - if (node.equals("urn:xmpp:avatar:metadata")) { + String node = items == null ? null : items.getAttribute("node"); + if ("urn:xmpp:avatar:metadata".equals(node)) { Avatar avatar = Avatar.parseMetadata(items); if (avatar != null) { avatar.owner = from; - if (mXmppConnectionService.getFileBackend().isAvatarCached( - avatar)) { + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { if (account.getJid().toBareJid().equals(from)) { if (account.setAvatar(avatar.getFilename())) { - mXmppConnectionService.databaseBackend - .updateAccount(account); + mXmppConnectionService.databaseBackend.updateAccount(account); } - mXmppConnectionService.getAvatarService().clear( - account); + mXmppConnectionService.getAvatarService().clear(account); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateAccountUi(); } else { - Contact contact = account.getRoster().getContact( - from); + Contact contact = account.getRoster().getContact(from); contact.setAvatar(avatar); - mXmppConnectionService.getAvatarService().clear( - contact); + mXmppConnectionService.getAvatarService().clear(contact); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateRosterUi(); } @@ -157,27 +160,35 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.fetchAvatar(account, avatar); } } - } else if (node.equals("http://jabber.org/protocol/nick")) { - Element item = items.findChild("item"); - if (item != null) { - Element nick = item.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - if (from != null) { - Contact contact = account.getRoster().getContact( - from); - contact.setPresenceName(nick.getContent()); - mXmppConnectionService.getAvatarService().clear(account); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateAccountUi(); - } - } + } else if ("http://jabber.org/protocol/nick".equals(node)) { + Element i = items.findChild("item"); + Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick"); + if (nick != null) { + Contact contact = account.getRoster().getContact(from); + contact.setPresenceName(nick.getContent()); + mXmppConnectionService.getAvatarService().clear(account); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateAccountUi(); } } } + private boolean handleErrorMessage(Account account, MessagePacket packet) { + if (packet.getType() == MessagePacket.TYPE_ERROR) { + Jid from = packet.getFrom(); + if (from != null) { + mXmppConnectionService.markMessage(account, from.toBareJid(), packet.getId(), Message.STATUS_SEND_FAILED); + } + return true; + } + return false; + } + @Override public void onMessagePacketReceived(Account account, MessagePacket original) { + if (handleErrorMessage(account, original)) { + return; + } final MessagePacket packet; Long timestamp = null; final boolean isForwarded; @@ -207,12 +218,16 @@ public class MessageParser extends AbstractParser implements f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; packet = f != null ? f.first : original; + if (handleErrorMessage(account, packet)) { + return; + } timestamp = f != null ? f.second : null; isForwarded = f != null; } else { packet = original; isForwarded = false; } + if (timestamp == null) { timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); } @@ -239,14 +254,7 @@ public class MessageParser extends AbstractParser implements } Invite invite = extractInvite(packet); - if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true,query); - if (!conversation.getMucOptions().online()) { - conversation.getMucOptions().setPassword(invite.password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } + if (invite != null && invite.execute(account)) { return; } -- cgit v1.2.3 From 8064832dcaf9098ed7748fbdf3e21f3f6734cd28 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 08:25:00 +0200 Subject: don't allow user to accidentally send empty messages --- build.gradle | 4 ++-- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 98b341d5..d572892d 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 66 - versionName "1.4.0" + versionCode 67 + versionName "1.4.1" } compileOptions { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 20fc1750..02f664db 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -285,12 +285,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private Message selectedMessage; private void sendMessage() { - if (this.conversation == null) { + final String body = mEditMessage.getText().toString(); + if (body.length() == 0 || this.conversation == null) { return; } - Message message = new Message(conversation, mEditMessage.getText() - .toString(), conversation.getNextEncryption(activity - .forceEncryption())); + Message message = new Message(conversation, body, conversation.getNextEncryption(activity.forceEncryption())); if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getNextCounterpart() != null) { message.setCounterpart(conversation.getNextCounterpart()); -- cgit v1.2.3 From 78847d0749765b7c1e424a8a264d8f23a43170b0 Mon Sep 17 00:00:00 2001 From: "M. Dietrich" Date: Wed, 20 May 2015 11:34:11 +0200 Subject: add extra jid to intend "show location" --- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index b31b9018..dd8ebd3d 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -54,6 +54,7 @@ public class GeoHelper { Intent locationPluginIntent = new Intent("eu.siacs.conversations.location.show"); locationPluginIntent.putExtra("latitude",latitude); locationPluginIntent.putExtra("longitude",longitude); + locationPluginIntent.putExtra("jid",conversation.getJid().toString()); if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { locationPluginIntent.putExtra("name",conversation.getName()); } -- cgit v1.2.3 From a4ec7a7df1b840e52d56bc7b31c629a0e96b6fc5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 12:26:38 +0200 Subject: pulled translations from transifex --- src/main/res/values-bg/strings.xml | 5 +++++ src/main/res/values-de/strings.xml | 5 +++++ src/main/res/values-id/strings.xml | 5 +++++ src/main/res/values-nl/strings.xml | 5 +++++ src/main/res/values-pl/strings.xml | 5 +++++ src/main/res/values-sr/strings.xml | 5 +++++ src/main/res/values-sv/strings.xml | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/src/main/res/values-bg/strings.xml b/src/main/res/values-bg/strings.xml index b27481dd..52bb0054 100644 --- a/src/main/res/values-bg/strings.xml +++ b/src/main/res/values-bg/strings.xml @@ -446,4 +446,9 @@ Изберете %d контакт Изберете %d контакта + Замяна на бутона за изпращане с бързо действие + Бързо действие + Нищо + Използвани наскоро + Изберете бързо действие diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 08b0d4a5..000c253b 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -446,4 +446,9 @@ %d Kontakt ausgewählt %d Kontakte ausgewählt + Ersetze Absende-Knopf durch Schnell-Tasten + Schnell-Tasten + keine + zuletzt verwendet + wähle Schnell-Taste diff --git a/src/main/res/values-id/strings.xml b/src/main/res/values-id/strings.xml index 69bd0911..3ce9cc82 100644 --- a/src/main/res/values-id/strings.xml +++ b/src/main/res/values-id/strings.xml @@ -444,4 +444,9 @@ Pilih %d kontak + Timpa tombol kirim dengan aksi cepat + Aksi Cepat + Tak satupun + Maling sering digunakan + Pilih aksi cepat diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 2532130d..e3f0e69b 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -446,4 +446,9 @@ Selecteer %d contact Selecteer %d contacten + Vervang verzendknop door snelle actie + Snelle actie + Geen + Recent gebruikt + Kies snelle actie diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 70c3a49d..6a983f50 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -448,4 +448,9 @@ %d kontakty wybrane %d kontaktów wybranych + Zastąp przycisk wysyłania szybką akcją + Szybka akcja + Brak + Ostatnio używana + Wybierz szybką akcję diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index ea5cbdb8..60f2e586 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -448,4 +448,9 @@ Изабери %d контакта Изабери %d контаката + Замени дугме за слање брзом радњом + Брза радња + Ниједна + Недавно коришћена + Изаберите брзу радњу diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index 4f84110b..9c60db53 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -446,4 +446,9 @@ Välj %d kontakt Välj %d kontakter + Byt sänd-knappen mot snabbfunktion + Snabbfunktion + Ingen + Senast använd + Välj snabbfunktion -- cgit v1.2.3 From 2364710afb345dfd797a1832c25b134fd34b0e29 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 12:47:04 +0200 Subject: added ShortcutBadger as a dependency to create unread counts on launcher icon --- build.gradle | 5 +++-- .../services/NotificationService.java | 1 + .../services/XmppConnectionService.java | 24 ++++++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index d572892d..635da8f8 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ dependencies { compile 'com.google.zxing:android-integration:3.1.0' compile 'de.measite.minidns:minidns:0.1.3' compile 'de.timroes.android:EnhancedListView:0.3.4' + compile 'me.leolin:ShortcutBadger:1.1.1@aar' } android { @@ -44,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 67 - versionName "1.4.1" + versionCode 68 + versionName "1.5.0-alpha" } compileOptions { diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index e111da95..49543eeb 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -134,6 +134,7 @@ public class NotificationService { } public void push(final Message message) { + mXmppConnectionService.updateUnreadCountBadge(); if (!notify(message)) { return; } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3a74b82b..f682bccd 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -100,6 +100,7 @@ import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; +import me.leolin.shortcutbadger.ShortcutBadger; public class XmppConnectionService extends Service implements OnPhoneContactsLoadedListener { @@ -1033,7 +1034,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) { - Log.d(Config.LOGTAG,"load more messages for "+conversation.getName() + " prior to "+MessageGenerator.getTimestamp(timestamp)); + Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp)); if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) { return; } @@ -1985,14 +1986,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private void fetchAvatarVcard(final Account account, final Avatar avatar, final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveVcardAvatar(avatar); - this.sendIqPacket(account,packet,new OnIqPacketReceived() { + this.sendIqPacket(account, packet, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - synchronized(mInProgressAvatarFetches) { - mInProgressAvatarFetches.remove(generateFetchKey(account,avatar)); + synchronized (mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); } if (packet.getType() == IqPacket.TYPE.RESULT) { - Element vCard = packet.findChild("vCard","vcard-temp"); + Element vCard = packet.findChild("vCard", "vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; String image = photo != null ? photo.findChildContent("BINVAL") : null; if (image != null) { @@ -2110,7 +2111,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void directInvite(Conversation conversation, Jid jid) { - MessagePacket packet = mMessageGenerator.directInvite(conversation,jid); + MessagePacket packet = mMessageGenerator.directInvite(conversation, jid); sendMessagePacket(conversation.getAccount(),packet); } @@ -2254,6 +2255,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void markRead(final Conversation conversation) { mNotificationService.clear(conversation); conversation.markRead(); + updateUnreadCountBadge(); + } + + public void updateUnreadCountBadge() { + int count = unreadCount(); + Log.d(Config.LOGTAG,"update unread count to "+count); + if (count > 0) { + ShortcutBadger.with(getApplicationContext()).count(count); + } else { + ShortcutBadger.with(getApplicationContext()).remove(); + } } public void sendReadMarker(final Conversation conversation) { -- cgit v1.2.3 From 4759607a772642735d57b476c9c474b128695027 Mon Sep 17 00:00:00 2001 From: "M. Dietrich" Date: Wed, 20 May 2015 15:43:45 +0200 Subject: fix to detect the sender jid correctly --- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index dd8ebd3d..74f91a98 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -54,9 +54,14 @@ public class GeoHelper { Intent locationPluginIntent = new Intent("eu.siacs.conversations.location.show"); locationPluginIntent.putExtra("latitude",latitude); locationPluginIntent.putExtra("longitude",longitude); - locationPluginIntent.putExtra("jid",conversation.getJid().toString()); - if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { - locationPluginIntent.putExtra("name",conversation.getName()); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + locationPluginIntent.putExtra("name",conversation.getName()); + locationPluginIntent.putExtra("jid",message.getCounterpart().toString()); + } + else { + locationPluginIntent.putExtra("jid",conversation.getAccount().getJid().toString()); + } } intents.add(locationPluginIntent); -- cgit v1.2.3 From 3cdac228f902978f71839b7c2ae6c1d1b15edd5b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 21 May 2015 05:21:22 +0200 Subject: fixed with attaching wrong files when returning to activity and background service is still alive --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 1b5e5178..d9f56c5d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1039,7 +1039,7 @@ public class ConversationActivity extends XmppActivity mPendingFileUris.clear(); mPendingFileUris.addAll(extractUriFromIntent(data)); if (xmppConnectionServiceBound) { - for(Iterator i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) { + for(Iterator i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) { attachFileToConversation(getSelectedConversation(), i.next()); } } -- cgit v1.2.3 From 82d4c3b21fd9ed6131ce97929013567f5756a9be Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 21 May 2015 05:21:52 +0200 Subject: version bump to 1.4.2 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d572892d..ef3b50ea 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 67 - versionName "1.4.1" + versionCode 68 + versionName "1.4.2" } compileOptions { -- cgit v1.2.3 From a535d45ec3cbb2f3f50882775692b98957e4ea26 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 25 May 2015 04:49:36 +0200 Subject: log connection age and reshedule ping check --- .../conversations/services/XmppConnectionService.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 63d9ba7a..97c52156 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -482,9 +482,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa long lastSent = account.getXmppConnection().getLastPingSent(); long pingInterval = "ui".equals(action) ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000; long msToNextPing = (Math.max(lastReceived,lastSent) + pingInterval) - SystemClock.elapsedRealtime(); - if (lastSent > lastReceived && (lastSent + Config.PING_TIMEOUT * 1000) < SystemClock.elapsedRealtime()) { - Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": ping timeout"); - this.reconnectAccount(account, true); + long pingTimeoutIn = (lastSent + Config.PING_TIMEOUT * 1000) - SystemClock.elapsedRealtime(); + if (lastSent > lastReceived) { + if (pingTimeoutIn < 0) { + long age = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000; + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ping timeout. connection age was: "+age+"s"); + this.reconnectAccount(account, true); + } else { + int secs = (int) (pingTimeoutIn / 1000); + this.scheduleWakeUpCall(secs,account.getUuid().hashCode()); + } } else if (msToNextPing <= 0) { account.getXmppConnection().sendPing(); Log.d(Config.LOGTAG, account.getJid().toBareJid()+" send ping"); @@ -613,7 +620,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } protected void scheduleWakeUpCall(int seconds, int requestCode) { - final long timeToWake = SystemClock.elapsedRealtime() + (seconds + 1) * 1000; + final long timeToWake = SystemClock.elapsedRealtime() + (seconds < 0 ? 1 : seconds + 1) * 1000; Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); -- cgit v1.2.3 From 36034815ee34c9a48c5236329914439bd5885179 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 25 May 2015 04:54:11 +0200 Subject: use same sm check inside xmppconnection and out --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 9bda3c09..d52ebee5 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -921,7 +921,7 @@ public class XmppConnection implements Runnable { ++stanzasSent; } tagWriter.writeStanzaAsync(packet); - if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) { + if (packet instanceof MessagePacket && packet.getId() != null && getFeatures().sm()) { if (Config.EXTENDED_SM_LOGGING) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent); } -- cgit v1.2.3 From 4cb49c4a9cf8c0bc3f38e6bac849b9dc0d55c63c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 25 May 2015 05:00:33 +0200 Subject: version bump to 1.4.3 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ef3b50ea..6d12080f 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 68 - versionName "1.4.2" + versionCode 69 + versionName "1.4.3" } compileOptions { -- cgit v1.2.3 From dc91ff8f291d4b142d28e77137a74dc8e7205149 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 04:36:32 +0200 Subject: renamed OtrEngine to OtrService --- .../eu/siacs/conversations/crypto/OtrEngine.java | 310 --------------------- .../eu/siacs/conversations/crypto/OtrService.java | 310 +++++++++++++++++++++ .../eu/siacs/conversations/entities/Account.java | 16 +- .../siacs/conversations/entities/Conversation.java | 4 +- .../services/XmppConnectionService.java | 6 +- 5 files changed, 323 insertions(+), 323 deletions(-) delete mode 100644 src/main/java/eu/siacs/conversations/crypto/OtrEngine.java create mode 100644 src/main/java/eu/siacs/conversations/crypto/OtrService.java diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java deleted file mode 100644 index 0dc7c37e..00000000 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ /dev/null @@ -1,310 +0,0 @@ -package eu.siacs.conversations.crypto; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.InvalidKeySpecException; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.util.Log; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; -import eu.siacs.conversations.xmpp.chatstate.ChatState; -import eu.siacs.conversations.xmpp.jid.InvalidJidException; -import eu.siacs.conversations.xmpp.jid.Jid; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; - -import net.java.otr4j.OtrEngineHost; -import net.java.otr4j.OtrException; -import net.java.otr4j.OtrPolicy; -import net.java.otr4j.OtrPolicyImpl; -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -import net.java.otr4j.crypto.OtrCryptoException; -import net.java.otr4j.session.InstanceTag; -import net.java.otr4j.session.SessionID; -import net.java.otr4j.session.FragmenterInstructions; - -public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { - - private Account account; - private OtrPolicy otrPolicy; - private KeyPair keyPair; - private XmppConnectionService mXmppConnectionService; - - public OtrEngine(XmppConnectionService service, Account account) { - this.account = account; - this.otrPolicy = new OtrPolicyImpl(); - this.otrPolicy.setAllowV1(false); - this.otrPolicy.setAllowV2(true); - this.otrPolicy.setAllowV3(true); - this.keyPair = loadKey(account.getKeys()); - this.mXmppConnectionService = service; - } - - private KeyPair loadKey(JSONObject keys) { - if (keys == null) { - return null; - } - try { - BigInteger x = new BigInteger(keys.getString("otr_x"), 16); - BigInteger y = new BigInteger(keys.getString("otr_y"), 16); - BigInteger p = new BigInteger(keys.getString("otr_p"), 16); - BigInteger q = new BigInteger(keys.getString("otr_q"), 16); - BigInteger g = new BigInteger(keys.getString("otr_g"), 16); - KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g); - DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g); - PublicKey publicKey = keyFactory.generatePublic(pubKeySpec); - PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); - return new KeyPair(publicKey, privateKey); - } catch (JSONException e) { - return null; - } catch (NoSuchAlgorithmException e) { - return null; - } catch (InvalidKeySpecException e) { - return null; - } - } - - private void saveKey() { - PublicKey publicKey = keyPair.getPublic(); - PrivateKey privateKey = keyPair.getPrivate(); - KeyFactory keyFactory; - try { - keyFactory = KeyFactory.getInstance("DSA"); - DSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec( - privateKey, DSAPrivateKeySpec.class); - DSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, - DSAPublicKeySpec.class); - this.account.setKey("otr_x", privateKeySpec.getX().toString(16)); - this.account.setKey("otr_g", privateKeySpec.getG().toString(16)); - this.account.setKey("otr_p", privateKeySpec.getP().toString(16)); - this.account.setKey("otr_q", privateKeySpec.getQ().toString(16)); - this.account.setKey("otr_y", publicKeySpec.getY().toString(16)); - } catch (final NoSuchAlgorithmException | InvalidKeySpecException e) { - e.printStackTrace(); - } - - } - - @Override - public void askForSecret(SessionID id, InstanceTag instanceTag, String question) { - try { - final Jid jid = Jid.fromSessionID(id); - Conversation conversation = this.mXmppConnectionService.find(this.account,jid); - if (conversation!=null) { - conversation.smp().hint = question; - conversation.smp().status = Conversation.Smp.STATUS_CONTACT_REQUESTED; - mXmppConnectionService.updateConversationUi(); - } - } catch (InvalidJidException e) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": smp in invalid session "+id.toString()); - } - } - - @Override - public void finishedSessionMessage(SessionID arg0, String arg1) - throws OtrException { - - } - - @Override - public String getFallbackMessage(SessionID arg0) { - return "I would like to start a private (OTR encrypted) conversation but your client doesn’t seem to support that"; - } - - @Override - public byte[] getLocalFingerprintRaw(SessionID arg0) { - try { - return getFingerprintRaw(getPublicKey()); - } catch (OtrCryptoException e) { - return null; - } - } - - public PublicKey getPublicKey() { - if (this.keyPair == null) { - return null; - } - return this.keyPair.getPublic(); - } - - @Override - public KeyPair getLocalKeyPair(SessionID arg0) throws OtrException { - if (this.keyPair == null) { - KeyPairGenerator kg; - try { - kg = KeyPairGenerator.getInstance("DSA"); - this.keyPair = kg.genKeyPair(); - this.saveKey(); - mXmppConnectionService.databaseBackend.updateAccount(account); - } catch (NoSuchAlgorithmException e) { - Log.d(Config.LOGTAG, - "error generating key pair " + e.getMessage()); - } - } - return this.keyPair; - } - - @Override - public String getReplyForUnreadableMessage(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public OtrPolicy getSessionPolicy(SessionID arg0) { - return otrPolicy; - } - - @Override - public void injectMessage(SessionID session, String body) - throws OtrException { - MessagePacket packet = new MessagePacket(); - packet.setFrom(account.getJid()); - if (session.getUserID().isEmpty()) { - packet.setAttribute("to", session.getAccountID()); - } else { - packet.setAttribute("to", session.getAccountID() + "/" + session.getUserID()); - } - packet.setBody(body); - packet.addChild("private", "urn:xmpp:carbons:2"); - packet.addChild("no-copy", "urn:xmpp:hints"); - packet.addChild("no-permanent-store", "urn:xmpp:hints"); - - try { - Jid jid = Jid.fromSessionID(session); - Conversation conversation = mXmppConnectionService.find(account,jid); - if (conversation != null && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { - if (mXmppConnectionService.sendChatStates()) { - packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); - } - } - } catch (final InvalidJidException ignored) { - - } - - packet.setType(MessagePacket.TYPE_CHAT); - account.getXmppConnection().sendMessagePacket(packet); - } - - @Override - public void messageFromAnotherInstanceReceived(SessionID session) { - sendOtrErrorMessage(session, "Message from another OTR-instance received"); - } - - @Override - public void multipleInstancesDetected(SessionID arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void requireEncryptedMessage(SessionID arg0, String arg1) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void showError(SessionID arg0, String arg1) throws OtrException { - Log.d(Config.LOGTAG,"show error"); - } - - @Override - public void smpAborted(SessionID id) throws OtrException { - setSmpStatus(id, Conversation.Smp.STATUS_NONE); - } - - private void setSmpStatus(SessionID id, int status) { - try { - final Jid jid = Jid.fromSessionID(id); - Conversation conversation = this.mXmppConnectionService.find(this.account,jid); - if (conversation!=null) { - conversation.smp().status = status; - mXmppConnectionService.updateConversationUi(); - } - } catch (final InvalidJidException ignored) { - - } - } - - @Override - public void smpError(SessionID id, int arg1, boolean arg2) - throws OtrException { - setSmpStatus(id, Conversation.Smp.STATUS_NONE); - } - - @Override - public void unencryptedMessageReceived(SessionID arg0, String arg1) - throws OtrException { - throw new OtrException(new Exception("unencrypted message received")); - } - - @Override - public void unreadableMessageReceived(SessionID session) throws OtrException { - Log.d(Config.LOGTAG,"unreadable message received"); - sendOtrErrorMessage(session, "You sent me an unreadable OTR-encrypted message"); - } - - public void sendOtrErrorMessage(SessionID session, String errorText) { - try { - Jid jid = Jid.fromSessionID(session); - Conversation conversation = mXmppConnectionService.find(account, jid); - String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId(); - if (id != null) { - MessagePacket packet = mXmppConnectionService.getMessageGenerator() - .generateOtrError(jid, id, errorText); - packet.setFrom(account.getJid()); - mXmppConnectionService.sendMessagePacket(account,packet); - Log.d(Config.LOGTAG,packet.toString()); - Log.d(Config.LOGTAG,account.getJid().toBareJid().toString() - +": unreadable OTR message in "+conversation.getName()); - } - } catch (InvalidJidException e) { - return; - } - } - - @Override - public void unverify(SessionID id, String arg1) { - setSmpStatus(id, Conversation.Smp.STATUS_FAILED); - } - - @Override - public void verify(SessionID id, String fingerprint, boolean approved) { - Log.d(Config.LOGTAG,"OtrEngine.verify("+id.toString()+","+fingerprint+","+String.valueOf(approved)+")"); - try { - final Jid jid = Jid.fromSessionID(id); - Conversation conversation = this.mXmppConnectionService.find(this.account,jid); - if (conversation!=null) { - if (approved) { - conversation.getContact().addOtrFingerprint(fingerprint); - } - conversation.smp().hint = null; - conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); - } - } catch (final InvalidJidException ignored) { - } - } - - @Override - public FragmenterInstructions getFragmenterInstructions(SessionID sessionID) { - return null; - } - -} diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrService.java b/src/main/java/eu/siacs/conversations/crypto/OtrService.java new file mode 100644 index 00000000..1e905bac --- /dev/null +++ b/src/main/java/eu/siacs/conversations/crypto/OtrService.java @@ -0,0 +1,310 @@ +package eu.siacs.conversations.crypto; + +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; + +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; +import eu.siacs.conversations.xmpp.chatstate.ChatState; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.MessagePacket; + +import net.java.otr4j.OtrEngineHost; +import net.java.otr4j.OtrException; +import net.java.otr4j.OtrPolicy; +import net.java.otr4j.OtrPolicyImpl; +import net.java.otr4j.crypto.OtrCryptoEngineImpl; +import net.java.otr4j.crypto.OtrCryptoException; +import net.java.otr4j.session.InstanceTag; +import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.FragmenterInstructions; + +public class OtrService extends OtrCryptoEngineImpl implements OtrEngineHost { + + private Account account; + private OtrPolicy otrPolicy; + private KeyPair keyPair; + private XmppConnectionService mXmppConnectionService; + + public OtrService(XmppConnectionService service, Account account) { + this.account = account; + this.otrPolicy = new OtrPolicyImpl(); + this.otrPolicy.setAllowV1(false); + this.otrPolicy.setAllowV2(true); + this.otrPolicy.setAllowV3(true); + this.keyPair = loadKey(account.getKeys()); + this.mXmppConnectionService = service; + } + + private KeyPair loadKey(JSONObject keys) { + if (keys == null) { + return null; + } + try { + BigInteger x = new BigInteger(keys.getString("otr_x"), 16); + BigInteger y = new BigInteger(keys.getString("otr_y"), 16); + BigInteger p = new BigInteger(keys.getString("otr_p"), 16); + BigInteger q = new BigInteger(keys.getString("otr_q"), 16); + BigInteger g = new BigInteger(keys.getString("otr_g"), 16); + KeyFactory keyFactory = KeyFactory.getInstance("DSA"); + DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g); + DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g); + PublicKey publicKey = keyFactory.generatePublic(pubKeySpec); + PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); + return new KeyPair(publicKey, privateKey); + } catch (JSONException e) { + return null; + } catch (NoSuchAlgorithmException e) { + return null; + } catch (InvalidKeySpecException e) { + return null; + } + } + + private void saveKey() { + PublicKey publicKey = keyPair.getPublic(); + PrivateKey privateKey = keyPair.getPrivate(); + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance("DSA"); + DSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec( + privateKey, DSAPrivateKeySpec.class); + DSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, + DSAPublicKeySpec.class); + this.account.setKey("otr_x", privateKeySpec.getX().toString(16)); + this.account.setKey("otr_g", privateKeySpec.getG().toString(16)); + this.account.setKey("otr_p", privateKeySpec.getP().toString(16)); + this.account.setKey("otr_q", privateKeySpec.getQ().toString(16)); + this.account.setKey("otr_y", publicKeySpec.getY().toString(16)); + } catch (final NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + + } + + @Override + public void askForSecret(SessionID id, InstanceTag instanceTag, String question) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().hint = question; + conversation.smp().status = Conversation.Smp.STATUS_CONTACT_REQUESTED; + mXmppConnectionService.updateConversationUi(); + } + } catch (InvalidJidException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": smp in invalid session "+id.toString()); + } + } + + @Override + public void finishedSessionMessage(SessionID arg0, String arg1) + throws OtrException { + + } + + @Override + public String getFallbackMessage(SessionID arg0) { + return "I would like to start a private (OTR encrypted) conversation but your client doesn’t seem to support that"; + } + + @Override + public byte[] getLocalFingerprintRaw(SessionID arg0) { + try { + return getFingerprintRaw(getPublicKey()); + } catch (OtrCryptoException e) { + return null; + } + } + + public PublicKey getPublicKey() { + if (this.keyPair == null) { + return null; + } + return this.keyPair.getPublic(); + } + + @Override + public KeyPair getLocalKeyPair(SessionID arg0) throws OtrException { + if (this.keyPair == null) { + KeyPairGenerator kg; + try { + kg = KeyPairGenerator.getInstance("DSA"); + this.keyPair = kg.genKeyPair(); + this.saveKey(); + mXmppConnectionService.databaseBackend.updateAccount(account); + } catch (NoSuchAlgorithmException e) { + Log.d(Config.LOGTAG, + "error generating key pair " + e.getMessage()); + } + } + return this.keyPair; + } + + @Override + public String getReplyForUnreadableMessage(SessionID arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public OtrPolicy getSessionPolicy(SessionID arg0) { + return otrPolicy; + } + + @Override + public void injectMessage(SessionID session, String body) + throws OtrException { + MessagePacket packet = new MessagePacket(); + packet.setFrom(account.getJid()); + if (session.getUserID().isEmpty()) { + packet.setAttribute("to", session.getAccountID()); + } else { + packet.setAttribute("to", session.getAccountID() + "/" + session.getUserID()); + } + packet.setBody(body); + packet.addChild("private", "urn:xmpp:carbons:2"); + packet.addChild("no-copy", "urn:xmpp:hints"); + packet.addChild("no-permanent-store", "urn:xmpp:hints"); + + try { + Jid jid = Jid.fromSessionID(session); + Conversation conversation = mXmppConnectionService.find(account,jid); + if (conversation != null && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { + if (mXmppConnectionService.sendChatStates()) { + packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); + } + } + } catch (final InvalidJidException ignored) { + + } + + packet.setType(MessagePacket.TYPE_CHAT); + account.getXmppConnection().sendMessagePacket(packet); + } + + @Override + public void messageFromAnotherInstanceReceived(SessionID session) { + sendOtrErrorMessage(session, "Message from another OTR-instance received"); + } + + @Override + public void multipleInstancesDetected(SessionID arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void requireEncryptedMessage(SessionID arg0, String arg1) + throws OtrException { + // TODO Auto-generated method stub + + } + + @Override + public void showError(SessionID arg0, String arg1) throws OtrException { + Log.d(Config.LOGTAG,"show error"); + } + + @Override + public void smpAborted(SessionID id) throws OtrException { + setSmpStatus(id, Conversation.Smp.STATUS_NONE); + } + + private void setSmpStatus(SessionID id, int status) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().status = status; + mXmppConnectionService.updateConversationUi(); + } + } catch (final InvalidJidException ignored) { + + } + } + + @Override + public void smpError(SessionID id, int arg1, boolean arg2) + throws OtrException { + setSmpStatus(id, Conversation.Smp.STATUS_NONE); + } + + @Override + public void unencryptedMessageReceived(SessionID arg0, String arg1) + throws OtrException { + throw new OtrException(new Exception("unencrypted message received")); + } + + @Override + public void unreadableMessageReceived(SessionID session) throws OtrException { + Log.d(Config.LOGTAG,"unreadable message received"); + sendOtrErrorMessage(session, "You sent me an unreadable OTR-encrypted message"); + } + + public void sendOtrErrorMessage(SessionID session, String errorText) { + try { + Jid jid = Jid.fromSessionID(session); + Conversation conversation = mXmppConnectionService.find(account, jid); + String id = conversation == null ? null : conversation.getLastReceivedOtrMessageId(); + if (id != null) { + MessagePacket packet = mXmppConnectionService.getMessageGenerator() + .generateOtrError(jid, id, errorText); + packet.setFrom(account.getJid()); + mXmppConnectionService.sendMessagePacket(account,packet); + Log.d(Config.LOGTAG,packet.toString()); + Log.d(Config.LOGTAG,account.getJid().toBareJid().toString() + +": unreadable OTR message in "+conversation.getName()); + } + } catch (InvalidJidException e) { + return; + } + } + + @Override + public void unverify(SessionID id, String arg1) { + setSmpStatus(id, Conversation.Smp.STATUS_FAILED); + } + + @Override + public void verify(SessionID id, String fingerprint, boolean approved) { + Log.d(Config.LOGTAG,"OtrService.verify("+id.toString()+","+fingerprint+","+String.valueOf(approved)+")"); + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + if (approved) { + conversation.getContact().addOtrFingerprint(fingerprint); + } + conversation.smp().hint = null; + conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); + } + } catch (final InvalidJidException ignored) { + } + } + + @Override + public FragmenterInstructions getFragmenterInstructions(SessionID sessionID) { + return null; + } + +} diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index fe103094..6e6dcb6a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -19,7 +19,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.OtrEngine; +import eu.siacs.conversations.crypto.OtrService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -117,7 +117,7 @@ public class Account extends AbstractEntity { protected JSONObject keys = new JSONObject(); protected String avatar; protected boolean online = false; - private OtrEngine otrEngine = null; + private OtrService mOtrService = null; private XmppConnection xmppConnection = null; private long mEndGracePeriod = 0L; private String otrFingerprint; @@ -273,12 +273,12 @@ public class Account extends AbstractEntity { return values; } - public void initOtrEngine(final XmppConnectionService context) { - this.otrEngine = new OtrEngine(context, this); + public void initAccountServices(final XmppConnectionService context) { + this.mOtrService = new OtrService(context, this); } - public OtrEngine getOtrEngine() { - return this.otrEngine; + public OtrService getOtrService() { + return this.mOtrService; } public XmppConnection getXmppConnection() { @@ -292,10 +292,10 @@ public class Account extends AbstractEntity { public String getOtrFingerprint() { if (this.otrFingerprint == null) { try { - if (this.otrEngine == null) { + if (this.mOtrService == null) { return null; } - final PublicKey publicKey = this.otrEngine.getPublicKey(); + final PublicKey publicKey = this.mOtrService.getPublicKey(); if (publicKey == null || !(publicKey instanceof DSAPublicKey)) { return null; } diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 95a8c957..b5f604b0 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -419,7 +419,7 @@ public class Conversation extends AbstractEntity implements Blockable { final SessionID sessionId = new SessionID(this.getJid().toBareJid().toString(), presence, "xmpp"); - this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine()); + this.otrSession = new SessionImpl(sessionId, getAccount().getOtrService()); try { if (sendStart) { this.otrSession.startSession(); @@ -491,7 +491,7 @@ public class Conversation extends AbstractEntity implements Blockable { return null; } DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession().getRemotePublicKey(); - this.otrFingerprint = getAccount().getOtrEngine().getFingerprint(remotePubKey); + this.otrFingerprint = getAccount().getOtrService().getFingerprint(remotePubKey); } catch (final OtrCryptoException | UnsupportedOperationException ignored) { return null; } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0d48e1a5..48b0624d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -574,7 +574,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.accounts = databaseBackend.getAccounts(); for (final Account account : this.accounts) { - account.initOtrEngine(this); + account.initAccountServices(this); } restoreFromDatabase(); @@ -1176,7 +1176,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void createAccount(final Account account) { - account.initOtrEngine(this); + account.initAccountServices(this); databaseBackend.createAccount(account); this.accounts.add(account); this.reconnectAccountInBackground(account); @@ -2267,7 +2267,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void updateUnreadCountBadge() { int count = unreadCount(); - Log.d(Config.LOGTAG,"update unread count to "+count); + Log.d(Config.LOGTAG, "update unread count to " + count); if (count > 0) { ShortcutBadger.with(getApplicationContext()).count(count); } else { -- cgit v1.2.3 From 997b11dbecc6023ad0679843d8a267d843a2951c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 05:34:58 +0200 Subject: added choose picture as another quick action. fixes #1221 --- art/ic_send_picture_away.svg | 55 +++++++++++++++++++++ art/ic_send_picture_dnd.svg | 55 +++++++++++++++++++++ art/ic_send_picture_offline.svg | 55 +++++++++++++++++++++ art/ic_send_picture_online.svg | 55 +++++++++++++++++++++ art/render.rb | 4 ++ .../conversations/ui/ConversationActivity.java | 3 ++ .../conversations/ui/ConversationFragment.java | 21 +++++++- .../res/drawable-hdpi/ic_send_picture_away.png | Bin 0 -> 790 bytes src/main/res/drawable-hdpi/ic_send_picture_dnd.png | Bin 0 -> 884 bytes .../res/drawable-hdpi/ic_send_picture_offline.png | Bin 0 -> 657 bytes .../res/drawable-hdpi/ic_send_picture_online.png | Bin 0 -> 867 bytes .../res/drawable-mdpi/ic_send_picture_away.png | Bin 0 -> 512 bytes src/main/res/drawable-mdpi/ic_send_picture_dnd.png | Bin 0 -> 585 bytes .../res/drawable-mdpi/ic_send_picture_offline.png | Bin 0 -> 456 bytes .../res/drawable-mdpi/ic_send_picture_online.png | Bin 0 -> 580 bytes .../res/drawable-xhdpi/ic_send_picture_away.png | Bin 0 -> 899 bytes .../res/drawable-xhdpi/ic_send_picture_dnd.png | Bin 0 -> 1016 bytes .../res/drawable-xhdpi/ic_send_picture_offline.png | Bin 0 -> 799 bytes .../res/drawable-xhdpi/ic_send_picture_online.png | Bin 0 -> 997 bytes .../res/drawable-xxhdpi/ic_send_picture_away.png | Bin 0 -> 1327 bytes .../res/drawable-xxhdpi/ic_send_picture_dnd.png | Bin 0 -> 1516 bytes .../drawable-xxhdpi/ic_send_picture_offline.png | Bin 0 -> 1159 bytes .../res/drawable-xxhdpi/ic_send_picture_online.png | Bin 0 -> 1493 bytes .../res/drawable-xxxhdpi/ic_send_picture_away.png | Bin 0 -> 1632 bytes .../res/drawable-xxxhdpi/ic_send_picture_dnd.png | Bin 0 -> 1784 bytes .../drawable-xxxhdpi/ic_send_picture_offline.png | Bin 0 -> 1428 bytes .../drawable-xxxhdpi/ic_send_picture_online.png | Bin 0 -> 1800 bytes src/main/res/values/arrays.xml | 2 + 28 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 art/ic_send_picture_away.svg create mode 100644 art/ic_send_picture_dnd.svg create mode 100644 art/ic_send_picture_offline.svg create mode 100644 art/ic_send_picture_online.svg create mode 100644 src/main/res/drawable-hdpi/ic_send_picture_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_picture_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_picture_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_picture_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_picture_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_picture_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_picture_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_picture_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_picture_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_picture_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_picture_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_picture_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_picture_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_picture_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_picture_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_picture_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_picture_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_picture_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_picture_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_picture_online.png diff --git a/art/ic_send_picture_away.svg b/art/ic_send_picture_away.svg new file mode 100644 index 00000000..a85a1eec --- /dev/null +++ b/art/ic_send_picture_away.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_picture_dnd.svg b/art/ic_send_picture_dnd.svg new file mode 100644 index 00000000..0c7d0635 --- /dev/null +++ b/art/ic_send_picture_dnd.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_picture_offline.svg b/art/ic_send_picture_offline.svg new file mode 100644 index 00000000..048508a3 --- /dev/null +++ b/art/ic_send_picture_offline.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_picture_online.svg b/art/ic_send_picture_online.svg new file mode 100644 index 00000000..06181bbd --- /dev/null +++ b/art/ic_send_picture_online.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/render.rb b/art/render.rb index ad53b1f4..698abea5 100755 --- a/art/render.rb +++ b/art/render.rb @@ -30,6 +30,10 @@ images = { 'ic_send_cancel_offline.svg' => ['ic_send_cancel_offline', 36], 'ic_send_cancel_away.svg' => ['ic_send_cancel_away', 36], 'ic_send_cancel_dnd.svg' => ['ic_send_cancel_dnd', 36], + 'ic_send_picture_online.svg' => ['ic_send_picture_online', 36], + 'ic_send_picture_offline.svg' => ['ic_send_picture_offline', 36], + 'ic_send_picture_away.svg' => ['ic_send_picture_away', 36], + 'ic_send_picture_dnd.svg' => ['ic_send_picture_dnd', 36] } images.each do |source, result| resolutions.each do |name, factor| diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index d9f56c5d..c48b5865 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -479,6 +479,9 @@ public class ConversationActivity extends XmppActivity case ATTACHMENT_CHOICE_TAKE_PHOTO: getPreferences().edit().putString("recently_used_quick_action","photo").apply(); break; + case ATTACHMENT_CHOICE_CHOOSE_IMAGE: + getPreferences().edit().putString("recently_used_quick_action","picture").apply(); + break; } final Conversation conversation = getSelectedConversation(); final int encryption = conversation.getNextEncryption(forceEncryption()); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 02f664db..a817b27b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -256,6 +256,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa case RECORD_VOICE: activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_RECORD_VOICE); break; + case CHOOSE_PICTURE: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_CHOOSE_IMAGE); + break; case CANCEL: if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { conversation.setNextCounterpart(null); @@ -818,7 +821,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateChatMsgHint(); } - enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE, CANCEL} + enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE, CANCEL, CHOOSE_PICTURE} private int getSendButtonImageResource(SendButtonAction action, int status) { switch (action) { @@ -887,6 +890,19 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa default: return R.drawable.ic_send_cancel_offline; } + case CHOOSE_PICTURE: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_picture_online; + case Presences.AWAY: + return R.drawable.ic_send_picture_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_picture_dnd; + default: + return R.drawable.ic_send_picture_offline; + } } return R.drawable.ic_send_text_offline; } @@ -920,6 +936,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa case "voice": action = SendButtonAction.RECORD_VOICE; break; + case "picture": + action = SendButtonAction.CHOOSE_PICTURE; + break; default: action = SendButtonAction.TEXT; break; diff --git a/src/main/res/drawable-hdpi/ic_send_picture_away.png b/src/main/res/drawable-hdpi/ic_send_picture_away.png new file mode 100644 index 00000000..09d1c7b7 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_picture_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_picture_dnd.png b/src/main/res/drawable-hdpi/ic_send_picture_dnd.png new file mode 100644 index 00000000..77964b5b Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_picture_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_picture_offline.png b/src/main/res/drawable-hdpi/ic_send_picture_offline.png new file mode 100644 index 00000000..28135e25 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_picture_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_picture_online.png b/src/main/res/drawable-hdpi/ic_send_picture_online.png new file mode 100644 index 00000000..feb926c6 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_picture_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_picture_away.png b/src/main/res/drawable-mdpi/ic_send_picture_away.png new file mode 100644 index 00000000..d3ebca53 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_picture_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_picture_dnd.png b/src/main/res/drawable-mdpi/ic_send_picture_dnd.png new file mode 100644 index 00000000..1d293f20 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_picture_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_picture_offline.png b/src/main/res/drawable-mdpi/ic_send_picture_offline.png new file mode 100644 index 00000000..95d5621e Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_picture_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_picture_online.png b/src/main/res/drawable-mdpi/ic_send_picture_online.png new file mode 100644 index 00000000..be4194d3 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_picture_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_picture_away.png b/src/main/res/drawable-xhdpi/ic_send_picture_away.png new file mode 100644 index 00000000..f9aa21dc Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_picture_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_picture_dnd.png b/src/main/res/drawable-xhdpi/ic_send_picture_dnd.png new file mode 100644 index 00000000..95e4acce Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_picture_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_picture_offline.png b/src/main/res/drawable-xhdpi/ic_send_picture_offline.png new file mode 100644 index 00000000..75ff2fc4 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_picture_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_picture_online.png b/src/main/res/drawable-xhdpi/ic_send_picture_online.png new file mode 100644 index 00000000..0f68d5f5 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_picture_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_picture_away.png b/src/main/res/drawable-xxhdpi/ic_send_picture_away.png new file mode 100644 index 00000000..7898ed4f Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_picture_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_picture_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_picture_dnd.png new file mode 100644 index 00000000..ccffabbe Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_picture_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_picture_offline.png b/src/main/res/drawable-xxhdpi/ic_send_picture_offline.png new file mode 100644 index 00000000..7b5687e4 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_picture_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_picture_online.png b/src/main/res/drawable-xxhdpi/ic_send_picture_online.png new file mode 100644 index 00000000..82eab70c Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_picture_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_picture_away.png b/src/main/res/drawable-xxxhdpi/ic_send_picture_away.png new file mode 100644 index 00000000..1daa8ecc Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_picture_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_picture_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_picture_dnd.png new file mode 100644 index 00000000..d8257aad Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_picture_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_picture_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_picture_offline.png new file mode 100644 index 00000000..d487709b Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_picture_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_picture_online.png b/src/main/res/drawable-xxxhdpi/ic_send_picture_online.png new file mode 100644 index 00000000..c095d795 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_picture_online.png differ diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml index fec077cc..5be352d1 100644 --- a/src/main/res/values/arrays.xml +++ b/src/main/res/values/arrays.xml @@ -44,6 +44,7 @@ @string/none @string/recently_used @string/attach_take_picture + @string/attach_choose_picture @string/attach_record_voice @string/send_location @@ -52,6 +53,7 @@ none recent photo + picture voice location -- cgit v1.2.3 From a423fc04facb5590998ebde98a7fc3b3edb163ba Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 11:09:17 +0200 Subject: pulled translations from transifex --- src/main/res/values-cs/strings.xml | 5 +++++ src/main/res/values-es/strings.xml | 5 +++++ src/main/res/values-eu/strings.xml | 5 +++++ src/main/res/values-ja/strings.xml | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml index f49cb1b9..c199ec76 100644 --- a/src/main/res/values-cs/strings.xml +++ b/src/main/res/values-cs/strings.xml @@ -448,4 +448,9 @@ Vybrat %d kontakty Vybrat %d kontaktů + Nahradit tlačítko odeslání rychlou akcí + Rychlá akce + Žádná + Naposledy použitá + Vybrat rychlou akci diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 109715e3..880ee66b 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -446,4 +446,9 @@ Seleccionado %d contacto Seleccionados %d contactos + Cambiar el botón de enviar por botón de acción rápida + Acción Rápida + Ninguna + Usada más recientemente + Elegir acción rápida diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index ac66bfc1..b594c069 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -446,4 +446,9 @@ Hautatu kontaktu %d Hautatu %d kontaktu + Bidaltze botoia ekintza azkar batekin aldatu + Ekintza azkarra + Bat ere ez + Azkenengo aldiz erabilitakoa + Ekintza azkarra aukeratu diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 35fb5472..38735f39 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -444,4 +444,9 @@ %d 連絡先を選択 + 送信ボタンをクイックアクションで置き換えます + クイックアクション + なし + 最近使用した + クイックアクションの選択 -- cgit v1.2.3 From 9debf8037b5def6c634d72042566fe63ab9e9ce1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 11:31:33 +0200 Subject: added default iq handler to print some iq error messages --- .../services/XmppConnectionService.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 48b0624d..ebb14669 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -204,6 +204,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private OnMessagePacketReceived mMessageParser = new MessageParser(this); private OnPresencePacketReceived mPresenceParser = new PresenceParser(this); private IqParser mIqParser = new IqParser(this); + private OnIqPacketReceived mDefaultIqHandler = new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.ERROR) { + Element error = packet.findChild("error"); + String text = error != null ? error.findChildContent("text") : null; + if (text != null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received iq error - "+text); + } + } + } + }; private MessageGenerator mMessageGenerator = new MessageGenerator(this); private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); private List accounts; @@ -903,7 +915,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa for (Bookmark bookmark : account.getBookmarks()) { storage.addChild(bookmark); } - sendIqPacket(account, iqPacket, null); + sendIqPacket(account, iqPacket, mDefaultIqHandler); } public void onPhoneContactsLoaded(final List phoneContacts) { @@ -1691,7 +1703,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } IqPacket request = this.mIqGenerator.changeAffiliation(conference, jids, after.toString()); - sendIqPacket(conference.getAccount(), request, null); + sendIqPacket(conference.getAccount(), request, mDefaultIqHandler); } public void changeRoleInConference(final Conversation conference, final String nick, MucOptions.Role role, final OnRoleChanged callback) { @@ -1835,7 +1847,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.query(Xmlns.ROSTER).addChild(contact.asElement()); - account.getXmppConnection().sendIqPacket(iq, null); + account.getXmppConnection().sendIqPacket(iq, mDefaultIqHandler); if (sendUpdates) { sendPresencePacket(account, mPresenceGenerator.sendPresenceUpdatesTo(contact)); @@ -2065,7 +2077,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Element item = iq.query(Xmlns.ROSTER).addChild("item"); item.setAttribute("jid", contact.getJid().toString()); item.setAttribute("subscription", "remove"); - account.getXmppConnection().sendIqPacket(iq, null); + account.getXmppConnection().sendIqPacket(iq, mDefaultIqHandler); } } -- cgit v1.2.3 From 6059ed47388c174db4d4eaa7e5d0b70e16dab6ac Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 12:00:38 +0200 Subject: update unread count badge only when necessary --- .../conversations/services/XmppConnectionService.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ebb14669..cfb2d50d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -227,7 +227,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private final List mInProgressAvatarFetches = new ArrayList<>(); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; - private Integer convChangedListenerCount = 0; + private int convChangedListenerCount = 0; + private int unreadCount = 0; private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @@ -2277,13 +2278,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa updateUnreadCountBadge(); } - public void updateUnreadCountBadge() { + public synchronized void updateUnreadCountBadge() { int count = unreadCount(); - Log.d(Config.LOGTAG, "update unread count to " + count); - if (count > 0) { - ShortcutBadger.with(getApplicationContext()).count(count); - } else { - ShortcutBadger.with(getApplicationContext()).remove(); + if (unreadCount != count) { + Log.d(Config.LOGTAG, "update unread count to " + count); + if (count > 0) { + ShortcutBadger.with(getApplicationContext()).count(count); + } else { + ShortcutBadger.with(getApplicationContext()).remove(); + } + unreadCount = count; } } -- cgit v1.2.3 From 402e5363d1db774e5e244948a2f0e961b48bb0a7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 12:00:55 +0200 Subject: deduplicate private muc messages --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 1e683892..898613e3 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -307,7 +307,9 @@ public class MessageParser extends AbstractParser implements } } updateLastseen(packet,account,true); - boolean checkForDuplicates = serverMsgId != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")); + boolean checkForDuplicates = serverMsgId != null + || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")) + || message.getType() == Message.TYPE_PRIVATE; if (checkForDuplicates && conversation.hasDuplicateMessage(message)) { Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody()); return; -- cgit v1.2.3 From 0f6f6adca0aa198eb78f88e4fc1b36a30ce8410c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 13:04:22 +0200 Subject: removed unnecessary / inacurate debug logging --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index cfb2d50d..fa8dd7d6 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -499,8 +499,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa long pingTimeoutIn = (lastSent + Config.PING_TIMEOUT * 1000) - SystemClock.elapsedRealtime(); if (lastSent > lastReceived) { if (pingTimeoutIn < 0) { - long age = (SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000; - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ping timeout. connection age was: "+age+"s"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ping timeout"); this.reconnectAccount(account, true); } else { int secs = (int) (pingTimeoutIn / 1000); -- cgit v1.2.3 From 165965bb83bb3ee9750b8cfecea87ddb154fc649 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 27 May 2015 11:44:44 +0200 Subject: parse nick and avatar only from available presences to avoid potential error reflection --- .../siacs/conversations/parser/PresenceParser.java | 73 ++++++++-------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index f7872210..d83347d8 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -45,38 +45,37 @@ public class PresenceParser extends AbstractParser implements } public void parseContactPresence(PresencePacket packet, Account account) { - PresenceGenerator mPresenceGenerator = mXmppConnectionService - .getPresenceGenerator(); - if (packet.getFrom() == null) { + PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); + final Jid from = packet.getFrom(); + if (from == null) { return; } - final Jid from = packet.getFrom(); - String type = packet.getAttribute("type"); - Contact contact = account.getRoster().getContact(packet.getFrom()); + final String type = packet.getAttribute("type"); + final Contact contact = account.getRoster().getContact(from); if (type == null) { - String presence; - if (!from.isBareJid()) { - presence = from.getResourcepart(); - } else { - presence = ""; + String presence = from.isBareJid() ? "" : from.getResourcepart(); + contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick")); + Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update")); + if (avatar != null && !contact.isSelf()) { + avatar.owner = from.toBareJid(); + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + if (contact.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(contact); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateRosterUi(); + } + } else { + mXmppConnectionService.fetchAvatar(account, avatar); + } } int sizeBefore = contact.getPresences().size(); - contact.updatePresence(presence, - Presences.parseShow(packet.findChild("show"))); + contact.updatePresence(presence, Presences.parseShow(packet.findChild("show"))); PgpEngine pgp = mXmppConnectionService.getPgpEngine(); - if (pgp != null) { - Element x = packet.findChild("x", "jabber:x:signed"); - if (x != null) { - Element status = packet.findChild("status"); - String msg; - if (status != null) { - msg = status.getContent(); - } else { - msg = ""; - } - contact.setPgpKeyId(pgp.fetchKeyId(account, msg, - x.getContent())); - } + Element x = packet.findChild("x", "jabber:x:signed"); + if (pgp != null && x != null) { + Element status = packet.findChild("status"); + String msg = status != null ? status.getContent() : ""; + contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent())); } boolean online = sizeBefore < contact.getPresences().size(); updateLastseen(packet, account, false); @@ -87,8 +86,7 @@ public class PresenceParser extends AbstractParser implements } else { contact.removePresence(from.getResourcepart()); } - mXmppConnectionService.onContactStatusChanged - .onContactStatusChanged(contact, false); + mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false); } else if (type.equals("subscribe")) { if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { mXmppConnectionService.sendPresencePacket(account, @@ -97,25 +95,6 @@ public class PresenceParser extends AbstractParser implements contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); } } - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - contact.setPresenceName(nick.getContent()); - } - Element x = packet.findChild("x","vcard-temp:x:update"); - Avatar avatar = Avatar.parsePresence(x); - if (avatar != null && !contact.isSelf()) { - avatar.owner = from.toBareJid(); - if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { - if (contact.setAvatar(avatar)) { - mXmppConnectionService.getAvatarService().clear(contact); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateRosterUi(); - } - } else { - mXmppConnectionService.fetchAvatar(account,avatar); - } - } mXmppConnectionService.updateRosterUi(); } -- cgit v1.2.3 From 5373956e19f318551841d59885f4c2567ffd46a3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 28 May 2015 16:55:48 +0200 Subject: use dns library to resolve missing ipv6 or ipv4 addresses --- .../eu/siacs/conversations/utils/DNSHelper.java | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 42dd1c95..5135acf7 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -142,11 +142,21 @@ public class DNSHelper { for (SRV srv : result) { if (ips6.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); + } else { + DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + if (response.getAnswers().length >= 1) { + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + } } if (ips4.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4)); + } else { + DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); + if (response.getAnswers().length >= 1) { + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + } } - values.add(createNamePortBundle(srv.getName(),srv.getPort(),null)); + values.add(createNamePortBundle(srv.getName(), srv.getPort())); } bundle.putParcelableArrayList("values", values); } catch (SocketTimeoutException e) { @@ -157,6 +167,13 @@ public class DNSHelper { return bundle; } + private static Bundle createNamePortBundle(String name, int port) { + Bundle namePort = new Bundle(); + namePort.putString("name", name); + namePort.putInt("port", port); + return namePort; + } + private static Bundle createNamePortBundle(String name, int port, TreeMap> ips) { Bundle namePort = new Bundle(); namePort.putString("name", name); @@ -169,6 +186,18 @@ public class DNSHelper { return namePort; } + private static Bundle createNamePortBundle(String name, int port, Data data) { + Bundle namePort = new Bundle(); + namePort.putString("name", name); + namePort.putInt("port", port); + if (data instanceof A) { + namePort.putString("ip", data.toString()); + } else if (data instanceof AAAA) { + namePort.putString("ip","["+data.toString()+"]"); + } + return namePort; + } + final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { -- cgit v1.2.3 From a577ec7c318d734de3ed8c2dc5ab1dd4b773b78a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 28 May 2015 17:31:46 +0200 Subject: let dns library take care of no-srv style hosts as well --- .../eu/siacs/conversations/utils/DNSHelper.java | 25 ++++++++++++++-------- .../siacs/conversations/xmpp/XmppConnection.java | 3 --- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 5135acf7..e91005a1 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -37,9 +37,6 @@ public class DNSHelper { Bundle b = queryDNS(host, ip); if (b.containsKey("values")) { return b; - } else if (b.containsKey("error") - && "nosrv".equals(b.getString("error", null))) { - return b; } } } @@ -134,26 +131,35 @@ public class DNSHelper { } + ArrayList values = new ArrayList<>(); if (result.size() == 0) { - bundle.putString("error", "nosrv"); + DNSMessage response; + response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + } + response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + } + bundle.putParcelableArrayList("values", values); return bundle; } - ArrayList values = new ArrayList<>(); for (SRV srv : result) { if (ips6.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); } else { DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - if (response.getAnswers().length >= 1) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } } if (ips4.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4)); } else { DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); - if (response.getAnswers().length >= 1) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } } values.add(createNamePortBundle(srv.getName(), srv.getPort())); @@ -162,6 +168,7 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { + Log.d(Config.LOGTAG,e.getMessage()); bundle.putString("error", "unhandled"); } return bundle; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index d52ebee5..f6e0bfdc 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -200,9 +200,6 @@ public class XmppConnection implements Runnable { if (socketError) { throw new UnknownHostException(); } - } else if (result.containsKey("error") - && "nosrv".equals(result.getString("error", null))) { - socket = new Socket(account.getServer().getDomainpart(), 5222); } else { throw new IOException("unhandled exception in DNS resolver"); } -- cgit v1.2.3 From df86b0fc47cb7af8e97826f97d0e202405cff414 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 06:23:32 +0200 Subject: improved compatibility with muc components that change the message id --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 898613e3..fe42a2ae 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -269,9 +269,10 @@ public class MessageParser extends AbstractParser implements status = Message.STATUS_SEND; if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { return; - } else if (remoteMsgId == null) { - Message message = conversation.findSentMessageWithBody(packet.getBody()); + } else { + Message message = conversation.findSentMessageWithBody(body); if (message != null) { + message.setRemoteMsgId(remoteMsgId); mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); return; } -- cgit v1.2.3 From 8ac933be9f8fddfda42159636d41c7652f7b79d6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 12:21:35 +0200 Subject: fixed more edge cases in muc message parser --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index fe42a2ae..bbb550b2 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -266,14 +266,14 @@ public class MessageParser extends AbstractParser implements Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { - status = Message.STATUS_SEND; - if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { + status = Message.STATUS_SEND_RECEIVED; + if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) { return; } else { Message message = conversation.findSentMessageWithBody(body); if (message != null) { message.setRemoteMsgId(remoteMsgId); - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); + mXmppConnectionService.markMessage(message, status); return; } } -- cgit v1.2.3 From ba5d0892a6114bd85ea667428518f6f75a096af3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 12:23:54 +0200 Subject: stick with 1.4.x --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7580be36..41f39941 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ android { minSdkVersion 14 targetSdkVersion 21 versionCode 70 - versionName "1.5.0-alpha" + versionName "1.4.4-beta" } compileOptions { -- cgit v1.2.3 From fe1cff016f3e1bccaf8287fb490380281cb13983 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 13:33:20 +0200 Subject: avoid unnessary muc mam queries when message count is 0 after subject --- src/main/java/eu/siacs/conversations/entities/Conversation.java | 6 ++++++ src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index b5f604b0..289ed4ea 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -249,6 +249,12 @@ public class Conversation extends AbstractEntity implements Blockable { this.mLastReceivedOtrMessageId = id; } + public int countMessages() { + synchronized (this.messages) { + return this.messages.size(); + } + } + public interface OnMessageFound { public void onMessageFound(final Message message); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index bbb550b2..d0d517ee 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -367,7 +367,7 @@ public class MessageParser extends AbstractParser implements if (packet.hasChild("subject") && isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setHasMessagesLeftOnServer(true); + conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); conversation.getMucOptions().setSubject(packet.findChildContent("subject")); mXmppConnectionService.updateConversationUi(); return; -- cgit v1.2.3 From b40922d7475249e07af77aacd68f39cfd4dd3859 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 14:10:49 +0200 Subject: upgrade build tools --- src/main/res/values-ca@valencia/strings.xml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/main/res/values-ca@valencia/strings.xml diff --git a/src/main/res/values-ca@valencia/strings.xml b/src/main/res/values-ca@valencia/strings.xml deleted file mode 100644 index c757504a..00000000 --- a/src/main/res/values-ca@valencia/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - -- cgit v1.2.3 From a4fb6bb3a3fd06435cbb3244f120506e47792e1b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 15:24:58 +0200 Subject: really update build tools --- build.gradle | 2 +- libs/MemorizingTrustManager/build.gradle | 2 +- libs/openpgp-api-lib/build.gradle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 41f39941..c75c3187 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.0.1' + classpath 'com.android.tools.build:gradle:1.2.3' } } diff --git a/libs/MemorizingTrustManager/build.gradle b/libs/MemorizingTrustManager/build.gradle index aa022a93..47491fec 100644 --- a/libs/MemorizingTrustManager/build.gradle +++ b/libs/MemorizingTrustManager/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.7.+' + classpath 'com.android.tools.build:gradle:1.2.3' } } diff --git a/libs/openpgp-api-lib/build.gradle b/libs/openpgp-api-lib/build.gradle index 6e8fdfb5..a991cf26 100644 --- a/libs/openpgp-api-lib/build.gradle +++ b/libs/openpgp-api-lib/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:0.12.2' + classpath 'com.android.tools.build:gradle:1.2.3' } } -- cgit v1.2.3 From 3eab3291dee7a3d20d2cf6ccb14da3e59562470f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Jun 2015 03:05:20 +0200 Subject: properly calculate remaining size. should fix #1243 --- .../siacs/conversations/xmpp/jingle/JingleInbandTransport.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 29efcf8f..8da53c1b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -160,13 +160,18 @@ public class JingleInbandTransport extends JingleTransport { byte[] buffer = new byte[this.bufferSize]; try { int count = fileInputStream.read(buffer); - this.remainingSize -= count; - if (count != buffer.length && count != -1) { + if (count == -1) { + file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); + this.onFileTransmissionStatusChanged.onFileTransmitted(file); + fileInputStream.close(); + return; + } else if (count != buffer.length) { int rem = fileInputStream.read(buffer,count,buffer.length-count); if (rem > 0) { count += rem; } } + this.remainingSize -= count; this.digest.update(buffer,0,count); String base64 = Base64.encodeToString(buffer,0,count, Base64.NO_WRAP); IqPacket iq = new IqPacket(IqPacket.TYPE.SET); -- cgit v1.2.3 From 53e8964dc17e5c994eda369e78c3bb81133abd9b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Jun 2015 14:05:54 +0200 Subject: reworked handeling of system contacts --- .../eu/siacs/conversations/entities/Contact.java | 12 +++++-- .../eu/siacs/conversations/entities/Roster.java | 14 +++++--- .../services/XmppConnectionService.java | 15 ++++++-- .../conversations/ui/ContactDetailsActivity.java | 42 +++++++++++----------- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index 9dbca59a..e546f214 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -237,8 +237,16 @@ public class Contact implements ListItem, Blockable { return this.presences.getMostAvailableStatus(); } - public void setPhotoUri(String uri) { - this.photoUri = uri; + public boolean setPhotoUri(String uri) { + if (uri != null && !uri.equals(this.photoUri)) { + this.photoUri = uri; + return true; + } else if (this.photoUri != null && uri == null) { + this.photoUri = null; + return true; + } else { + return false; + } } public void setServerName(String serverName) { diff --git a/src/main/java/eu/siacs/conversations/entities/Roster.java b/src/main/java/eu/siacs/conversations/entities/Roster.java index ce058004..d6777ef6 100644 --- a/src/main/java/eu/siacs/conversations/entities/Roster.java +++ b/src/main/java/eu/siacs/conversations/entities/Roster.java @@ -2,6 +2,7 @@ package eu.siacs.conversations.entities; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import eu.siacs.conversations.xmpp.jid.Jid; @@ -55,12 +56,15 @@ public class Roster { } } - public void clearSystemAccounts() { - for (Contact contact : getContacts()) { - contact.setPhotoUri(null); - contact.setSystemName(null); - contact.setSystemAccount(null); + public List getWithSystemAccounts() { + List with = getContacts(); + for(Iterator iterator = with.iterator(); iterator.hasNext();) { + Contact contact = iterator.next(); + if (contact.getSystemAccount() == null) { + iterator.remove(); + } } + return with; } public List getContacts() { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index fa8dd7d6..7b5532a4 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -927,7 +927,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void run() { Log.d(Config.LOGTAG,"start merging phone contacts with roster"); for (Account account : accounts) { - account.getRoster().clearSystemAccounts(); + List withSystemAccounts = account.getRoster().getWithSystemAccounts(); for (Bundle phoneContact : phoneContacts) { if (Thread.interrupted()) { Log.d(Config.LOGTAG,"interrupted merging phone contacts"); @@ -944,9 +944,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa + "#" + phoneContact.getString("lookup"); contact.setSystemAccount(systemAccount); - contact.setPhotoUri(phoneContact.getString("photouri")); - getAvatarService().clear(contact); + if (contact.setPhotoUri(phoneContact.getString("photouri"))) { + getAvatarService().clear(contact); + } contact.setSystemName(phoneContact.getString("displayname")); + withSystemAccounts.remove(contact); + } + for(Contact contact : withSystemAccounts) { + contact.setSystemAccount(null); + contact.setSystemName(null); + if (contact.setPhotoUri(null)) { + getAvatarService().clear(contact); + } } } Log.d(Config.LOGTAG,"finished merging phone contacts"); diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index f7156d7a..c190caed 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -10,6 +10,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Intents; @@ -126,14 +127,23 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder( - ContactDetailsActivity.this); - builder.setTitle(getString(R.string.action_add_phone_book)); - builder.setMessage(getString(R.string.add_phone_book_text, + if (contact.getSystemAccount() == null) { + AlertDialog.Builder builder = new AlertDialog.Builder( + ContactDetailsActivity.this); + builder.setTitle(getString(R.string.action_add_phone_book)); + builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid())); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.add), addToPhonebook); - builder.create().show(); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.setPositiveButton(getString(R.string.add), addToPhonebook); + builder.create().show(); + } else { + String[] systemAccount = contact.getSystemAccount().split("#"); + long id = Long.parseLong(systemAccount[0]); + Uri uri = ContactsContract.Contacts.getLookupUri(id, systemAccount[1]); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(uri); + startActivity(intent); + } } }; @@ -340,12 +350,9 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } else { contactJidTv.setText(contact.getJid().toString()); } - accountJidTv.setText(getString(R.string.using_account, contact - .getAccount().getJid().toBareJid())); - prepareContactBadge(badge, contact); - if (contact.getSystemAccount() == null) { - badge.setOnClickListener(onBadgeClick); - } + accountJidTv.setText(getString(R.string.using_account, contact.getAccount().getJid().toBareJid())); + badge.setImageBitmap(avatarService().get(contact, getPixel(72))); + badge.setOnClickListener(this.onBadgeClick); keys.removeAllViews(); boolean hasKeys = false; @@ -419,15 +426,6 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } } - private void prepareContactBadge(QuickContactBadge badge, Contact contact) { - if (contact.getSystemAccount() != null) { - String[] systemAccount = contact.getSystemAccount().split("#"); - long id = Long.parseLong(systemAccount[0]); - badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1])); - } - badge.setImageBitmap(avatarService().get(contact, getPixel(72))); - } - protected void confirmToDeleteFingerprint(final String fingerprint) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.delete_fingerprint); -- cgit v1.2.3 From 6b794eca2cfc8d1edf4f73c740a3e1b4e966da27 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 02:47:24 +0200 Subject: send_received muc messages will mark a conversation a read --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d0d517ee..96568fbd 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -320,7 +320,7 @@ public class MessageParser extends AbstractParser implements } conversation.add(message); if (serverMsgId == null) { - if (status == Message.STATUS_SEND) { + if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) { mXmppConnectionService.markRead(conversation); account.activateGracePeriod(); } else { -- cgit v1.2.3 From 8f07e4c441778e476119f25cc8cac833e0937508 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 02:48:07 +0200 Subject: streamlined dns helper by ignoring weight --- .../eu/siacs/conversations/utils/DNSHelper.java | 65 ++++------------------ 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index e91005a1..7a51c1ce 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -47,88 +47,43 @@ public class DNSHelper { Bundle bundle = new Bundle(); try { String qname = "_xmpp-client._tcp." + host; - Log.d(Config.LOGTAG, - "using dns server: " + dnsServer.getHostAddress() - + " to look up " + host); - DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, - dnsServer.getHostAddress()); - - // How should we handle priorities and weight? - // Wikipedia has a nice article about priorities vs. weights: - // https://en.wikipedia.org/wiki/SRV_record#Provisioning_for_high_service_availability - - // we bucket the SRV records based on priority, pick per priority - // a random order respecting the weight, and dump that priority by - // priority + Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); + DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); TreeMap> priorities = new TreeMap<>(); TreeMap> ips4 = new TreeMap<>(); TreeMap> ips6 = new TreeMap<>(); - for (Record[] rrset : new Record[][] { message.getAnswers(), - message.getAdditionalResourceRecords() }) { + for (Record[] rrset : new Record[][] { message.getAnswers(), message.getAdditionalResourceRecords() }) { for (Record rr : rrset) { Data d = rr.getPayload(); - if (d instanceof SRV - && NameUtil.idnEquals(qname, rr.getName())) { + if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { SRV srv = (SRV) d; if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(), - new ArrayList(2)); + priorities.put(srv.getPriority(),new ArrayList()); } priorities.get(srv.getPriority()).add(srv); } if (d instanceof A) { - A arecord = (A) d; + A a = (A) d; if (!ips4.containsKey(rr.getName())) { - ips4.put(rr.getName(), new ArrayList(3)); + ips4.put(rr.getName(), new ArrayList()); } - ips4.get(rr.getName()).add(arecord.toString()); + ips4.get(rr.getName()).add(a.toString()); } if (d instanceof AAAA) { AAAA aaaa = (AAAA) d; if (!ips6.containsKey(rr.getName())) { - ips6.put(rr.getName(), new ArrayList(3)); + ips6.put(rr.getName(), new ArrayList()); } ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); } } } - Random rnd = new Random(); - ArrayList result = new ArrayList<>( - priorities.size() * 2 + 1); + ArrayList result = new ArrayList<>(); for (ArrayList s : priorities.values()) { - - // trivial case - if (s.size() <= 1) { - result.addAll(s); - continue; - } - - long totalweight = 0l; - for (SRV srv : s) { - totalweight += srv.getWeight(); - } - - while (totalweight > 0l && s.size() > 0) { - long p = (rnd.nextLong() & 0x7fffffffffffffffl) - % totalweight; - int i = 0; - while (p > 0) { - p -= s.get(i++).getPriority(); - } - if (i>0) i--; - // remove is expensive, but we have only a few entries - // anyway - SRV srv = s.remove(i); - totalweight -= srv.getWeight(); - result.add(srv); - } - - Collections.shuffle(s, rnd); result.addAll(s); - } ArrayList values = new ArrayList<>(); -- cgit v1.2.3 From a4e9f0c9c04c5fcc6e9686552a5fcc0198526a49 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 16:26:51 +0200 Subject: fixed obvious bug in dns helper --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 7a51c1ce..6f414ccc 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -106,7 +106,7 @@ public class DNSHelper { } else { DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); } } if (ips4.containsKey(srv.getName())) { @@ -114,7 +114,7 @@ public class DNSHelper { } else { DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); } } values.add(createNamePortBundle(srv.getName(), srv.getPort())); -- cgit v1.2.3 From 31deb44780f1d6c955897d6adefea1d1ea63eb2c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 16:27:27 +0200 Subject: version bump --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c75c3187..35cf1133 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 70 - versionName "1.4.4-beta" + versionCode 71 + versionName "1.4.4-beta2" } compileOptions { -- cgit v1.2.3 From 9d1e8205a2d362a33e142a49db1787fe5145ce3f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 5 Jun 2015 08:46:06 +0200 Subject: made i/o and memory intensive operations execute in serial order --- .../services/XmppConnectionService.java | 29 +++++++++++------- .../utils/SerialSingleThreadExecutor.java | 34 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 7b5532a4..0a264dd1 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -77,6 +77,7 @@ import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener; import eu.siacs.conversations.utils.PRNGFixes; import eu.siacs.conversations.utils.PhoneHelper; +import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnBindListener; @@ -119,6 +120,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa startService(intent); } }; + + private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor(); + private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor(); + private final IBinder mBinder = new XmppConnectionBinder(); private final List conversations = new CopyOnWriteArrayList<>(); private final FileObserver fileObserver = new FileObserver( @@ -373,7 +378,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.success(message); } } else { - new Thread(new Runnable() { + mFileAddingExecutor.execute(new Runnable() { @Override public void run() { try { @@ -388,8 +393,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.error(e.getResId(),message); } } - }).start(); - + }); } } @@ -405,7 +409,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_IMAGE); - new Thread(new Runnable() { + mFileAddingExecutor.execute(new Runnable() { @Override public void run() { @@ -420,7 +424,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.error(e.getResId(), message); } } - }).start(); + }); } public Conversation find(Bookmark bookmark) { @@ -976,7 +980,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Account account = accountLookupTable.get(conversation.getAccountUuid()); conversation.setAccount(account); } - new Thread(new Runnable() { + Runnable runnable =new Runnable() { @Override public void run() { Log.d(Config.LOGTAG,"restoring roster"); @@ -997,7 +1001,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Log.d(Config.LOGTAG,"restored all messages"); updateConversationUi(); } - }).start(); + }; + mDatabaseExecutor.execute(runnable); } } @@ -1066,7 +1071,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) { return; } - new Thread(new Runnable() { + Runnable runnable = new Runnable() { @Override public void run() { final Account account = conversation.getAccount(); @@ -1085,7 +1090,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.informUser(R.string.fetching_history_from_server); } } - }).start(); + }; + mDatabaseExecutor.execute(runnable); } public List getAccounts() { @@ -2344,13 +2350,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void syncRosterToDisk(final Account account) { - new Thread(new Runnable() { + Runnable runnable = new Runnable() { @Override public void run() { databaseBackend.writeRoster(account.getRoster()); } - }).start(); + }; + mDatabaseExecutor.execute(runnable); } diff --git a/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java b/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java new file mode 100644 index 00000000..bfb4668d --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java @@ -0,0 +1,34 @@ +package eu.siacs.conversations.utils; + +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class SerialSingleThreadExecutor implements Executor { + + final Executor executor = Executors.newSingleThreadExecutor(); + final Queue tasks = new ArrayDeque(); + Runnable active; + + public synchronized void execute(final Runnable r) { + tasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (active == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + if ((active = tasks.poll()) != null) { + executor.execute(active); + } + } +} \ No newline at end of file -- cgit v1.2.3 From 0ea83832cde4982d94cbee7b5779d0f32721fea0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 10 Jun 2015 03:29:52 +0200 Subject: pulled new translations from transifex --- src/main/res/values-ko/strings.xml | 5 +++++ src/main/res/values-zh-rCN/strings.xml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml index d00ab0fd..9354c432 100644 --- a/src/main/res/values-ko/strings.xml +++ b/src/main/res/values-ko/strings.xml @@ -444,4 +444,9 @@ %d 연락처 선택 + 전송 버튼을 빠른 동작 버튼으로 교체 + 빠른 동작 + 없음 + 최근 사용된 항목 + 빠른 동작 선택 diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 2f80e064..e194bffd 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -444,4 +444,9 @@ 选择 %d 个联系人 + 以快速动作替代发送按钮 + 快速动作 + + 最近使用过的 + 选择快速动作 -- cgit v1.2.3 From 58201b440856a60d45d3a72cf6aaacd3a36dc828 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 10 Jun 2015 03:30:17 +0200 Subject: changed paragraph divider --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 90b74a53..a63d033d 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -17,7 +17,7 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; - public static final String MERGE_SEPARATOR = "\u200B\n\n"; + public static final String MERGE_SEPARATOR = " \u200B\n\n"; public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; -- cgit v1.2.3 From 5a48afdd4d44b5865831df470a2c5d00e9cc9599 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 19 Jun 2015 16:25:08 +0200 Subject: don't perform dns lookups on domain parts that obviously look like ip addresses --- .../eu/siacs/conversations/utils/DNSHelper.java | 24 +++--- .../siacs/conversations/xmpp/XmppConnection.java | 96 ++++++++++++---------- 2 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 6f414ccc..bb354ae0 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -20,11 +20,19 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Random; import java.util.TreeMap; +import java.util.regex.Pattern; import android.os.Bundle; import android.util.Log; public class DNSHelper { + + public static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z"); + public static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z"); + protected static Client client = new Client(); public static Bundle getSRVRecord(final Jid jid) throws IOException { @@ -160,15 +168,11 @@ public class DNSHelper { return namePort; } - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); + public static boolean isIp(final String server) { + return PATTERN_IPV4.matcher(server).matches() + || PATTERN_IPV6.matcher(server).matches() + || PATTERN_IPV6_6HEX4DEC.matcher(server).matches() + || PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches() + || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches(); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index f6e0bfdc..8a438906 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -26,6 +26,7 @@ import java.net.IDN; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -155,53 +156,62 @@ public class XmppConnection implements Runnable { tagWriter = new TagWriter(); packetCallbacks.clear(); this.changeStatus(Account.State.CONNECTING); - final Bundle result = DNSHelper.getSRVRecord(account.getServer()); - final ArrayList values = result.getParcelableArrayList("values"); - if ("timeout".equals(result.getString("error"))) { - throw new IOException("timeout in dns"); - } else if (values != null) { - int i = 0; - boolean socketError = true; - while (socketError && values.size() > i) { - final Bundle namePort = (Bundle) values.get(i); - try { - String srvRecordServer; + if (DNSHelper.isIp(account.getServer().toString())) { + socket = new Socket(); + try { + socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000); + } catch (IOException e) { + throw new UnknownHostException(); + } + } else { + final Bundle result = DNSHelper.getSRVRecord(account.getServer()); + final ArrayList values = result.getParcelableArrayList("values"); + if ("timeout".equals(result.getString("error"))) { + throw new IOException("timeout in dns"); + } else if (values != null) { + int i = 0; + boolean socketError = true; + while (socketError && values.size() > i) { + final Bundle namePort = (Bundle) values.get(i); try { - srvRecordServer = IDN.toASCII(namePort.getString("name")); - } catch (final IllegalArgumentException e) { - // TODO: Handle me?` - srvRecordServer = ""; - } - final int srvRecordPort = namePort.getInt("port"); - final String srvIpServer = namePort.getString("ip"); - final InetSocketAddress addr; - if (srvIpServer != null) { - addr = new InetSocketAddress(srvIpServer, srvRecordPort); - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() - + ": using values from dns " + srvRecordServer - + "[" + srvIpServer + "]:" + srvRecordPort); - } else { - addr = new InetSocketAddress(srvRecordServer, srvRecordPort); - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() - + ": using values from dns " - + srvRecordServer + ":" + srvRecordPort); + String srvRecordServer; + try { + srvRecordServer = IDN.toASCII(namePort.getString("name")); + } catch (final IllegalArgumentException e) { + // TODO: Handle me?` + srvRecordServer = ""; + } + final int srvRecordPort = namePort.getInt("port"); + final String srvIpServer = namePort.getString("ip"); + final InetSocketAddress addr; + if (srvIpServer != null) { + addr = new InetSocketAddress(srvIpServer, srvRecordPort); + Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + + ": using values from dns " + srvRecordServer + + "[" + srvIpServer + "]:" + srvRecordPort); + } else { + addr = new InetSocketAddress(srvRecordServer, srvRecordPort); + Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + + ": using values from dns " + + srvRecordServer + ":" + srvRecordPort); + } + socket = new Socket(); + socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); + socketError = false; + } catch (final UnknownHostException e) { + Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); + i++; + } catch (final IOException e) { + Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); + i++; } - socket = new Socket(); - socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); - socketError = false; - } catch (final UnknownHostException e) { - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); - i++; - } catch (final IOException e) { - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); - i++; } + if (socketError) { + throw new UnknownHostException(); + } + } else { + throw new IOException("unhandled exception in DNS resolver"); } - if (socketError) { - throw new UnknownHostException(); - } - } else { - throw new IOException("unhandled exception in DNS resolver"); } final OutputStream out = socket.getOutputStream(); tagWriter.setOutputStream(out); -- cgit v1.2.3 From 9b7a606cb03bbaf36fc691f02ef32ab9c158de6d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jun 2015 12:14:42 +0200 Subject: version bump to 1.4.4 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 6d12080f..b57b6c86 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 69 - versionName "1.4.3" + versionCode 72 + versionName "1.4.4" } compileOptions { -- cgit v1.2.3 From 35782636864f4567729b99b4a1c96d9495fcdab1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jun 2015 12:19:33 +0200 Subject: pulled new translations from transifex --- src/main/res/values-ru/strings.xml | 5 +++++ src/main/res/values-sk/strings.xml | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 7b104820..7a57777b 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -450,4 +450,9 @@ Выбрано %d контактов + Заменить кнопку отправки кнопкой быстрого действия + Быстрое действие + Нет + Последнее выбранное + Выбрать быстрое действие diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index aa0fcff7..561f9824 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -110,7 +110,7 @@ Vždy upozorniť pri novej konferenčnej správe, nie len ak je zvýraznená Doba na prečítanie upozornenia Neupozorňovať krátko po obdržaní kópie správy - Pokročilé nastavenia + Rozšírené možnosti Neodosielať detaily o zlyhaní aplikácie Zaslaním detailov o dôvode zlyhania pomáhate ďalšiemu vývoju aplikácie Conversations Potvrdzovať správy @@ -266,7 +266,7 @@ Vždy zasielať šifrované správy (okrem skupinových konverzácií) Neukladať šifrované správy Varovanie: Toto môže viesť k strate správ - Expertné nastavenia + Expertné možnosti S týmto narábajte veľmi opatrne, prosím O Conversations Informácie o tvorbe a licencii @@ -375,7 +375,7 @@ Bez úlohy Vylúčený Člen - Pokročilý režim + Rozšírený režim Povoliť členstvo Odobrať členstvo Povoliť administrátorské výsady @@ -429,11 +429,23 @@ Prijatá poloha Konverzácia zatvorená Opustil skupinovú konverzáciu + Možnosti certifikátu Nedôverovať systému CAs Všetky certifikáty musia byť ručne schválené + Odstrániť certifikáty + Vymazať ručne schválené certifikáty + Žiadne ručne schválené certifikáty + Odstrániť certifikáty + Vymazať výber + Zrušiť Vybrať %d kontaktu Vybrať %d kontaktu Vybrať %d kontaktov + Nahradiť tlačidlo poslať rýchlou akciou + Rýchla akcia + Žiadny + Naposledy použitý + Vybrať rýchlu voľbu -- cgit v1.2.3 From 46595b6d43679f17cb8e374b2120ab7889423555 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 20:11:28 +0200 Subject: fixed parsing of muc status messages in new message parser --- .../siacs/conversations/parser/MessageParser.java | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 96568fbd..946e4b6f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -364,13 +364,25 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.getNotificationService().push(message); } } else { //no body - if (packet.hasChild("subject") && isTypeGroupChat) { + if (isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); - if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); - conversation.getMucOptions().setSubject(packet.findChildContent("subject")); - mXmppConnectionService.updateConversationUi(); - return; + if (packet.hasChild("subject")) { + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); + conversation.getMucOptions().setSubject(packet.findChildContent("subject")); + mXmppConnectionService.updateConversationUi(); + return; + } + } + + final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); + if (conversation != null && x != null && from.isBareJid()) { + for (Element child : x.getChildren()) { + if (child.getName().equals("status") + && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) { + mXmppConnectionService.fetchConferenceConfiguration(conversation); + } + } } } } -- cgit v1.2.3 From 0d01e51da5333cfbc3ac2cb0e381180823203e1b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 22:14:40 +0200 Subject: don't parse body from muc status messages --- .../java/eu/siacs/conversations/parser/MessageParser.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 946e4b6f..5a40b170 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -233,13 +233,15 @@ public class MessageParser extends AbstractParser implements } final String body = packet.getBody(); final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); + final Element mucUserElement = packet.findChild("x","http://jabber.org/protocol/muc#user"); int status; final Jid counterpart; final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; - boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; + boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; + boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); if (packet.fromAccount(account)) { status = Message.STATUS_SEND; counterpart = to; @@ -262,7 +264,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateConversationUi(); } - if (body != null || encrypted != null) { + if ((body != null || encrypted != null) && !isMucStatusMessage) { Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { @@ -283,7 +285,7 @@ public class MessageParser extends AbstractParser implements } Message message; if (body != null && body.startsWith("?OTR")) { - if (!isForwarded && !isTypeGroupChat && properlyAddressed) { + if (!isForwarded && !isTypeGroupChat && isProperlyAddressed) { message = parseOtrChat(body, from, remoteMsgId, conversation); if (message == null) { return; @@ -375,9 +377,8 @@ public class MessageParser extends AbstractParser implements } } - final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); - if (conversation != null && x != null && from.isBareJid()) { - for (Element child : x.getChildren()) { + if (conversation != null && isMucStatusMessage) { + for (Element child : mucUserElement.getChildren()) { if (child.getName().equals("status") && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) { mXmppConnectionService.fetchConferenceConfiguration(conversation); -- cgit v1.2.3 From 6ee11e5323ac3e78caf64d5e205cba9a405f87f8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Jun 2015 15:18:53 +0200 Subject: version bump to 1.4.5 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 03451412..3706aca5 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 72 - versionName "1.4.4" + versionCode 73 + versionName "1.4.5" } compileOptions { -- cgit v1.2.3 From 9eb9a522050589e60bc7c76b2b040b1dadb7fd1d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 11:19:07 +0200 Subject: initial http upload support be careful: little error handling and no encryption --- .../siacs/conversations/entities/Downloadable.java | 32 ++-- .../entities/DownloadablePlaceholder.java | 5 - .../eu/siacs/conversations/entities/Message.java | 8 + .../siacs/conversations/generator/IqGenerator.java | 12 +- .../conversations/generator/MessageGenerator.java | 22 ++- .../siacs/conversations/http/HttpConnection.java | 5 - .../conversations/http/HttpConnectionManager.java | 14 +- .../conversations/http/HttpUploadConnection.java | 164 +++++++++++++++++++++ .../conversations/persistance/FileBackend.java | 2 +- .../services/XmppConnectionService.java | 66 +++++---- .../java/eu/siacs/conversations/utils/Xmlns.java | 1 + .../siacs/conversations/xmpp/XmppConnection.java | 14 +- .../xmpp/jingle/JingleConnection.java | 20 --- .../xmpp/jingle/JingleConnectionManager.java | 8 +- 14 files changed, 278 insertions(+), 95 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java diff --git a/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/src/main/java/eu/siacs/conversations/entities/Downloadable.java index d25bf93a..c32165e8 100644 --- a/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ b/src/main/java/eu/siacs/conversations/entities/Downloadable.java @@ -2,27 +2,25 @@ package eu.siacs.conversations.entities; public interface Downloadable { - public final String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; - public final String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; + String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; + String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; - public static final int STATUS_UNKNOWN = 0x200; - public static final int STATUS_CHECKING = 0x201; - public static final int STATUS_FAILED = 0x202; - public static final int STATUS_OFFER = 0x203; - public static final int STATUS_DOWNLOADING = 0x204; - public static final int STATUS_DELETED = 0x205; - public static final int STATUS_OFFER_CHECK_FILESIZE = 0x206; - public static final int STATUS_UPLOADING = 0x207; + int STATUS_UNKNOWN = 0x200; + int STATUS_CHECKING = 0x201; + int STATUS_FAILED = 0x202; + int STATUS_OFFER = 0x203; + int STATUS_DOWNLOADING = 0x204; + int STATUS_DELETED = 0x205; + int STATUS_OFFER_CHECK_FILESIZE = 0x206; + int STATUS_UPLOADING = 0x207; - public boolean start(); + boolean start(); - public int getStatus(); + int getStatus(); - public long getFileSize(); + long getFileSize(); - public int getProgress(); + int getProgress(); - public String getMimeType(); - - public void cancel(); + void cancel(); } diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java b/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java index 03fceceb..cce22ea3 100644 --- a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java +++ b/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java @@ -27,11 +27,6 @@ public class DownloadablePlaceholder implements Downloadable { return 0; } - @Override - public String getMimeType() { - return ""; - } - @Override public void cancel() { diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index a63d033d..d80400d8 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -586,6 +586,14 @@ public class Message extends AbstractEntity { return type == TYPE_FILE || type == TYPE_IMAGE; } + public boolean hasFileOnRemoteHost() { + return isFileOrImage() && getImageParams().url != null; + } + + public boolean needsUploading() { + return isFileOrImage() && getImageParams().url == null; + } + public class ImageParams { public URL url; public long size = 0; diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index d7366daa..47915e3f 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -6,6 +6,7 @@ import java.util.List; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.PhoneHelper; @@ -102,7 +103,7 @@ public class IqGenerator extends AbstractGenerator { public IqPacket retrieveVcardAvatar(final Avatar avatar) { final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); packet.setTo(avatar.owner); - packet.addChild("vCard","vcard-temp"); + packet.addChild("vCard", "vcard-temp"); return packet; } @@ -194,4 +195,13 @@ public class IqGenerator extends AbstractGenerator { item.setAttribute("role", role); return packet; } + + public IqPacket requestHttpUploadSlot(Jid host, DownloadableFile file) { + IqPacket packet = new IqPacket(IqPacket.TYPE.GET); + packet.setTo(host); + Element request = packet.addChild("request",Xmlns.HTTP_UPLOAD); + request.addChild("filename").setContent(file.getName()); + request.addChild("size").setContent(String.valueOf(file.getExpectedSize())); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 474a3e1d..b7a4efca 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -73,7 +73,13 @@ public class MessageGenerator extends AbstractGenerator { packet.addChild("no-copy", "urn:xmpp:hints"); packet.addChild("no-permanent-store", "urn:xmpp:hints"); try { - packet.setBody(otrSession.transformSending(message.getBody())[0]); + String content; + if (message.hasFileOnRemoteHost()) { + content = message.getImageParams().url.toString(); + } else { + content = message.getBody(); + } + packet.setBody(otrSession.transformSending(content)[0]); return packet; } catch (OtrException e) { return null; @@ -86,7 +92,11 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generateChat(Message message, boolean addDelay) { MessagePacket packet = preparePacket(message, addDelay); - packet.setBody(message.getBody()); + if (message.hasFileOnRemoteHost()) { + packet.setBody(message.getImageParams().url.toString()); + } else { + packet.setBody(message.getBody()); + } return packet; } @@ -96,13 +106,11 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generatePgpChat(Message message, boolean addDelay) { MessagePacket packet = preparePacket(message, addDelay); - packet.setBody("This is an XEP-0027 encryted message"); + packet.setBody("This is an XEP-0027 encrypted message"); if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - packet.addChild("x", "jabber:x:encrypted").setContent( - message.getEncryptedBody()); + packet.addChild("x", "jabber:x:encrypted").setContent(message.getEncryptedBody()); } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - packet.addChild("x", "jabber:x:encrypted").setContent( - message.getBody()); + packet.addChild("x", "jabber:x:encrypted").setContent(message.getBody()); } return packet; } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index e7d30919..d2550b47 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -302,9 +302,4 @@ public class HttpConnection implements Downloadable { public int getProgress() { return this.mProgress; } - - @Override - public String getMimeType() { - return ""; - } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index 9a2a2405..fc266e7b 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -13,7 +13,8 @@ public class HttpConnectionManager extends AbstractConnectionManager { super(service); } - private List connections = new CopyOnWriteArrayList(); + private List connections = new CopyOnWriteArrayList<>(); + private List uploadConnections = new CopyOnWriteArrayList<>(); public HttpConnection createNewConnection(Message message) { HttpConnection connection = new HttpConnection(this); @@ -22,7 +23,18 @@ public class HttpConnectionManager extends AbstractConnectionManager { return connection; } + public HttpUploadConnection createNewUploadConnection(Message message) { + HttpUploadConnection connection = new HttpUploadConnection(this); + connection.init(message); + this.uploadConnections.add(connection); + return connection; + } + public void finishConnection(HttpConnection connection) { this.connections.remove(connection); } + + public void finishUploadConnection(HttpUploadConnection httpUploadConnection) { + this.uploadConnections.remove(httpUploadConnection); + } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java new file mode 100644 index 00000000..e16d93e1 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -0,0 +1,164 @@ +package eu.siacs.conversations.http; + +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.persistance.FileBackend; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.Xmlns; +import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xmpp.OnIqPacketReceived; +import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.IqPacket; + +public class HttpUploadConnection implements Downloadable { + + private HttpConnectionManager mHttpConnectionManager; + private XmppConnectionService mXmppConnectionService; + + private boolean canceled = false; + private Account account; + private DownloadableFile file; + private Message message; + private URL mGetUrl; + private URL mPutUrl; + + private long transmitted = 0; + private long expected = 1; + + public HttpUploadConnection(HttpConnectionManager httpConnectionManager) { + this.mHttpConnectionManager = httpConnectionManager; + this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService(); + } + + @Override + public boolean start() { + return false; + } + + @Override + public int getStatus() { + return STATUS_UPLOADING; + } + + @Override + public long getFileSize() { + return this.file.getExpectedSize(); + } + + @Override + public int getProgress() { + return (int) ((((double) transmitted) / expected) * 100); + } + + @Override + public void cancel() { + this.canceled = true; + } + + private void fail() { + mHttpConnectionManager.finishUploadConnection(this); + message.setDownloadable(null); + mXmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); + } + + public void init(Message message) { + this.message = message; + message.setDownloadable(this); + mXmppConnectionService.markMessage(message,Message.STATUS_UNSEND); + this.account = message.getConversation().getAccount(); + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + this.file.setExpectedSize(this.file.getSize()); + Jid host = account.getXmppConnection().findDiscoItemByFeature(Xmlns.HTTP_UPLOAD); + IqPacket request = mXmppConnectionService.getIqGenerator().requestHttpUploadSlot(host,file); + mXmppConnectionService.sendIqPacket(account, request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element slot = packet.findChild("slot",Xmlns.HTTP_UPLOAD); + if (slot != null) { + try { + mGetUrl = new URL(slot.findChildContent("get")); + mPutUrl = new URL(slot.findChildContent("put")); + if (!canceled) { + new Thread(new FileUploader()).start(); + } + } catch (MalformedURLException e) { + fail(); + } + } else { + fail(); + } + } else { + fail(); + } + } + }); + } + + private class FileUploader implements Runnable { + + @Override + public void run() { + this.upload(); + } + + private void upload() { + OutputStream os = null; + InputStream is = null; + HttpURLConnection connection = null; + try { + Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString()); + connection = (HttpURLConnection) mPutUrl.openConnection(); + connection.setRequestMethod("PUT"); + connection.setFixedLengthStreamingMode((int) file.getExpectedSize()); + connection.setDoOutput(true); + connection.connect(); + os = connection.getOutputStream(); + is = file.createInputStream(); + transmitted = 0; + expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[4096]; + while (((count = is.read(buffer)) != -1) && !canceled) { + transmitted += count; + os.write(buffer, 0, count); + mXmppConnectionService.updateConversationUi(); + } + os.flush(); + os.close(); + is.close(); + int code = connection.getResponseCode(); + if (code == 200) { + Log.d(Config.LOGTAG, "finished uploading file"); + Message.ImageParams params = message.getImageParams(); + message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height)); + message.setDownloadable(null); + mXmppConnectionService.resendMessage(message); + } else { + fail(); + } + } catch (IOException e) { + Log.d(Config.LOGTAG, e.getMessage()); + fail(); + } finally { + FileBackend.close(is); + FileBackend.close(os); + if (connection != null) { + connection.disconnect(); + } + } + } + } +} diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index e120adbd..e1de0b23 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -217,7 +217,7 @@ public class FileBackend { long size = file.getSize(); int width = scaledBitmap.getWidth(); int height = scaledBitmap.getHeight(); - message.setBody(Long.toString(size) + ',' + width + ',' + height); + message.setBody(Long.toString(size) + '|' + width + '|' + height); return file; } catch (FileNotFoundException e) { throw new FileCopyException(R.string.error_file_not_found); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0a264dd1..90b2ee17 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -390,7 +390,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.success(message); } } catch (FileBackend.FileCopyException e) { - callback.error(e.getResId(),message); + callback.error(e.getResId(), message); } } }); @@ -671,6 +671,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + private void sendFileMessage(final Message message) { + Log.d(Config.LOGTAG, "send file message"); + final Account account = message.getConversation().getAccount(); + final XmppConnection connection = account.getXmppConnection(); + if (connection != null && connection.getFeatures().httpUpload()) { + mHttpConnectionManager.createNewUploadConnection(message); + } else { + mJingleConnectionManager.createNewConnection(message); + } + } + public void sendMessage(final Message message) { final Account account = message.getConversation().getAccount(); account.deactivateGracePeriod(); @@ -680,7 +691,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa boolean send = false; if (account.getStatus() == Account.State.ONLINE && account.getXmppConnection() != null) { - if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + if (message.needsUploading()) { if (message.getCounterpart() != null) { if (message.getEncryption() == Message.ENCRYPTION_OTR) { if (!conv.hasValidOtrSession()) { @@ -688,11 +699,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa message.setStatus(Message.STATUS_WAITING); } else if (conv.hasValidOtrSession() && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - mJingleConnectionManager - .createNewConnection(message); - } + mJingleConnectionManager.createNewConnection(message); + } } else { - mJingleConnectionManager.createNewConnection(message); + this.sendFileMessage(message); + } } else { if (message.getEncryption() == Message.ENCRYPTION_OTR) { @@ -791,12 +802,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - private void resendMessage(final Message message) { + public void resendMessage(final Message message) { Account account = message.getConversation().getAccount(); MessagePacket packet = null; if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Presences presences = message.getConversation().getContact() - .getPresences(); + Presences presences = message.getConversation().getContact().getPresences(); if (!message.getConversation().hasValidOtrSession()) { if ((message.getCounterpart() != null) && (presences.has(message.getCounterpart().getResourcepart()))) { @@ -808,34 +818,25 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } } else { - if (message.getConversation().getOtrSession() - .getSessionStatus() == SessionStatus.ENCRYPTED) { + if (message.getConversation().getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { try { message.setCounterpart(Jid.fromSessionID(message.getConversation().getOtrSession().getSessionID())); - if (message.getType() == Message.TYPE_TEXT) { - packet = mMessageGenerator.generateOtrChat(message, - true); - } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + if (message.needsUploading()) { mJingleConnectionManager.createNewConnection(message); + } else { + packet = mMessageGenerator.generateOtrChat(message, true); } } catch (final InvalidJidException ignored) { } - } + } } - } else if (message.getType() == Message.TYPE_TEXT) { - if (message.getEncryption() == Message.ENCRYPTION_NONE) { - packet = mMessageGenerator.generateChat(message, true); - } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED) - || (message.getEncryption() == Message.ENCRYPTION_PGP)) { - packet = mMessageGenerator.generatePgpChat(message, true); - } - } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + } else if (message.needsUploading()) { Contact contact = message.getConversation().getContact(); Presences presences = contact.getPresences(); if ((message.getCounterpart() != null) && (presences.has(message.getCounterpart().getResourcepart()))) { - mJingleConnectionManager.createNewConnection(message); + this.sendFileMessage(message); } else { if (presences.size() == 1) { String presence = presences.asStringArray()[0]; @@ -844,9 +845,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } catch (InvalidJidException e) { return; } - mJingleConnectionManager.createNewConnection(message); + this.sendFileMessage(message); } } + } else { + if (message.getEncryption() == Message.ENCRYPTION_NONE) { + packet = mMessageGenerator.generateChat(message, true); + } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED) + || (message.getEncryption() == Message.ENCRYPTION_PGP)) { + packet = mMessageGenerator.generatePgpChat(message, true); + } } if (packet != null) { if (!account.getXmppConnection().getFeatures().sm() @@ -1809,15 +1817,15 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } catch (InvalidJidException e) { return; } - if (message.getType() == Message.TYPE_TEXT) { + if (message.needsUploading()) { + mJingleConnectionManager.createNewConnection(message); + } else { MessagePacket outPacket = mMessageGenerator.generateOtrChat(message, true); if (outPacket != null) { message.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(message); sendMessagePacket(account, outPacket); } - } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { - mJingleConnectionManager.createNewConnection(message); } updateConversationUi(); } diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index 17fd2d26..de0a29ce 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -5,4 +5,5 @@ public final class Xmlns { public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; + public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 8a438906..87dfb897 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1025,18 +1025,18 @@ public class XmppConnection implements Runnable { this.streamId = null; } - public List findDiscoItemsByFeature(final String feature) { - final List items = new ArrayList<>(); + public List findDiscoItemsByFeature(final String feature) { + final List items = new ArrayList<>(); for (final Entry cursor : disco.entrySet()) { if (cursor.getValue().features.contains(feature)) { - items.add(cursor.getKey().toString()); + items.add(cursor.getKey()); } } return items; } - public String findDiscoItemByFeature(final String feature) { - final List items = findDiscoItemsByFeature(feature); + public Jid findDiscoItemByFeature(final String feature) { + final List items = findDiscoItemsByFeature(feature); if (items.size() >= 1) { return items.get(0); } @@ -1191,6 +1191,10 @@ public class XmppConnection implements Runnable { public void setBlockListRequested(boolean value) { this.blockListRequested = value; } + + public boolean httpUpload() { + return findDiscoItemsByFeature(Xmlns.HTTP_UPLOAD).size() > 0; + } } private IqGenerator getIqGenerator() { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index c9bb9c93..8e4282a9 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -954,24 +954,4 @@ public class JingleConnection implements Downloadable { public int getProgress() { return this.mProgress; } - - @Override - public String getMimeType() { - if (this.message.getType() == Message.TYPE_FILE) { - String mime = null; - String path = this.message.getRelativeFilePath(); - if (path != null && !this.message.getRelativeFilePath().isEmpty()) { - mime = URLConnection.guessContentTypeFromName(this.message.getRelativeFilePath()); - if (mime!=null) { - return mime; - } else { - return ""; - } - } else { - return ""; - } - } else { - return "image/webp"; - } - } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index c19dd04c..f0cf5d8a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -87,10 +87,10 @@ public class JingleConnectionManager extends AbstractConnectionManager { return; } if (!this.primaryCandidates.containsKey(account.getJid().toBareJid())) { - final String proxy = account.getXmppConnection().findDiscoItemByFeature(Xmlns.BYTE_STREAMS); + final Jid proxy = account.getXmppConnection().findDiscoItemByFeature(Xmlns.BYTE_STREAMS); if (proxy != null) { IqPacket iq = new IqPacket(IqPacket.TYPE.GET); - iq.setAttribute("to", proxy); + iq.setTo(proxy); iq.query(Xmlns.BYTE_STREAMS); account.getXmppConnection().sendIqPacket(iq,new OnIqPacketReceived() { @@ -105,11 +105,11 @@ public class JingleConnectionManager extends AbstractConnectionManager { candidate.setHost(host); candidate.setPort(Integer.parseInt(port)); candidate.setType(JingleCandidate.TYPE_PROXY); - candidate.setJid(Jid.fromString(proxy)); + candidate.setJid(proxy); candidate.setPriority(655360 + 65535); primaryCandidates.put(account.getJid().toBareJid(),candidate); listener.onPrimaryCandidateFound(true,candidate); - } catch (final NumberFormatException | InvalidJidException e) { + } catch (final NumberFormatException e) { listener.onPrimaryCandidateFound(false,null); return; } -- cgit v1.2.3 From 7e11570f2c2eeeab17b4c024442bb849b40899df Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 13:14:21 +0200 Subject: show attach button in conferences when http upload is available --- src/main/java/eu/siacs/conversations/entities/Account.java | 4 ++++ .../eu/siacs/conversations/http/HttpUploadConnection.java | 1 + .../siacs/conversations/services/XmppConnectionService.java | 5 ++--- .../java/eu/siacs/conversations/ui/ConversationActivity.java | 11 +++++++---- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 6e6dcb6a..f472361f 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -44,6 +44,10 @@ public class Account extends AbstractEntity { public static final int OPTION_REGISTER = 2; public static final int OPTION_USECOMPRESSION = 3; + public boolean httpUploadAvailable() { + return xmppConnection != null && xmppConnection.getFeatures().httpUpload(); + } + public static enum State { DISABLED, OFFLINE, diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index e16d93e1..32e8cdff 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -145,6 +145,7 @@ public class HttpUploadConnection implements Downloadable { Message.ImageParams params = message.getImageParams(); message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height)); message.setDownloadable(null); + message.setCounterpart(message.getConversation().getJid().toBareJid()); mXmppConnectionService.resendMessage(message); } else { fail(); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 90b2ee17..877806f3 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -692,7 +692,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (account.getStatus() == Account.State.ONLINE && account.getXmppConnection() != null) { if (message.needsUploading()) { - if (message.getCounterpart() != null) { + if (message.getCounterpart() != null || account.httpUploadAvailable()) { if (message.getEncryption() == Message.ENCRYPTION_OTR) { if (!conv.hasValidOtrSession()) { conv.startOtrSession(message.getCounterpart().getResourcepart(),true); @@ -834,8 +834,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else if (message.needsUploading()) { Contact contact = message.getConversation().getContact(); Presences presences = contact.getPresences(); - if ((message.getCounterpart() != null) - && (presences.has(message.getCounterpart().getResourcepart()))) { + if (account.httpUploadAvailable() || (message.getCounterpart() != null && presences.has(message.getCounterpart().getResourcepart()))) { this.sendFileMessage(message); } else { if (presences.size() == 1) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index c48b5865..770129ab 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -35,6 +35,7 @@ import java.util.Iterator; import java.util.List; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -382,7 +383,7 @@ public class ConversationActivity extends XmppActivity } if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { menuContactDetails.setVisible(false); - menuAttach.setVisible(false); + menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable()); menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); } else { menuMucDetails.setVisible(false); @@ -398,6 +399,8 @@ public class ConversationActivity extends XmppActivity } private void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) { + final Conversation conversation = getSelectedConversation(); + final Account account = conversation.getAccount(); final OnPresenceSelected callback = new OnPresenceSelected() { @Override @@ -449,11 +452,11 @@ public class ConversationActivity extends XmppActivity } } }; - if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) { - getSelectedConversation().setNextCounterpart(null); + if ((account.httpUploadAvailable() || attachmentChoice == ATTACHMENT_CHOICE_LOCATION) && encryption != Message.ENCRYPTION_OTR) { + conversation.setNextCounterpart(null); callback.onPresenceSelected(); } else { - selectPresence(getSelectedConversation(),callback); + selectPresence(conversation,callback); } } -- cgit v1.2.3 From 82714dedfe33651eff587e6fb0d2dc0fc4a5d3b8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Jun 2015 00:14:37 +0200 Subject: make quick actions available in conferences when file attachment is available --- .../conversations/ui/ConversationFragment.java | 51 ++++++++++++---------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index a817b27b..419e4e52 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -912,7 +912,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final SendButtonAction action; final int status; final boolean empty = this.mEditMessage == null || this.mEditMessage.getText().length() == 0; - if (c.getMode() == Conversation.MODE_MULTI) { + final boolean conference = c.getMode() == Conversation.MODE_MULTI; + if (conference && !c.getAccount().httpUploadAvailable()) { if (empty && c.getNextCounterpart() != null) { action = SendButtonAction.CANCEL; } else { @@ -920,28 +921,32 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } } else { if (empty) { - String setting = activity.getPreferences().getString("quick_action","recent"); - if (!setting.equals("none") && UIHelper.receivedLocationQuestion(conversation.getLatestMessage())) { - setting = "location"; - } else if (setting.equals("recent")) { - setting = activity.getPreferences().getString("recently_used_quick_action","text"); - } - switch (setting) { - case "photo": - action = SendButtonAction.TAKE_PHOTO; - break; - case "location": - action = SendButtonAction.SEND_LOCATION; - break; - case "voice": - action = SendButtonAction.RECORD_VOICE; - break; - case "picture": - action = SendButtonAction.CHOOSE_PICTURE; - break; - default: - action = SendButtonAction.TEXT; - break; + if (conference && c.getNextCounterpart() != null) { + action = SendButtonAction.CANCEL; + } else { + String setting = activity.getPreferences().getString("quick_action", "recent"); + if (!setting.equals("none") && UIHelper.receivedLocationQuestion(conversation.getLatestMessage())) { + setting = "location"; + } else if (setting.equals("recent")) { + setting = activity.getPreferences().getString("recently_used_quick_action", "text"); + } + switch (setting) { + case "photo": + action = SendButtonAction.TAKE_PHOTO; + break; + case "location": + action = SendButtonAction.SEND_LOCATION; + break; + case "voice": + action = SendButtonAction.RECORD_VOICE; + break; + case "picture": + action = SendButtonAction.CHOOSE_PICTURE; + break; + default: + action = SendButtonAction.TEXT; + break; + } } } else { action = SendButtonAction.TEXT; -- cgit v1.2.3 From fdd46f1c913e9ca7e23643ed58b67900d7659a5d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Jun 2015 02:04:58 +0200 Subject: added trigger to Config.java to always enable aes encryption for uploaded files --- src/main/java/eu/siacs/conversations/Config.java | 2 ++ .../eu/siacs/conversations/http/HttpUploadConnection.java | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 779cbbe8..f6ff00cf 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -32,6 +32,8 @@ public final class Config { public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption + public static final boolean ENCRYPT_ON_HTTP_UPLOADED = true; + public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; public static final int MAM_MAX_MESSAGES = 500; diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 32e8cdff..25d8d6fa 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -16,6 +16,7 @@ import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; @@ -34,6 +35,8 @@ public class HttpUploadConnection implements Downloadable { private URL mGetUrl; private URL mPutUrl; + private byte[] key = null; + private long transmitted = 0; private long expected = 1; @@ -80,6 +83,13 @@ public class HttpUploadConnection implements Downloadable { this.account = message.getConversation().getAccount(); this.file = mXmppConnectionService.getFileBackend().getFile(message, false); this.file.setExpectedSize(this.file.getSize()); + + if (Config.ENCRYPT_ON_HTTP_UPLOADED) { + this.key = new byte[48]; + mXmppConnectionService.getRNG().nextBytes(this.key); + this.file.setKey(this.key); + } + Jid host = account.getXmppConnection().findDiscoItemByFeature(Xmlns.HTTP_UPLOAD); IqPacket request = mXmppConnectionService.getIqGenerator().requestHttpUploadSlot(host,file); mXmppConnectionService.sendIqPacket(account, request, new OnIqPacketReceived() { @@ -143,6 +153,9 @@ public class HttpUploadConnection implements Downloadable { if (code == 200) { Log.d(Config.LOGTAG, "finished uploading file"); Message.ImageParams params = message.getImageParams(); + if (key != null) { + mGetUrl = new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)); + } message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height)); message.setDownloadable(null); message.setCounterpart(message.getConversation().getJid().toBareJid()); -- cgit v1.2.3 From 0030bbf472910c3ce421c3ba90d91b8c5f00102b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Jun 2015 15:38:16 +0200 Subject: untested pgp support for http upload --- .../eu/siacs/conversations/crypto/PgpEngine.java | 14 ++++++++----- .../conversations/http/HttpUploadConnection.java | 23 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index ad5a4132..ca255cfc 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -143,11 +143,15 @@ public class PgpEngine { params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message .getConversation().getAccount().getJid().toBareJid().toString()); - if (message.getType() == Message.TYPE_TEXT) { + if (!message.needsUploading()) { params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - - InputStream is = new ByteArrayInputStream(message.getBody() - .getBytes()); + String body; + if (message.hasFileOnRemoteHost()) { + body = message.getImageParams().url.toString(); + } else { + body = message.getBody(); + } + InputStream is = new ByteArrayInputStream(body.getBytes()); final OutputStream os = new ByteArrayOutputStream(); api.executeApiAsync(params, is, os, new IOpenPgpCallback() { @@ -184,7 +188,7 @@ public class PgpEngine { } } }); - } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + } else { try { DownloadableFile inputFile = this.mXmppConnectionService .getFileBackend().getFile(message, true); diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 25d8d6fa..099cf354 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.http; +import android.app.PendingIntent; import android.util.Log; import java.io.IOException; @@ -16,6 +17,7 @@ import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.UiCallback; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; @@ -159,7 +161,26 @@ public class HttpUploadConnection implements Downloadable { message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height)); message.setDownloadable(null); message.setCounterpart(message.getConversation().getJid().toBareJid()); - mXmppConnectionService.resendMessage(message); + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { + mXmppConnectionService.getPgpEngine().encrypt(message, new UiCallback() { + @Override + public void success(Message message) { + mXmppConnectionService.resendMessage(message); + } + + @Override + public void error(int errorCode, Message object) { + fail(); + } + + @Override + public void userInputRequried(PendingIntent pi, Message object) { + fail(); + } + }); + } else { + mXmppConnectionService.resendMessage(message); + } } else { fail(); } -- cgit v1.2.3 From a2a1f1e0847952c1b6f08f003cd78ad5520a3db6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Jun 2015 15:45:49 +0200 Subject: updated changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61980b61..1170e5a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ###Changelog +####Version 1.4.5 +* fixes to message parser to not display some ejabberd muc status messages + +####Version 1.4.4 +* added unread count badges on supported devices +* rewrote message parser + ####Version 1.4.0 * send button turns into quick action button to offer faster access to take photo, send location or record audio * visually seperate merged messages -- cgit v1.2.3 From 5b42b392a162efb1b503ec2f052bddf34b3bbcf0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 13:01:04 +0200 Subject: always show copy original url in context menu when url is available --- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 419e4e52..f7022ee5 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -452,8 +452,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (m.getStatus() != Message.STATUS_SEND_FAILED) { sendAgain.setVisible(false); } - if (((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) - || m.getImageParams().url == null) && !GeoHelper.isGeoUri(m.getBody())) { + if (!m.hasFileOnRemoteHost() && !GeoHelper.isGeoUri(m.getBody())) { copyUrl.setVisible(false); } if (m.getType() != Message.TYPE_TEXT -- cgit v1.2.3 From d7de3113795738ada1488f673f6e7b651e166058 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 13:52:53 +0200 Subject: refactored bodyContainsDownloadable to be more flexible --- .../eu/siacs/conversations/crypto/PgpEngine.java | 2 +- .../eu/siacs/conversations/entities/Message.java | 68 +++++++++++----------- .../siacs/conversations/parser/MessageParser.java | 2 +- .../conversations/persistance/FileBackend.java | 2 +- .../conversations/ui/ConversationFragment.java | 2 +- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index ca255cfc..936e046c 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -59,7 +59,7 @@ public class PgpEngine { message.setEncryption(Message.ENCRYPTION_DECRYPTED); final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() - && message.bodyContainsDownloadable() + && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index d80400d8..bf68d018 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -375,8 +375,8 @@ public class Message extends AbstractEntity { (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !GeoHelper.isGeoUri(message.getBody()) && !GeoHelper.isGeoUri(this.body) && - !message.bodyContainsDownloadable() && - !this.bodyContainsDownloadable() && + message.treatAsDownloadable() == Decision.NO && + this.treatAsDownloadable() == Decision.NO && !message.getBody().startsWith(ME_COMMAND) && !this.getBody().startsWith(ME_COMMAND) && !this.bodyIsHeart() && @@ -434,48 +434,50 @@ public class Message extends AbstractEntity { return (status > STATUS_RECEIVED || (contact != null && contact.trusted())); } - public boolean bodyContainsDownloadable() { - /** - * there are a few cases where spaces result in an unwanted behavior, e.g. - * "http://example.com/image.jpg text that will not be shown /abc.png" - * or more than one image link in one message. - */ + public enum Decision { + YES, + NO, + ASK + } + + public Decision treatAsDownloadable() { if (body.trim().contains(" ")) { - return false; + return Decision.NO; } try { URL url = new URL(body); - if (!url.getProtocol().equalsIgnoreCase("http") - && !url.getProtocol().equalsIgnoreCase("https")) { - return false; + if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { + return Decision.NO; } - - String sUrlPath = url.getPath(); - if (sUrlPath == null || sUrlPath.isEmpty()) { - return false; + String path = url.getPath(); + if (path == null || path.isEmpty()) { + return Decision.NO; } - int iSlashIndex = sUrlPath.lastIndexOf('/') + 1; - - String sLastUrlPath = sUrlPath.substring(iSlashIndex).toLowerCase(); - - String[] extensionParts = sLastUrlPath.split("\\."); - if (extensionParts.length == 2 - && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 1])) { - return true; - } else if (extensionParts.length == 3 - && Arrays + String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); + String[] extensionParts = filename.split("\\."); + String extension; + String ref = url.getRef(); + if (extensionParts.length == 2) { + extension = extensionParts[extensionParts.length - 1]; + } else if (extensionParts.length == 3 && Arrays .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) - .contains(extensionParts[extensionParts.length - 1]) - && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 2])) { - return true; + .contains(extensionParts[extensionParts.length - 1])) { + extension = extensionParts[extensionParts.length -2]; } else { - return false; + return Decision.NO; } + + if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + return Decision.YES; + } else if (ref != null && ref.matches("([A-Fa-f0-9]{2}){48}")) { + return Decision.ASK; + } else { + return Decision.NO; + } + } catch (MalformedURLException e) { - return false; + return Decision.NO; } } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a40b170..6d2aebf2 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -360,7 +360,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + if (message.trusted() && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index e1de0b23..6d37bbd5 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -497,7 +497,7 @@ public class FileBackend { message.setBody(url.toString()+"|"+Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight); } } else { - message.setBody(Long.toString(file.getSize())); + message.setBody(url.toString()+"|"+Long.toString(file.getSize())); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index f7022ee5..b7400a94 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -457,7 +457,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null - || !m.bodyContainsDownloadable()) { + || m.treatAsDownloadable() == Message.Decision.NO) { downloadImage.setVisible(false); } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) -- cgit v1.2.3 From 6af97c724cdcc7d94070a99e9035d84373c5eb75 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 14:04:39 +0200 Subject: made storage path decision entirely based upon file extension --- src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 6d37bbd5..c20cfa0e 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -13,6 +13,7 @@ import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; import java.util.Locale; @@ -32,6 +33,7 @@ import android.webkit.MimeTypeMap; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; @@ -78,10 +80,10 @@ public class FileBackend { if (path.startsWith("/")) { return new DownloadableFile(path); } else { - if (message.getType() == Message.TYPE_FILE) { + if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { return new DownloadableFile(getConversationsFileDirectory() + path); } else { - return new DownloadableFile(getConversationsImageDirectory()+path); + return new DownloadableFile(getConversationsImageDirectory() + path); } } } -- cgit v1.2.3 From aca9d8036c53c0d0689ed94d67d7c5071d74b14e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 17:15:02 +0200 Subject: made httpconnection (download) ready all kind of files --- .../eu/siacs/conversations/crypto/PgpEngine.java | 4 +- .../eu/siacs/conversations/entities/Message.java | 108 +++++++++++---------- .../conversations/generator/MessageGenerator.java | 4 +- .../siacs/conversations/http/HttpConnection.java | 4 +- .../conversations/http/HttpUploadConnection.java | 4 +- .../conversations/persistance/FileBackend.java | 6 +- .../conversations/ui/ConversationFragment.java | 2 +- .../ui/adapter/ConversationAdapter.java | 3 +- .../conversations/ui/adapter/MessageAdapter.java | 8 +- 9 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index 936e046c..32b9b924 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -98,7 +98,7 @@ public class PgpEngine { switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: - URL url = message.getImageParams().url; + URL url = message.getFileParams().url; mXmppConnectionService.getFileBackend().updateFileParams(message,url); message.setEncryption(Message.ENCRYPTION_DECRYPTED); PgpEngine.this.mXmppConnectionService @@ -147,7 +147,7 @@ public class PgpEngine { params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); String body; if (message.hasFileOnRemoteHost()) { - body = message.getImageParams().url.toString(); + body = message.getFileParams().url.toString(); } else { body = message.getBody(); } diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index bf68d018..1f622bf4 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -485,12 +485,12 @@ public class Message extends AbstractEntity { return body != null && UIHelper.HEARTS.contains(body.trim()); } - public ImageParams getImageParams() { - ImageParams params = getLegacyImageParams(); + public FileParams getFileParams() { + FileParams params = getLegacyFileParams(); if (params != null) { return params; } - params = new ImageParams(); + params = new FileParams(); if (this.downloadable != null) { params.size = this.downloadable.getFileSize(); } @@ -498,61 +498,64 @@ public class Message extends AbstractEntity { return params; } String parts[] = body.split("\\|"); - if (parts.length == 1) { - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - params.origin = parts[0]; + switch (parts.length) { + case 1: + try { + params.size = Long.parseLong(parts[0]); + } catch (NumberFormatException e) { + try { + params.url = new URL(parts[0]); + } catch (MalformedURLException e1) { + params.url = null; + } + } + break; + case 2: + case 4: try { params.url = new URL(parts[0]); } catch (MalformedURLException e1) { params.url = null; } - } - } else if (parts.length == 3) { - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[1]); - } catch (NumberFormatException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - params.height = 0; - } - } else if (parts.length == 4) { - params.origin = parts[0]; - try { - params.url = new URL(parts[0]); - } catch (MalformedURLException e1) { - params.url = null; - } - try { - params.size = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[3]); - } catch (NumberFormatException e) { - params.height = 0; - } + try { + params.size = Long.parseLong(parts[1]); + } catch (NumberFormatException e) { + params.size = 0; + } + try { + params.width = Integer.parseInt(parts[2]); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + params.width = 0; + } + try { + params.height = Integer.parseInt(parts[3]); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + params.height = 0; + } + break; + case 3: + try { + params.size = Long.parseLong(parts[0]); + } catch (NumberFormatException e) { + params.size = 0; + } + try { + params.width = Integer.parseInt(parts[1]); + } catch (NumberFormatException e) { + params.width = 0; + } + try { + params.height = Integer.parseInt(parts[2]); + } catch (NumberFormatException e) { + params.height = 0; + } + break; } return params; } - public ImageParams getLegacyImageParams() { - ImageParams params = new ImageParams(); + public FileParams getLegacyFileParams() { + FileParams params = new FileParams(); if (body == null) { return params; } @@ -589,18 +592,17 @@ public class Message extends AbstractEntity { } public boolean hasFileOnRemoteHost() { - return isFileOrImage() && getImageParams().url != null; + return isFileOrImage() && getFileParams().url != null; } public boolean needsUploading() { - return isFileOrImage() && getImageParams().url == null; + return isFileOrImage() && getFileParams().url == null; } - public class ImageParams { + public class FileParams { public URL url; public long size = 0; public int width = 0; public int height = 0; - public String origin; } } diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index b7a4efca..bc1148d9 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -75,7 +75,7 @@ public class MessageGenerator extends AbstractGenerator { try { String content; if (message.hasFileOnRemoteHost()) { - content = message.getImageParams().url.toString(); + content = message.getFileParams().url.toString(); } else { content = message.getBody(); } @@ -93,7 +93,7 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generateChat(Message message, boolean addDelay) { MessagePacket packet = preparePacket(message, addDelay); if (message.hasFileOnRemoteHost()) { - packet.setBody(message.getImageParams().url.toString()); + packet.setBody(message.getFileParams().url.toString()); } else { packet.setBody(message.getBody()); } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index d2550b47..002611dc 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -269,8 +269,8 @@ public class HttpConnection implements Downloadable { } private void updateImageBounds() { - message.setType(Message.TYPE_IMAGE); - mXmppConnectionService.getFileBackend().updateFileParams(message,mUrl); + message.setType(Message.TYPE_FILE); + mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); mXmppConnectionService.updateMessage(message); } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 099cf354..d861f616 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -154,11 +154,11 @@ public class HttpUploadConnection implements Downloadable { int code = connection.getResponseCode(); if (code == 200) { Log.d(Config.LOGTAG, "finished uploading file"); - Message.ImageParams params = message.getImageParams(); + Message.FileParams params = message.getFileParams(); if (key != null) { mGetUrl = new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)); } - message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height)); + mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl); message.setDownloadable(null); message.setCounterpart(message.getConversation().getJid().toBareJid()); if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index c20cfa0e..52373fef 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -499,7 +499,11 @@ public class FileBackend { message.setBody(url.toString()+"|"+Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight); } } else { - message.setBody(url.toString()+"|"+Long.toString(file.getSize())); + if (url != null) { + message.setBody(url.toString()+"|"+Long.toString(file.getSize())); + } else { + message.setBody(Long.toString(file.getSize())); + } } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index b7400a94..445aaa47 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -543,7 +543,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa url = message.getBody(); } else { resId = R.string.image_url; - url = message.getImageParams().url.toString(); + url = message.getFileParams().url.toString(); } if (activity.copyTextToClipboard(url, resId)) { Toast.makeText(activity, R.string.url_copied_to_clipboard, diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index d5b7e4c0..5cbc73ec 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -3,7 +3,6 @@ package eu.siacs.conversations.ui.adapter; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -69,7 +68,7 @@ public class ConversationAdapter extends ArrayAdapter { convName.setTypeface(null, Typeface.NORMAL); } - if (message.getImageParams().width > 0 + if (message.getFileParams().width > 0 && (message.getDownloadable() == null || message.getDownloadable().getStatus() != Downloadable.STATUS_DELETED)) { mLastMessage.setVisibility(View.GONE); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 29dfced2..8648f048 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -32,7 +32,7 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.entities.Message.ImageParams; +import eu.siacs.conversations.entities.Message.FileParams; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.UIHelper; @@ -100,7 +100,7 @@ public class MessageAdapter extends ArrayAdapter { boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI && message.getMergedStatus() <= Message.STATUS_RECEIVED; if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getDownloadable() != null) { - ImageParams params = message.getImageParams(); + FileParams params = message.getFileParams(); if (params.size > (1.5 * 1024 * 1024)) { filesize = params.size / (1024 * 1024)+ " MiB"; } else if (params.size > 0) { @@ -339,7 +339,7 @@ public class MessageAdapter extends ArrayAdapter { } viewHolder.messageBody.setVisibility(View.GONE); viewHolder.image.setVisibility(View.VISIBLE); - ImageParams params = message.getImageParams(); + FileParams params = message.getFileParams(); double target = metrics.density * 288; int scalledW; int scalledH; @@ -494,7 +494,7 @@ public class MessageAdapter extends ArrayAdapter { } else if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { displayImageMessage(viewHolder, message); } else if (message.getType() == Message.TYPE_FILE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { - if (message.getImageParams().width > 0) { + if (message.getFileParams().width > 0) { displayImageMessage(viewHolder,message); } else { displayOpenableMessage(viewHolder, message); -- cgit v1.2.3 From 9190e0307694dae6462c8f8f63589a7bab8ae4bc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 20:11:50 +0200 Subject: changed namespace of the http upload feature --- src/main/java/eu/siacs/conversations/utils/Xmlns.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index de0a29ce..868566d9 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -5,5 +5,5 @@ public final class Xmlns { public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; - public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; + public static final String HTTP_UPLOAD = "eu:siacs:conversations:http:upload"; } -- cgit v1.2.3 From c36238141de719442e3f542019e68e268f2f2265 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 20:19:18 +0200 Subject: disable automatic aes encryption for the time being --- src/main/java/eu/siacs/conversations/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index f6ff00cf..ce91244d 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -32,7 +32,7 @@ public final class Config { public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption - public static final boolean ENCRYPT_ON_HTTP_UPLOADED = true; + public static final boolean ENCRYPT_ON_HTTP_UPLOADED = false; public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; -- cgit v1.2.3 From c20a088ea811ab702244006fa2588cbdf7be0099 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 1 Jul 2015 16:01:18 +0200 Subject: changed mime type handling --- .../eu/siacs/conversations/crypto/PgpEngine.java | 2 +- .../conversations/entities/DownloadableFile.java | 17 +- .../eu/siacs/conversations/entities/Message.java | 85 ++-- .../siacs/conversations/parser/MessageParser.java | 2 +- .../conversations/ui/ConversationFragment.java | 5 +- .../eu/siacs/conversations/utils/MimeUtils.java | 487 +++++++++++++++++++++ .../eu/siacs/conversations/utils/UIHelper.java | 11 +- 7 files changed, 555 insertions(+), 54 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/MimeUtils.java diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index 32b9b924..cba80ba0 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -59,7 +59,7 @@ public class PgpEngine { message.setEncryption(Message.ENCRYPTION_DECRYPTED); final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() - && message.treatAsDownloadable() == Message.Decision.YES + && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java index 7c8f95d1..ae9ba1f1 100644 --- a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java +++ b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java @@ -20,6 +20,8 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import eu.siacs.conversations.Config; +import eu.siacs.conversations.utils.MimeUtils; + import android.util.Log; public class DownloadableFile extends File { @@ -56,16 +58,11 @@ public class DownloadableFile extends File { public String getMimeType() { String path = this.getAbsolutePath(); - try { - String mime = URLConnection.guessContentTypeFromName(path.replace("#","")); - if (mime != null) { - return mime; - } else if (mime == null && path.endsWith(".webp")) { - return "image/webp"; - } else { - return ""; - } - } catch (final StringIndexOutOfBoundsException e) { + int start = path.lastIndexOf('.') + 1; + if (start < path.length()) { + String mime = MimeUtils.guessMimeTypeFromExtension(path.substring(start)); + return mime == null ? "" : mime; + } else { return ""; } } diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 1f622bf4..0b938639 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -9,6 +9,7 @@ import java.util.Arrays; import eu.siacs.conversations.Config; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -375,8 +376,8 @@ public class Message extends AbstractEntity { (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !GeoHelper.isGeoUri(message.getBody()) && !GeoHelper.isGeoUri(this.body) && - message.treatAsDownloadable() == Decision.NO && - this.treatAsDownloadable() == Decision.NO && + message.treatAsDownloadable() == Decision.NEVER && + this.treatAsDownloadable() == Decision.NEVER && !message.getBody().startsWith(ME_COMMAND) && !this.getBody().startsWith(ME_COMMAND) && !this.bodyIsHeart() && @@ -435,49 +436,75 @@ public class Message extends AbstractEntity { } public enum Decision { - YES, - NO, - ASK + MUST, + SHOULD, + NEVER, + } + + private static String extractRelevantExtension(URL url) { + String path = url.getPath(); + if (path == null || path.isEmpty()) { + return null; + } + String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); + String[] extensionParts = filename.split("\\."); + if (extensionParts.length == 2) { + return extensionParts[extensionParts.length - 1]; + } else if (extensionParts.length == 3 && Arrays + .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) + .contains(extensionParts[extensionParts.length - 1])) { + return extensionParts[extensionParts.length -2]; + } + return null; + } + + public String getMimeType() { + if (relativeFilePath != null) { + int start = relativeFilePath.lastIndexOf('.') + 1; + if (start < relativeFilePath.length()) { + return MimeUtils.guessMimeTypeFromExtension(relativeFilePath.substring(start)); + } else { + return null; + } + } else { + try { + return MimeUtils.guessExtensionFromMimeType(extractRelevantExtension(new URL(body.trim()))); + } catch (MalformedURLException e) { + return null; + } + } } public Decision treatAsDownloadable() { if (body.trim().contains(" ")) { - return Decision.NO; + return Decision.NEVER; } try { URL url = new URL(body); if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { - return Decision.NO; + return Decision.NEVER; } - String path = url.getPath(); - if (path == null || path.isEmpty()) { - return Decision.NO; + String extension = extractRelevantExtension(url); + if (extension == null) { + return Decision.NEVER; } - - String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); - String[] extensionParts = filename.split("\\."); - String extension; String ref = url.getRef(); - if (extensionParts.length == 2) { - extension = extensionParts[extensionParts.length - 1]; - } else if (extensionParts.length == 3 && Arrays - .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) - .contains(extensionParts[extensionParts.length - 1])) { - extension = extensionParts[extensionParts.length -2]; - } else { - return Decision.NO; - } + boolean encrypted = ref != null && ref.matches("([A-Fa-f0-9]{2}){48}"); - if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { - return Decision.YES; - } else if (ref != null && ref.matches("([A-Fa-f0-9]{2}){48}")) { - return Decision.ASK; + if (encrypted) { + if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { + return Decision.MUST; + } else { + return Decision.NEVER; + } + } else if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + return Decision.SHOULD; } else { - return Decision.NO; + return Decision.NEVER; } } catch (MalformedURLException e) { - return Decision.NO; + return Decision.NEVER; } } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 6d2aebf2..d1b8c03a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -360,7 +360,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { + if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 445aaa47..a0403335 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -457,7 +457,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null - || m.treatAsDownloadable() == Message.Decision.NO) { + || m.treatAsDownloadable() == Message.Decision.NEVER) { downloadImage.setVisible(false); } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) @@ -505,8 +505,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa activity.xmppConnectionService.getFileBackend() .getJingleFileUri(message)); shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - String path = message.getRelativeFilePath(); - String mime = path == null ? null : URLConnection.guessContentTypeFromName(path); + String mime = message.getMimeType(); if (mime == null) { mime = "image/webp"; } diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java new file mode 100644 index 00000000..a9e89d1b --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.siacs.conversations.utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +/** + * Utilities for dealing with MIME types. + * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap. + */ +public final class MimeUtils { + private static final Map mimeTypeToExtensionMap = new HashMap(); + private static final Map extensionToMimeTypeMap = new HashMap(); + static { + // The following table is based on /etc/mime.types data minus + // chemical/* MIME types and MIME types that don't map to any + // file extensions. We also exclude top-level domain names to + // deal with cases like: + // + // mail.google.com/a/google.com + // + // and "active" MIME types (due to potential security issues). + // Note that this list is _not_ in alphabetical order and must not be sorted. + // The "most popular" extension must come first, so that it's the one returned + // by guessExtensionFromMimeType. + add("application/andrew-inset", "ez"); + add("application/dsptype", "tsp"); + add("application/hta", "hta"); + add("application/mac-binhex40", "hqx"); + add("application/mathematica", "nb"); + add("application/msaccess", "mdb"); + add("application/oda", "oda"); + add("application/ogg", "ogg"); + add("application/ogg", "oga"); + add("application/pdf", "pdf"); + add("application/pgp-keys", "key"); + add("application/pgp-signature", "pgp"); + add("application/pics-rules", "prf"); + add("application/pkix-cert", "cer"); + add("application/rar", "rar"); + add("application/rdf+xml", "rdf"); + add("application/rss+xml", "rss"); + add("application/zip", "zip"); + add("application/vnd.android.package-archive", "apk"); + add("application/vnd.cinderella", "cdy"); + add("application/vnd.ms-pki.stl", "stl"); + add("application/vnd.oasis.opendocument.database", "odb"); + add("application/vnd.oasis.opendocument.formula", "odf"); + add("application/vnd.oasis.opendocument.graphics", "odg"); + add("application/vnd.oasis.opendocument.graphics-template", "otg"); + add("application/vnd.oasis.opendocument.image", "odi"); + add("application/vnd.oasis.opendocument.spreadsheet", "ods"); + add("application/vnd.oasis.opendocument.spreadsheet-template", "ots"); + add("application/vnd.oasis.opendocument.text", "odt"); + add("application/vnd.oasis.opendocument.text-master", "odm"); + add("application/vnd.oasis.opendocument.text-template", "ott"); + add("application/vnd.oasis.opendocument.text-web", "oth"); + add("application/vnd.google-earth.kml+xml", "kml"); + add("application/vnd.google-earth.kmz", "kmz"); + add("application/msword", "doc"); + add("application/msword", "dot"); + add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"); + add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx"); + add("application/vnd.ms-excel", "xls"); + add("application/vnd.ms-excel", "xlt"); + add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"); + add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx"); + add("application/vnd.ms-powerpoint", "ppt"); + add("application/vnd.ms-powerpoint", "pot"); + add("application/vnd.ms-powerpoint", "pps"); + add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"); + add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx"); + add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx"); + add("application/vnd.rim.cod", "cod"); + add("application/vnd.smaf", "mmf"); + add("application/vnd.stardivision.calc", "sdc"); + add("application/vnd.stardivision.draw", "sda"); + add("application/vnd.stardivision.impress", "sdd"); + add("application/vnd.stardivision.impress", "sdp"); + add("application/vnd.stardivision.math", "smf"); + add("application/vnd.stardivision.writer", "sdw"); + add("application/vnd.stardivision.writer", "vor"); + add("application/vnd.stardivision.writer-global", "sgl"); + add("application/vnd.sun.xml.calc", "sxc"); + add("application/vnd.sun.xml.calc.template", "stc"); + add("application/vnd.sun.xml.draw", "sxd"); + add("application/vnd.sun.xml.draw.template", "std"); + add("application/vnd.sun.xml.impress", "sxi"); + add("application/vnd.sun.xml.impress.template", "sti"); + add("application/vnd.sun.xml.math", "sxm"); + add("application/vnd.sun.xml.writer", "sxw"); + add("application/vnd.sun.xml.writer.global", "sxg"); + add("application/vnd.sun.xml.writer.template", "stw"); + add("application/vnd.visio", "vsd"); + add("application/x-abiword", "abw"); + add("application/x-apple-diskimage", "dmg"); + add("application/x-bcpio", "bcpio"); + add("application/x-bittorrent", "torrent"); + add("application/x-cdf", "cdf"); + add("application/x-cdlink", "vcd"); + add("application/x-chess-pgn", "pgn"); + add("application/x-cpio", "cpio"); + add("application/x-debian-package", "deb"); + add("application/x-debian-package", "udeb"); + add("application/x-director", "dcr"); + add("application/x-director", "dir"); + add("application/x-director", "dxr"); + add("application/x-dms", "dms"); + add("application/x-doom", "wad"); + add("application/x-dvi", "dvi"); + add("application/x-font", "pfa"); + add("application/x-font", "pfb"); + add("application/x-font", "gsf"); + add("application/x-font", "pcf"); + add("application/x-font", "pcf.Z"); + add("application/x-freemind", "mm"); + // application/futuresplash isn't IANA, so application/x-futuresplash should come first. + add("application/x-futuresplash", "spl"); + add("application/futuresplash", "spl"); + add("application/x-gnumeric", "gnumeric"); + add("application/x-go-sgf", "sgf"); + add("application/x-graphing-calculator", "gcf"); + add("application/x-gtar", "tgz"); + add("application/x-gtar", "gtar"); + add("application/x-gtar", "taz"); + add("application/x-hdf", "hdf"); + add("application/x-ica", "ica"); + add("application/x-internet-signup", "ins"); + add("application/x-internet-signup", "isp"); + add("application/x-iphone", "iii"); + add("application/x-iso9660-image", "iso"); + add("application/x-jmol", "jmz"); + add("application/x-kchart", "chrt"); + add("application/x-killustrator", "kil"); + add("application/x-koan", "skp"); + add("application/x-koan", "skd"); + add("application/x-koan", "skt"); + add("application/x-koan", "skm"); + add("application/x-kpresenter", "kpr"); + add("application/x-kpresenter", "kpt"); + add("application/x-kspread", "ksp"); + add("application/x-kword", "kwd"); + add("application/x-kword", "kwt"); + add("application/x-latex", "latex"); + add("application/x-lha", "lha"); + add("application/x-lzh", "lzh"); + add("application/x-lzx", "lzx"); + add("application/x-maker", "frm"); + add("application/x-maker", "maker"); + add("application/x-maker", "frame"); + add("application/x-maker", "fb"); + add("application/x-maker", "book"); + add("application/x-maker", "fbdoc"); + add("application/x-mif", "mif"); + add("application/x-ms-wmd", "wmd"); + add("application/x-ms-wmz", "wmz"); + add("application/x-msi", "msi"); + add("application/x-ns-proxy-autoconfig", "pac"); + add("application/x-nwc", "nwc"); + add("application/x-object", "o"); + add("application/x-oz-application", "oza"); + add("application/x-pem-file", "pem"); + add("application/x-pkcs12", "p12"); + add("application/x-pkcs12", "pfx"); + add("application/x-pkcs7-certreqresp", "p7r"); + add("application/x-pkcs7-crl", "crl"); + add("application/x-quicktimeplayer", "qtl"); + add("application/x-shar", "shar"); + add("application/x-shockwave-flash", "swf"); + add("application/x-stuffit", "sit"); + add("application/x-sv4cpio", "sv4cpio"); + add("application/x-sv4crc", "sv4crc"); + add("application/x-tar", "tar"); + add("application/x-texinfo", "texinfo"); + add("application/x-texinfo", "texi"); + add("application/x-troff", "t"); + add("application/x-troff", "roff"); + add("application/x-troff-man", "man"); + add("application/x-ustar", "ustar"); + add("application/x-wais-source", "src"); + add("application/x-wingz", "wz"); + add("application/x-webarchive", "webarchive"); + add("application/x-webarchive-xml", "webarchivexml"); + add("application/x-x509-ca-cert", "crt"); + add("application/x-x509-user-cert", "crt"); + add("application/x-x509-server-cert", "crt"); + add("application/x-xcf", "xcf"); + add("application/x-xfig", "fig"); + add("application/xhtml+xml", "xhtml"); + add("audio/3gpp", "3gpp"); + add("audio/aac", "aac"); + add("audio/aac-adts", "aac"); + add("audio/amr", "amr"); + add("audio/amr-wb", "awb"); + add("audio/basic", "snd"); + add("audio/flac", "flac"); + add("application/x-flac", "flac"); + add("audio/imelody", "imy"); + add("audio/midi", "mid"); + add("audio/midi", "midi"); + add("audio/midi", "ota"); + add("audio/midi", "kar"); + add("audio/midi", "rtttl"); + add("audio/midi", "xmf"); + add("audio/mobile-xmf", "mxmf"); + // add ".mp3" first so it will be the default for guessExtensionFromMimeType + add("audio/mpeg", "mp3"); + add("audio/mpeg", "mpga"); + add("audio/mpeg", "mpega"); + add("audio/mpeg", "mp2"); + add("audio/mpeg", "m4a"); + add("audio/mpegurl", "m3u"); + add("audio/prs.sid", "sid"); + add("audio/x-aiff", "aif"); + add("audio/x-aiff", "aiff"); + add("audio/x-aiff", "aifc"); + add("audio/x-gsm", "gsm"); + add("audio/x-matroska", "mka"); + add("audio/x-mpegurl", "m3u"); + add("audio/x-ms-wma", "wma"); + add("audio/x-ms-wax", "wax"); + add("audio/x-pn-realaudio", "ra"); + add("audio/x-pn-realaudio", "rm"); + add("audio/x-pn-realaudio", "ram"); + add("audio/x-realaudio", "ra"); + add("audio/x-scpls", "pls"); + add("audio/x-sd2", "sd2"); + add("audio/x-wav", "wav"); + // image/bmp isn't IANA, so image/x-ms-bmp should come first. + add("image/x-ms-bmp", "bmp"); + add("image/bmp", "bmp"); + add("image/gif", "gif"); + // image/ico isn't IANA, so image/x-icon should come first. + add("image/x-icon", "ico"); + add("image/ico", "cur"); + add("image/ico", "ico"); + add("image/ief", "ief"); + // add ".jpg" first so it will be the default for guessExtensionFromMimeType + add("image/jpeg", "jpg"); + add("image/jpeg", "jpeg"); + add("image/jpeg", "jpe"); + add("image/pcx", "pcx"); + add("image/png", "png"); + add("image/svg+xml", "svg"); + add("image/svg+xml", "svgz"); + add("image/tiff", "tiff"); + add("image/tiff", "tif"); + add("image/vnd.djvu", "djvu"); + add("image/vnd.djvu", "djv"); + add("image/vnd.wap.wbmp", "wbmp"); + add("image/webp", "webp"); + add("image/x-cmu-raster", "ras"); + add("image/x-coreldraw", "cdr"); + add("image/x-coreldrawpattern", "pat"); + add("image/x-coreldrawtemplate", "cdt"); + add("image/x-corelphotopaint", "cpt"); + add("image/x-jg", "art"); + add("image/x-jng", "jng"); + add("image/x-photoshop", "psd"); + add("image/x-portable-anymap", "pnm"); + add("image/x-portable-bitmap", "pbm"); + add("image/x-portable-graymap", "pgm"); + add("image/x-portable-pixmap", "ppm"); + add("image/x-rgb", "rgb"); + add("image/x-xbitmap", "xbm"); + add("image/x-xpixmap", "xpm"); + add("image/x-xwindowdump", "xwd"); + add("model/iges", "igs"); + add("model/iges", "iges"); + add("model/mesh", "msh"); + add("model/mesh", "mesh"); + add("model/mesh", "silo"); + add("text/calendar", "ics"); + add("text/calendar", "icz"); + add("text/comma-separated-values", "csv"); + add("text/css", "css"); + add("text/html", "htm"); + add("text/html", "html"); + add("text/h323", "323"); + add("text/iuls", "uls"); + add("text/mathml", "mml"); + // add ".txt" first so it will be the default for guessExtensionFromMimeType + add("text/plain", "txt"); + add("text/plain", "asc"); + add("text/plain", "text"); + add("text/plain", "diff"); + add("text/plain", "po"); // reserve "pot" for vnd.ms-powerpoint + add("text/richtext", "rtx"); + add("text/rtf", "rtf"); + add("text/text", "phps"); + add("text/tab-separated-values", "tsv"); + add("text/xml", "xml"); + add("text/x-bibtex", "bib"); + add("text/x-boo", "boo"); + add("text/x-c++hdr", "hpp"); + add("text/x-c++hdr", "h++"); + add("text/x-c++hdr", "hxx"); + add("text/x-c++hdr", "hh"); + add("text/x-c++src", "cpp"); + add("text/x-c++src", "c++"); + add("text/x-c++src", "cc"); + add("text/x-c++src", "cxx"); + add("text/x-chdr", "h"); + add("text/x-component", "htc"); + add("text/x-csh", "csh"); + add("text/x-csrc", "c"); + add("text/x-dsrc", "d"); + add("text/x-haskell", "hs"); + add("text/x-java", "java"); + add("text/x-literate-haskell", "lhs"); + add("text/x-moc", "moc"); + add("text/x-pascal", "p"); + add("text/x-pascal", "pas"); + add("text/x-pcs-gcd", "gcd"); + add("text/x-setext", "etx"); + add("text/x-tcl", "tcl"); + add("text/x-tex", "tex"); + add("text/x-tex", "ltx"); + add("text/x-tex", "sty"); + add("text/x-tex", "cls"); + add("text/x-vcalendar", "vcs"); + add("text/x-vcard", "vcf"); + add("video/3gpp", "3gpp"); + add("video/3gpp", "3gp"); + add("video/3gpp2", "3gpp2"); + add("video/3gpp2", "3g2"); + add("video/avi", "avi"); + add("video/dl", "dl"); + add("video/dv", "dif"); + add("video/dv", "dv"); + add("video/fli", "fli"); + add("video/m4v", "m4v"); + add("video/mp2ts", "ts"); + add("video/mpeg", "mpeg"); + add("video/mpeg", "mpg"); + add("video/mpeg", "mpe"); + add("video/mp4", "mp4"); + add("video/mpeg", "VOB"); + add("video/quicktime", "qt"); + add("video/quicktime", "mov"); + add("video/vnd.mpegurl", "mxu"); + add("video/webm", "webm"); + add("video/x-la-asf", "lsf"); + add("video/x-la-asf", "lsx"); + add("video/x-matroska", "mkv"); + add("video/x-mng", "mng"); + add("video/x-ms-asf", "asf"); + add("video/x-ms-asf", "asx"); + add("video/x-ms-wm", "wm"); + add("video/x-ms-wmv", "wmv"); + add("video/x-ms-wmx", "wmx"); + add("video/x-ms-wvx", "wvx"); + add("video/x-sgi-movie", "movie"); + add("video/x-webex", "wrf"); + add("x-conference/x-cooltalk", "ice"); + add("x-epoc/x-sisx-app", "sisx"); + applyOverrides(); + } + private static void add(String mimeType, String extension) { + // If we have an existing x -> y mapping, we do not want to + // override it with another mapping x -> y2. + // If a mime type maps to several extensions + // the first extension added is considered the most popular + // so we do not want to overwrite it later. + if (!mimeTypeToExtensionMap.containsKey(mimeType)) { + mimeTypeToExtensionMap.put(mimeType, extension); + } + if (!extensionToMimeTypeMap.containsKey(extension)) { + extensionToMimeTypeMap.put(extension, mimeType); + } + } + private static InputStream getContentTypesPropertiesStream() { + // User override? + String userTable = System.getProperty("content.types.user.table"); + if (userTable != null) { + File f = new File(userTable); + if (f.exists()) { + try { + return new FileInputStream(f); + } catch (IOException ignored) { + } + } + } + // Standard location? + File f = new File(System.getProperty("java.home"), "lib" + File.separator + "content-types.properties"); + if (f.exists()) { + try { + return new FileInputStream(f); + } catch (IOException ignored) { + } + } + return null; + } + /** + * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your + * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins + * come from "$JAVA_HOME/lib/content-types.properties". + */ + private static void applyOverrides() { + // Get the appropriate InputStream to read overrides from, if any. + InputStream stream = getContentTypesPropertiesStream(); + if (stream == null) { + return; + } + try { + try { + // Read the properties file... + Properties overrides = new Properties(); + overrides.load(stream); + // And translate its mapping to ours... + for (Map.Entry entry : overrides.entrySet()) { + String extension = (String) entry.getKey(); + String mimeType = (String) entry.getValue(); + add(mimeType, extension); + } + } finally { + stream.close(); + } + } catch (IOException ignored) { + } + } + private MimeUtils() { + } + /** + * Returns true if the given MIME type has an entry in the map. + * @param mimeType A MIME type (i.e. text/plain) + * @return True iff there is a mimeType entry in the map. + */ + public static boolean hasMimeType(String mimeType) { + if (mimeType == null || mimeType.isEmpty()) { + return false; + } + return mimeTypeToExtensionMap.containsKey(mimeType); + } + /** + * Returns the MIME type for the given extension. + * @param extension A file extension without the leading '.' + * @return The MIME type for the given extension or null iff there is none. + */ + public static String guessMimeTypeFromExtension(String extension) { + if (extension == null || extension.isEmpty()) { + return null; + } + return extensionToMimeTypeMap.get(extension); + } + /** + * Returns true if the given extension has a registered MIME type. + * @param extension A file extension without the leading '.' + * @return True iff there is an extension entry in the map. + */ + public static boolean hasExtension(String extension) { + if (extension == null || extension.isEmpty()) { + return false; + } + return extensionToMimeTypeMap.containsKey(extension); + } + /** + * Returns the registered extension for the given MIME type. Note that some + * MIME types map to multiple extensions. This call will return the most + * common extension for the given MIME type. + * @param mimeType A MIME type (i.e. text/plain) + * @return The extension for the given MIME type or null iff there is none. + */ + public static String guessExtensionFromMimeType(String mimeType) { + if (mimeType == null || mimeType.isEmpty()) { + return null; + } + return mimeTypeToExtensionMap.get(mimeType); + } +} diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2f96a83a..19a8653f 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -199,16 +199,7 @@ public class UIHelper { if (message.getType() == Message.TYPE_IMAGE) { return context.getString(R.string.image); } - final String path = message.getRelativeFilePath(); - if (path == null) { - return ""; - } - final String mime; - try { - mime = URLConnection.guessContentTypeFromName(path.replace("#","")); - } catch (final StringIndexOutOfBoundsException ignored) { - return context.getString(R.string.file); - } + final String mime = message.getMimeType(); if (mime == null) { return context.getString(R.string.file); } else if (mime.startsWith("audio/")) { -- cgit v1.2.3 From a2525346f461183125c5840498228c347a86d4aa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 18:02:32 +0200 Subject: moved null check for to and from in message parser --- .../java/eu/siacs/conversations/parser/MessageParser.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d1b8c03a..72f822ca 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -239,6 +239,12 @@ public class MessageParser extends AbstractParser implements final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); + + if (from == null || to == null) { + Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + return; + } + boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); @@ -250,11 +256,6 @@ public class MessageParser extends AbstractParser implements counterpart = from; } - if (from == null || to == null) { - Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); - return; - } - Invite invite = extractInvite(packet); if (invite != null && invite.execute(account)) { return; -- cgit v1.2.3 From f5ba9d4223ca8e5dc9ce00024f69a8374d170a31 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 23:13:00 +0200 Subject: refactored message context menu --- .../eu/siacs/conversations/entities/Message.java | 2 +- .../conversations/ui/ConversationFragment.java | 57 ++++++++++++---------- .../conversations/ui/adapter/MessageAdapter.java | 12 ++--- src/main/res/menu/message_context.xml | 20 +++++--- src/main/res/values/strings.xml | 5 +- 5 files changed, 53 insertions(+), 43 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 0b938639..d15f3bbd 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -468,7 +468,7 @@ public class Message extends AbstractEntity { } } else { try { - return MimeUtils.guessExtensionFromMimeType(extractRelevantExtension(new URL(body.trim()))); + return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(body.trim()))); } catch (MalformedURLException e) { return null; } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index a0403335..20c6681b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -34,7 +34,6 @@ import android.widget.Toast; import net.java.otr4j.session.SessionStatus; -import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; @@ -437,33 +436,36 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa MenuItem shareWith = menu.findItem(R.id.share_with); MenuItem sendAgain = menu.findItem(R.id.send_again); MenuItem copyUrl = menu.findItem(R.id.copy_url); - MenuItem downloadImage = menu.findItem(R.id.download_image); + MenuItem downloadFile = menu.findItem(R.id.download_file); MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); - if ((m.getType() != Message.TYPE_TEXT && m.getType() != Message.TYPE_PRIVATE) - || m.getDownloadable() != null || GeoHelper.isGeoUri(m.getBody())) { - copyText.setVisible(false); + if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE) + && m.getDownloadable() == null + && !GeoHelper.isGeoUri(m.getBody()) + && m.treatAsDownloadable() != Message.Decision.MUST) { + copyText.setVisible(true); } - if ((m.getType() == Message.TYPE_TEXT - || m.getType() == Message.TYPE_PRIVATE - || m.getDownloadable() != null) - && (!GeoHelper.isGeoUri(m.getBody()))) { - shareWith.setVisible(false); + if ((m.getType() != Message.TYPE_TEXT + && m.getType() != Message.TYPE_PRIVATE + && m.getDownloadable() == null) + || (GeoHelper.isGeoUri(m.getBody()))) { + shareWith.setVisible(true); } - if (m.getStatus() != Message.STATUS_SEND_FAILED) { - sendAgain.setVisible(false); + if (m.getStatus() == Message.STATUS_SEND_FAILED) { + sendAgain.setVisible(true); } - if (!m.hasFileOnRemoteHost() && !GeoHelper.isGeoUri(m.getBody())) { - copyUrl.setVisible(false); + if (m.hasFileOnRemoteHost() + || GeoHelper.isGeoUri(m.getBody()) + || m.treatAsDownloadable() == Message.Decision.MUST) { + copyUrl.setVisible(true); } - if (m.getType() != Message.TYPE_TEXT - || m.getDownloadable() != null - || m.treatAsDownloadable() == Message.Decision.NEVER) { - downloadImage.setVisible(false); + if (m.getType() == Message.TYPE_TEXT && m.getDownloadable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) { + downloadFile.setVisible(true); + downloadFile.setTitle(activity.getString(R.string.download_x_file,UIHelper.getFileDescriptionString(activity, m))); } - if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) + if ((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING - || m.getStatus() == Message.STATUS_OFFERED)))) { - cancelTransmission.setVisible(false); + || m.getStatus() == Message.STATUS_OFFERED))) { + cancelTransmission.setVisible(true); } } } @@ -483,8 +485,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa case R.id.copy_url: copyUrl(selectedMessage); return true; - case R.id.download_image: - downloadImage(selectedMessage); + case R.id.download_file: + downloadFile(selectedMessage); return true; case R.id.cancel_transmission: cancelTransmission(selectedMessage); @@ -540,9 +542,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (GeoHelper.isGeoUri(message.getBody())) { resId = R.string.location; url = message.getBody(); - } else { - resId = R.string.image_url; + } else if (message.hasFileOnRemoteHost()) { + resId = R.string.file_url; url = message.getFileParams().url.toString(); + } else { + url = message.getBody().trim(); + resId = R.string.file_url; } if (activity.copyTextToClipboard(url, resId)) { Toast.makeText(activity, R.string.url_copied_to_clipboard, @@ -550,7 +555,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } } - private void downloadImage(Message message) { + private void downloadFile(Message message) { activity.xmppConnectionService.getHttpConnectionManager() .createNewConnection(message); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 8648f048..dedac77e 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -487,7 +487,7 @@ public class MessageAdapter extends ArrayAdapter { if (downloadable.getStatus() == Downloadable.STATUS_OFFER) { displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); } else if (downloadable.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { - displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_image_filesize)); + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); } else { displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first); } @@ -521,12 +521,12 @@ public class MessageAdapter extends ArrayAdapter { } else { if (GeoHelper.isGeoUri(message.getBody())) { displayLocationMessage(viewHolder,message); + } else if (message.bodyIsHeart()) { + displayHeartMessage(viewHolder, message.getBody().trim()); + } else if (message.treatAsDownloadable() == Message.Decision.MUST) { + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); } else { - if (message.bodyIsHeart()) { - displayHeartMessage(viewHolder, message.getBody().trim()); - } else { - displayTextMessage(viewHolder, message); - } + displayTextMessage(viewHolder, message); } } diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index 21659266..4e1316d3 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -3,21 +3,27 @@ + android:title="@string/copy_text" + android:visible="false"/> + android:title="@string/share_with" + android:visible="false"/> + android:title="@string/copy_original_url" + android:visible="false"/> + android:title="@string/send_again" + android:visible="false"/> + android:id="@+id/download_file" + android:title="@string/download_x_file" + android:visible="false"/> + android:title="@string/cancel_transmission" + android:visible="false"/> \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 4631bd60..444d9ecf 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -82,7 +82,6 @@ Send OTR encrypted message Send OpenPGP encrypted message Your nickname has been changed - Download Image Send unencrypted Decryption failed. Maybe you don’t have the proper private key. OpenKeychain @@ -320,12 +319,12 @@ Checking image on HTTP host The image file has been deleted You are not connected. Try again later - Check image file size + Check %s size Message options Copy text Copy original URL Send again - Image URL + File URL Message text URL copied to clipboard Message copied to clipboard -- cgit v1.2.3 From e4d1bd415dcd61013005075af3e6a03b9de24d74 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 23:19:50 +0200 Subject: also offer http download for some 'well known extensions' --- src/main/java/eu/siacs/conversations/entities/Downloadable.java | 2 ++ src/main/java/eu/siacs/conversations/entities/Message.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/src/main/java/eu/siacs/conversations/entities/Downloadable.java index c32165e8..8fae91bb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ b/src/main/java/eu/siacs/conversations/entities/Downloadable.java @@ -4,6 +4,7 @@ public interface Downloadable { String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; + String[] WELL_KNOWN_EXTENSIONS = {"pdf","m4a"}; int STATUS_UNKNOWN = 0x200; int STATUS_CHECKING = 0x201; @@ -14,6 +15,7 @@ public interface Downloadable { int STATUS_OFFER_CHECK_FILESIZE = 0x206; int STATUS_UPLOADING = 0x207; + boolean start(); int getStatus(); diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index d15f3bbd..ac5a9d56 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -497,7 +497,8 @@ public class Message extends AbstractEntity { } else { return Decision.NEVER; } - } else if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + } else if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension) + || Arrays.asList(Downloadable.WELL_KNOWN_EXTENSIONS).contains(extension)) { return Decision.SHOULD; } else { return Decision.NEVER; -- cgit v1.2.3 From c745fbb562b6f25cb57a06538b4c54fdfe619fa3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 23:51:59 +0200 Subject: fixed share with activity to account for http file upload --- .../services/XmppConnectionService.java | 7 +- .../siacs/conversations/ui/ShareWithActivity.java | 74 ++++++++++------------ 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 877806f3..a0961d69 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1046,13 +1046,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa populateWithOrderedConversations(list, true); } - public void populateWithOrderedConversations(final List list, boolean includeConferences) { + public void populateWithOrderedConversations(final List list, boolean includeNoFileUpload) { list.clear(); - if (includeConferences) { + if (includeNoFileUpload) { list.addAll(getConversations()); } else { for (Conversation conversation : getConversations()) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { + if (conversation.getMode() == Conversation.MODE_SINGLE + || conversation.getAccount().httpUploadAvailable()) { list.add(conversation); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 200a577e..351f1dfc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -4,7 +4,6 @@ import android.app.PendingIntent; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -13,10 +12,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.Toast; -import java.io.UnsupportedEncodingException; import java.net.URLConnection; -import java.net.URLDecoder; -import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -66,18 +62,17 @@ public class ShareWithActivity extends XmppActivity { } }; - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { + protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_START_NEW_CONVERSATION && resultCode == RESULT_OK) { share.contact = data.getStringExtra("contact"); share.account = data.getStringExtra("account"); - Log.d(Config.LOGTAG, "contact: " + share.contact + " account:" - + share.account); } - if (xmppConnectionServiceBound && share != null - && share.contact != null && share.account != null) { + if (xmppConnectionServiceBound + && share != null + && share.contact != null + && share.account != null) { share(); } } @@ -101,13 +96,8 @@ public class ShareWithActivity extends XmppActivity { mListView.setOnItemClickListener(new OnItemClickListener() { @Override - public void onItemClick(AdapterView arg0, View arg1, - int position, long arg3) { - Conversation conversation = mConversations.get(position); - if (conversation.getMode() == Conversation.MODE_SINGLE - || share.uris.size() == 0) { - share(mConversations.get(position)); - } + public void onItemClick(AdapterView arg0, View arg1, int position, long arg3) { + share(mConversations.get(position)); } }); @@ -123,11 +113,10 @@ public class ShareWithActivity extends XmppActivity { @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { - case R.id.action_add: - final Intent intent = new Intent(getApplicationContext(), - ChooseContactActivity.class); - startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION); - return true; + case R.id.action_add: + final Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class); + startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION); + return true; } return super.onOptionsItemSelected(item); } @@ -157,7 +146,7 @@ public class ShareWithActivity extends XmppActivity { this.share.uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); } if (xmppConnectionServiceBound) { - xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.image); + xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uris.size() == 0); } } @@ -183,28 +172,28 @@ public class ShareWithActivity extends XmppActivity { } private void share() { - Account account; - try { - account = xmppConnectionService.findAccountByJid(Jid.fromString(share.account)); - } catch (final InvalidJidException e) { - account = null; - } - if (account == null) { + Account account; + try { + account = xmppConnectionService.findAccountByJid(Jid.fromString(share.account)); + } catch (final InvalidJidException e) { + account = null; + } + if (account == null) { return; } - final Conversation conversation; - try { - conversation = xmppConnectionService - .findOrCreateConversation(account, Jid.fromString(share.contact), false); - } catch (final InvalidJidException e) { - return; - } - share(conversation); + final Conversation conversation; + try { + conversation = xmppConnectionService + .findOrCreateConversation(account, Jid.fromString(share.contact), false); + } catch (final InvalidJidException e) { + return; + } + share(conversation); } private void share(final Conversation conversation) { if (share.uris.size() != 0) { - selectPresence(conversation, new OnPresenceSelected() { + OnPresenceSelected callback = new OnPresenceSelected() { @Override public void onPresenceSelected() { if (share.image) { @@ -227,7 +216,12 @@ public class ShareWithActivity extends XmppActivity { switchToConversation(conversation, null, true); finish(); } - }); + }; + if (conversation.getAccount().httpUploadAvailable()) { + callback.onPresenceSelected(); + } else { + selectPresence(conversation, callback); + } } else { switchToConversation(conversation, this.share.text, true); finish(); -- cgit v1.2.3 From fc479697413c8b9bc9b8eb228d5c57fb3cdc4548 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 13:07:48 +0200 Subject: added fallback for non-srv dns queries --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index bb354ae0..06426340 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -105,6 +105,7 @@ public class DNSHelper { for(int i = 0; i < response.getAnswers().length; ++i) { values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } + values.add(createNamePortBundle(host,5222)); bundle.putParcelableArrayList("values", values); return bundle; } -- cgit v1.2.3 From bfe1d2489ae41f21c2899c6eea4273357a6aa20b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 13:08:25 +0200 Subject: version bump to 1.4.6 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3706aca5..e4d2168b 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 73 - versionName "1.4.5" + versionCode 74 + versionName "1.4.6" } compileOptions { -- cgit v1.2.3 From d30fb6f0a15fe574069694732bb23c339f0c30d1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 21:32:46 +0200 Subject: avoid very rare npe --- src/main/java/eu/siacs/conversations/entities/Roster.java | 3 +++ src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Roster.java b/src/main/java/eu/siacs/conversations/entities/Roster.java index d6777ef6..628a31d1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Roster.java +++ b/src/main/java/eu/siacs/conversations/entities/Roster.java @@ -74,6 +74,9 @@ public class Roster { } public void initContact(final Contact contact) { + if (contact == null) { + return; + } contact.setAccount(account); contact.setOption(Contact.Options.IN_ROSTER); synchronized (this.contacts) { diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index ed88e434..d11b02fa 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -386,8 +386,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; String args[] = { roster.getAccount().getUuid() }; - cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", - args, null, null, null); + cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null); while (cursor.moveToNext()) { roster.initContact(Contact.fromCursor(cursor)); } -- cgit v1.2.3 From 2fbeb0bbb2db84a54a67f91e45602c55bfd92ea4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 22:08:23 +0200 Subject: make sure unread count is initialized as 0. fixes #1270 --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index a0961d69..3b64872e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -233,7 +233,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private int convChangedListenerCount = 0; - private int unreadCount = 0; + private int unreadCount = -1; private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @@ -602,6 +602,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE); this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"XmppConnectionService"); toggleForegroundService(); + updateUnreadCountBadge(); } public void toggleForegroundService() { -- cgit v1.2.3 From 96fe75fe9f7e143268e6306fd799eceaad85c48d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 18:02:32 +0200 Subject: moved null check for to and from in message parser --- .../java/eu/siacs/conversations/parser/MessageParser.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a40b170..864d0667 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -239,6 +239,12 @@ public class MessageParser extends AbstractParser implements final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); + + if (from == null || to == null) { + Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + return; + } + boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); @@ -250,11 +256,6 @@ public class MessageParser extends AbstractParser implements counterpart = from; } - if (from == null || to == null) { - Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); - return; - } - Invite invite = extractInvite(packet); if (invite != null && invite.execute(account)) { return; -- cgit v1.2.3 From 097bdf1a3ea4a1821b18eeffebaff4bd4d395817 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 21:32:46 +0200 Subject: avoid very rare npe --- src/main/java/eu/siacs/conversations/entities/Roster.java | 3 +++ src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Roster.java b/src/main/java/eu/siacs/conversations/entities/Roster.java index d6777ef6..628a31d1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Roster.java +++ b/src/main/java/eu/siacs/conversations/entities/Roster.java @@ -74,6 +74,9 @@ public class Roster { } public void initContact(final Contact contact) { + if (contact == null) { + return; + } contact.setAccount(account); contact.setOption(Contact.Options.IN_ROSTER); synchronized (this.contacts) { diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index ed88e434..d11b02fa 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -386,8 +386,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; String args[] = { roster.getAccount().getUuid() }; - cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", - args, null, null, null); + cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null); while (cursor.moveToNext()) { roster.initContact(Contact.fromCursor(cursor)); } -- cgit v1.2.3 From a2bab9c5649c8a0c0ff2331d2ec3294123d640ec Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 22:08:23 +0200 Subject: make sure unread count is initialized as 0. fixes #1270 --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0a264dd1..17c344c2 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -233,7 +233,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private int convChangedListenerCount = 0; - private int unreadCount = 0; + private int unreadCount = -1; private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @@ -602,6 +602,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE); this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"XmppConnectionService"); toggleForegroundService(); + updateUnreadCountBadge(); } public void toggleForegroundService() { -- cgit v1.2.3 From 148955a7136b65b6a070706e5cf561db68fa6616 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 4 Jul 2015 00:05:28 +0200 Subject: version bump to 1.4.7 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e4d2168b..e93f3946 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 74 - versionName "1.4.6" + versionCode 75 + versionName "1.4.7" } compileOptions { -- cgit v1.2.3 From f8f5bcb2ae099240ecbc525b0e56119fe7c65e8d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 4 Jul 2015 00:05:28 +0200 Subject: version bump to 1.4.7 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e4d2168b..e93f3946 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 74 - versionName "1.4.6" + versionCode 75 + versionName "1.4.7" } compileOptions { -- cgit v1.2.3 From bef731a3c8ec2d4cefb70e6a7fe4232825a1d876 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jul 2015 11:59:38 +0200 Subject: refactored sendMessage and merged with resendMessage --- .../eu/siacs/conversations/entities/Message.java | 20 ++ .../services/XmppConnectionService.java | 245 ++++++++------------- 2 files changed, 117 insertions(+), 148 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index ac5a9d56..078a4565 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -435,6 +435,26 @@ public class Message extends AbstractEntity { return (status > STATUS_RECEIVED || (contact != null && contact.trusted())); } + public boolean fixCounterpart() { + Presences presences = conversation.getContact().getPresences(); + if (counterpart != null && presences.has(counterpart.getResourcepart())) { + return true; + } else if (presences.size() >= 1) { + try { + counterpart = Jid.fromParts(conversation.getJid().getLocalpart(), + conversation.getJid().getDomainpart(), + presences.asStringArray()[0]); + return true; + } catch (InvalidJidException e) { + counterpart = null; + return false; + } + } else { + counterpart = null; + return false; + } + } + public enum Decision { MUST, SHOULD, diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3b64872e..2fead238 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -28,6 +28,7 @@ import android.util.LruCache; import net.java.otr4j.OtrException; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.SessionImpl; import net.java.otr4j.session.SessionStatus; import org.openintents.openpgp.util.OpenPgpApi; @@ -684,113 +685,126 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void sendMessage(final Message message) { + sendMessage(message,false); + } + + private void sendMessage(final Message message, final boolean resend) { final Account account = message.getConversation().getAccount(); + final Conversation conversation = message.getConversation(); account.deactivateGracePeriod(); - final Conversation conv = message.getConversation(); MessagePacket packet = null; boolean saveInDb = true; - boolean send = false; - if (account.getStatus() == Account.State.ONLINE - && account.getXmppConnection() != null) { - if (message.needsUploading()) { - if (message.getCounterpart() != null || account.httpUploadAvailable()) { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession()) { - conv.startOtrSession(message.getCounterpart().getResourcepart(),true); - message.setStatus(Message.STATUS_WAITING); - } else if (conv.hasValidOtrSession() - && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - mJingleConnectionManager.createNewConnection(message); + message.setStatus(Message.STATUS_WAITING); + + if (!resend && message.getEncryption() != Message.ENCRYPTION_OTR) { + message.getConversation().endOtrIfNeeded(); + message.getConversation().findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { + @Override + public void onMessageFound(Message message) { + markMessage(message,Message.STATUS_SEND_FAILED); + } + }); + } + + if (account.isOnlineAndConnected()) { + switch (message.getEncryption()) { + case Message.ENCRYPTION_NONE: + if (message.needsUploading()) { + if (account.httpUploadAvailable() || message.fixCounterpart()) { + this.sendFileMessage(message); + } else { + break; } } else { - this.sendFileMessage(message); - + packet = mMessageGenerator.generateChat(message,resend); } - } else { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - conv.startOtrIfNeeded(); - } - message.setStatus(Message.STATUS_WAITING); - } - } else { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() && (message.getCounterpart() != null)) { - conv.startOtrSession(message.getCounterpart().getResourcepart(), true); - message.setStatus(Message.STATUS_WAITING); - } else if (conv.hasValidOtrSession()) { - if (conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - packet = mMessageGenerator.generateOtrChat(message); - send = true; + break; + case Message.ENCRYPTION_PGP: + case Message.ENCRYPTION_DECRYPTED: + if (message.needsUploading()) { + if (account.httpUploadAvailable() || message.fixCounterpart()) { + this.sendFileMessage(message); } else { - message.setStatus(Message.STATUS_WAITING); - conv.startOtrIfNeeded(); + break; } } else { - message.setStatus(Message.STATUS_WAITING); + packet = mMessageGenerator.generatePgpChat(message,resend); } - } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - message.getConversation().endOtrIfNeeded(); - message.getConversation().findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { - @Override - public void onMessageFound(Message message) { - markMessage(message,Message.STATUS_SEND_FAILED); + break; + case Message.ENCRYPTION_OTR: + SessionImpl otrSession = conversation.getOtrSession(); + if (otrSession != null && otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) { + try { + message.setCounterpart(Jid.fromSessionID(otrSession.getSessionID())); + } catch (InvalidJidException e) { + break; } - }); - packet = mMessageGenerator.generatePgpChat(message); - send = true; - } else { - message.getConversation().endOtrIfNeeded(); - message.getConversation().findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { - @Override - public void onMessageFound(Message message) { - markMessage(message,Message.STATUS_SEND_FAILED); + if (message.needsUploading()) { + mJingleConnectionManager.createNewConnection(message); + } else { + packet = mMessageGenerator.generateOtrChat(message,resend); } - }); - packet = mMessageGenerator.generateChat(message); - send = true; + } else if (otrSession == null) { + if (message.fixCounterpart()) { + conversation.startOtrSession(message.getCounterpart().getResourcepart(), true); + } else { + break; + } + } + break; + } + if (packet != null) { + if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) { + message.setStatus(Message.STATUS_UNSEND); + } else { + message.setStatus(Message.STATUS_SEND); } } - if (!account.getXmppConnection().getFeatures().sm() - && conv.getMode() != Conversation.MODE_MULTI) { - message.setStatus(Message.STATUS_SEND); - } } else { - message.setStatus(Message.STATUS_WAITING); - if (message.getType() == Message.TYPE_TEXT) { - if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - String pgpBody = message.getEncryptedBody(); - String decryptedBody = message.getBody(); - message.setBody(pgpBody); - message.setEncryption(Message.ENCRYPTION_PGP); - databaseBackend.createMessage(message); - saveInDb = false; - message.setBody(decryptedBody); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - } else if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() - && message.getCounterpart() != null) { - conv.startOtrSession(message.getCounterpart().getResourcepart(), false); - } - } + switch(message.getEncryption()) { + case Message.ENCRYPTION_DECRYPTED: + if (!message.needsUploading()) { + String pgpBody = message.getEncryptedBody(); + String decryptedBody = message.getBody(); + message.setBody(pgpBody); + message.setEncryption(Message.ENCRYPTION_PGP); + databaseBackend.createMessage(message); + saveInDb = false; + message.setBody(decryptedBody); + message.setEncryption(Message.ENCRYPTION_DECRYPTED); + } + break; + case Message.ENCRYPTION_OTR: + if (!conversation.hasValidOtrSession() && message.getCounterpart() != null) { + conversation.startOtrSession(message.getCounterpart().getResourcepart(), false); + } + break; } - } - conv.add(message); - if (saveInDb) { - if (message.getEncryption() == Message.ENCRYPTION_NONE - || saveEncryptedMessages()) { + + if (resend) { + if (packet != null) { + if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) { + markMessage(message,Message.STATUS_UNSEND); + } else { + markMessage(message,Message.STATUS_SEND); + } + } + } else { + conversation.add(message); + if (saveInDb && (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages())) { databaseBackend.createMessage(message); - } + } + updateConversationUi(); } - if ((send) && (packet != null)) { - if (conv.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { + if (packet != null) { + if (conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { if (this.sendChatStates()) { - packet.addChild(ChatState.toElement(conv.getOutgoingChatState())); + packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); } } sendMessagePacket(account, packet); } - updateConversationUi(); } private void sendUnsentMessages(final Conversation conversation) { @@ -804,72 +818,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void resendMessage(final Message message) { - Account account = message.getConversation().getAccount(); - MessagePacket packet = null; - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Presences presences = message.getConversation().getContact().getPresences(); - if (!message.getConversation().hasValidOtrSession()) { - if ((message.getCounterpart() != null) - && (presences.has(message.getCounterpart().getResourcepart()))) { - message.getConversation().startOtrSession(message.getCounterpart().getResourcepart(), true); - } else { - if (presences.size() == 1) { - String presence = presences.asStringArray()[0]; - message.getConversation().startOtrSession(presence, true); - } - } - } else { - if (message.getConversation().getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - try { - message.setCounterpart(Jid.fromSessionID(message.getConversation().getOtrSession().getSessionID())); - if (message.needsUploading()) { - mJingleConnectionManager.createNewConnection(message); - } else { - packet = mMessageGenerator.generateOtrChat(message, true); - } - } catch (final InvalidJidException ignored) { - - } - } - } - } else if (message.needsUploading()) { - Contact contact = message.getConversation().getContact(); - Presences presences = contact.getPresences(); - if (account.httpUploadAvailable() || (message.getCounterpart() != null && presences.has(message.getCounterpart().getResourcepart()))) { - this.sendFileMessage(message); - } else { - if (presences.size() == 1) { - String presence = presences.asStringArray()[0]; - try { - message.setCounterpart(Jid.fromParts(contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence)); - } catch (InvalidJidException e) { - return; - } - this.sendFileMessage(message); - } - } - } else { - if (message.getEncryption() == Message.ENCRYPTION_NONE) { - packet = mMessageGenerator.generateChat(message, true); - } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED) - || (message.getEncryption() == Message.ENCRYPTION_PGP)) { - packet = mMessageGenerator.generatePgpChat(message, true); - } - } - if (packet != null) { - if (!account.getXmppConnection().getFeatures().sm() - && message.getConversation().getMode() != Conversation.MODE_MULTI) { - markMessage(message, Message.STATUS_SEND); - } else { - markMessage(message, Message.STATUS_UNSEND); - } - if (message.getConversation().setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { - if (this.sendChatStates()) { - packet.addChild(ChatState.toElement(message.getConversation().getOutgoingChatState())); - } - } - sendMessagePacket(account, packet); - } + sendMessage(message,true); } public void fetchRosterFromServer(final Account account) { -- cgit v1.2.3 From ef1429c9a6983c101da41a277bd9353374dc89e7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jul 2015 18:10:18 +0200 Subject: show contacts name in non anonymous mucs. fixes #1213 --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 19a8653f..ddc4781c 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -221,10 +221,14 @@ public class UIHelper { public static String getMessageDisplayName(final Message message) { if (message.getStatus() == Message.STATUS_RECEIVED) { + final Contact contact = message.getContact(); if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - return getDisplayedMucCounterpart(message.getCounterpart()); + if (contact != null) { + return contact.getDisplayName(); + } else { + return getDisplayedMucCounterpart(message.getCounterpart()); + } } else { - final Contact contact = message.getContact(); return contact != null ? contact.getDisplayName() : ""; } } else { -- cgit v1.2.3 From 26044ca229c48dd6e3e9da664ef82813ea69bc7c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2015 13:40:08 +0200 Subject: print stack trace instead of writing error message to log in case of unknown exception in dnsutil --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 06426340..5a47bb3c 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -132,7 +132,7 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { - Log.d(Config.LOGTAG,e.getMessage()); + e.printStackTrace(); bundle.putString("error", "unhandled"); } return bundle; -- cgit v1.2.3 From 7eac30d1f48d6bb676ebd0e55a5ffabb37053559 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 12:09:59 +0200 Subject: catch number format exception in server ack --- .../siacs/conversations/xmpp/XmppConnection.java | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 87dfb897..35c89b45 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -366,17 +366,21 @@ public class XmppConnection implements Runnable { } else if (nextTag.isStart("a")) { final Element ack = tagReader.readElement(nextTag); lastPacketReceived = SystemClock.elapsedRealtime(); - final int serverSequence = Integer.parseInt(ack.getAttribute("h")); - if (Config.EXTENDED_SM_LOGGING) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence); - } - final String msgId = this.messageReceipts.get(serverSequence); - if (msgId != null) { - if (this.acknowledgedListener != null) { - this.acknowledgedListener.onMessageAcknowledged( - account, msgId); + try { + final int serverSequence = Integer.parseInt(ack.getAttribute("h")); + if (Config.EXTENDED_SM_LOGGING) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence); + } + final String msgId = this.messageReceipts.get(serverSequence); + if (msgId != null) { + if (this.acknowledgedListener != null) { + this.acknowledgedListener.onMessageAcknowledged( + account, msgId); + } + this.messageReceipts.remove(serverSequence); } - this.messageReceipts.remove(serverSequence); + } catch (NumberFormatException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number"); } } else if (nextTag.isStart("failed")) { tagReader.readElement(nextTag); -- cgit v1.2.3 From 492e38748258abe3d4efcbd4c76ef281af44783a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 12:16:30 +0200 Subject: added null check in sasl response verifier --- src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java index 10cd3167..c95a62df 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramSha1.java @@ -185,7 +185,7 @@ public class ScramSha1 extends SaslMechanism { case RESPONSE_SENT: final String clientCalculatedServerFinalMessage = "v=" + Base64.encodeToString(serverSignature, Base64.NO_WRAP); - if (!clientCalculatedServerFinalMessage.equals(new String(Base64.decode(challenge, Base64.DEFAULT)))) { + if (challenge == null || !clientCalculatedServerFinalMessage.equals(new String(Base64.decode(challenge, Base64.DEFAULT)))) { throw new AuthenticationException("Server final message does not match calculated final message"); } state = State.VALID_SERVER_RESPONSE; -- cgit v1.2.3 From b02ef0c62fdf616b95401d49601f357c492fc257 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 12:42:41 +0200 Subject: show timestamp on images in mucs fixes #1178 --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index dedac77e..525ae649 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -160,7 +160,7 @@ public class MessageAdapter extends ArrayAdapter { message.getMergedTimeSent()); if (message.getStatus() <= Message.STATUS_RECEIVED) { if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); + viewHolder.time.setText(formatedTime + " \u00B7 " + filesize +" \u00B7 " + info); } else if ((filesize == null) && (info != null)) { viewHolder.time.setText(formatedTime + " \u00B7 " + info); } else if ((filesize != null) && (info == null)) { -- cgit v1.2.3 From 0f5c87ca1f3dc25e0f76ff1fa4308326d1d287f0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 13:28:50 +0200 Subject: display toast in ui on failed http download fixes #954 --- .../siacs/conversations/http/HttpConnection.java | 56 ++++++++++++---------- .../conversations/http/HttpConnectionManager.java | 6 ++- .../services/XmppConnectionService.java | 48 +++++++++++++++++-- .../conversations/ui/ConversationActivity.java | 13 ++++- .../eu/siacs/conversations/ui/XmppActivity.java | 15 +++--- .../conversations/ui/adapter/MessageAdapter.java | 2 + src/main/res/values/strings.xml | 1 + 7 files changed, 105 insertions(+), 36 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index 002611dc..8b76545c 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.http; import android.content.Intent; import android.net.Uri; import android.os.SystemClock; +import android.util.Log; import org.apache.http.conn.ssl.StrictHostnameVerifier; @@ -24,6 +25,7 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; @@ -63,6 +65,10 @@ public class HttpConnection implements Downloadable { } public void init(Message message) { + init(message,false); + } + + public void init(Message message, boolean interactive) { this.message = message; this.message.setDownloadable(this); try { @@ -92,7 +98,7 @@ public class HttpConnection implements Downloadable { && this.file.getKey() == null) { this.message.setEncryption(Message.ENCRYPTION_NONE); } - checkFileSize(false); + checkFileSize(true); } catch (MalformedURLException e) { this.cancel(); } @@ -180,6 +186,10 @@ public class HttpConnection implements Downloadable { HttpConnection.this.mXmppConnectionService.getNotificationService().push(message); return; } catch (IOException e) { + Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); + if (interactive) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + } cancel(); return; } @@ -194,25 +204,24 @@ public class HttpConnection implements Downloadable { } } - private long retrieveFileSize() throws IOException, - SSLHandshakeException { - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } - try { - return Long.parseLong(contentLength, 10); - } catch (NumberFormatException e) { - throw new IOException(); - } + private long retrieveFileSize() throws IOException { + Log.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + if (contentLength == null) { + throw new IOException(); + } + try { + return Long.parseLong(contentLength, 10); + } catch (NumberFormatException e) { + throw new IOException(); + } } } @@ -235,19 +244,18 @@ public class HttpConnection implements Downloadable { } catch (SSLHandshakeException e) { changeStatus(STATUS_OFFER); } catch (IOException e) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); cancel(); } } private void download() throws SSLHandshakeException, IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); if (connection instanceof HttpsURLConnection) { setupTrustManager((HttpsURLConnection) connection, interactive); } connection.connect(); - BufferedInputStream is = new BufferedInputStream( - connection.getInputStream()); + BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); file.getParentFile().mkdirs(); file.createNewFile(); OutputStream os = file.createOutputStream(); diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index fc266e7b..f141987b 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -17,8 +17,12 @@ public class HttpConnectionManager extends AbstractConnectionManager { private List uploadConnections = new CopyOnWriteArrayList<>(); public HttpConnection createNewConnection(Message message) { + return this.createNewConnection(message,false); + } + + public HttpConnection createNewConnection(Message message,boolean interactive) { HttpConnection connection = new HttpConnection(this); - connection.init(message); + connection.init(message,interactive); this.connections.add(connection); return connection; } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2fead238..e3cfb09e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -234,6 +234,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private int convChangedListenerCount = 0; + private OnShowErrorToast mOnShowErrorToast = null; + private int showErrorToastListenerCount = 0; private int unreadCount = -1; private OnAccountUpdate mOnAccountUpdate = null; private OnStatusChanged statusListener = new OnStatusChanged() { @@ -631,7 +633,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + .getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, EventReceiver.class); alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); Log.d(Config.LOGTAG, "good bye"); @@ -685,7 +687,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void sendMessage(final Message message) { - sendMessage(message,false); + sendMessage(message, false); } private void sendMessage(final Message message, final boolean resend) { @@ -818,7 +820,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void resendMessage(final Message message) { - sendMessage(message,true); + sendMessage(message, true); } public void fetchRosterFromServer(final Account account) { @@ -1241,6 +1243,32 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void setOnShowErrorToastListener(OnShowErrorToast onShowErrorToast) { + synchronized (this) { + if (checkListeners()) { + switchToForeground(); + } + this.mOnShowErrorToast = onShowErrorToast; + if (this.showErrorToastListenerCount < 2) { + this.showErrorToastListenerCount++; + } + } + this.mOnShowErrorToast = onShowErrorToast; + } + + public void removeOnShowErrorToastListener() { + synchronized (this) { + this.showErrorToastListenerCount--; + if (this.showErrorToastListenerCount <= 0) { + this.showErrorToastListenerCount = 0; + this.mOnShowErrorToast = null; + if (checkListeners()) { + switchToBackground(); + } + } + } + } + public void setOnAccountListChangedListener(OnAccountUpdate listener) { synchronized (this) { if (checkListeners()) { @@ -1345,7 +1373,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return (this.mOnAccountUpdate == null && this.mOnConversationUpdate == null && this.mOnRosterUpdate == null - && this.mOnUpdateBlocklist == null); + && this.mOnUpdateBlocklist == null + && this.mOnShowErrorToast == null); } private void switchToForeground() { @@ -2196,6 +2225,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return count; } + + public void showErrorToastInUi(int resId) { + if (mOnShowErrorToast != null) { + mOnShowErrorToast.onShowErrorToast(resId); + } + } + public void updateConversationUi() { if (mOnConversationUpdate != null) { mOnConversationUpdate.onConversationUpdate(); @@ -2529,6 +2565,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onPushFailed(); } + public interface OnShowErrorToast { + void onShowErrorToast(int resId); + } + public class XmppConnectionBinder extends Binder { public XmppConnectionService getService() { return XmppConnectionService.this; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 770129ab..a507a5fe 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -40,6 +40,7 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; @@ -48,7 +49,7 @@ import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; public class ConversationActivity extends XmppActivity - implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist { + implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast { public static final String ACTION_DOWNLOAD = "eu.siacs.conversations.action.DOWNLOAD"; @@ -1271,4 +1272,14 @@ public class ConversationActivity extends XmppActivity public boolean enterIsSend() { return getPreferences().getBoolean("enter_is_send",false); } + + @Override + public void onShowErrorToast(final int resId) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(ConversationActivity.this,resId,Toast.LENGTH_SHORT).show(); + } + }); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 934c696f..ddad1e30 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -284,6 +284,9 @@ public abstract class XmppActivity extends Activity { if (this instanceof OnUpdateBlocklist) { this.xmppConnectionService.setOnUpdateBlocklistListener((OnUpdateBlocklist) this); } + if (this instanceof XmppConnectionService.OnShowErrorToast) { + this.xmppConnectionService.setOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this); + } } protected void unregisterListeners() { @@ -302,6 +305,9 @@ public abstract class XmppActivity extends Activity { if (this instanceof OnUpdateBlocklist) { this.xmppConnectionService.removeOnUpdateBlocklistListener(); } + if (this instanceof XmppConnectionService.OnShowErrorToast) { + this.xmppConnectionService.removeOnShowErrorToastListener(); + } } @Override @@ -447,14 +453,11 @@ public abstract class XmppActivity extends Activity { @Override public void success(Account account) { - xmppConnectionService.databaseBackend - .updateAccount(account); + xmppConnectionService.databaseBackend.updateAccount(account); xmppConnectionService.sendPresence(account); if (conversation != null) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); - xmppConnectionService.databaseBackend - .updateConversation(conversation); + conversation.setNextEncryption(Message.ENCRYPTION_PGP); + xmppConnectionService.databaseBackend.updateConversation(conversation); } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 525ae649..d0a05c37 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -542,6 +542,8 @@ public class MessageAdapter extends ArrayAdapter { Toast.makeText(activity, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show(); } + } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { + activity.xmppConnectionService.getHttpConnectionManager().createNewConnection(message); } } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 444d9ecf..1af33587 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -478,4 +478,5 @@ None Most recently used Choose quick action + File not found on remote server -- cgit v1.2.3 From 925801c14e7500313069b2bc04abd066798a881c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 14:14:45 +0200 Subject: get file upload ready to work with https --- .../siacs/conversations/http/HttpConnection.java | 40 +------------------ .../conversations/http/HttpConnectionManager.java | 46 ++++++++++++++++++++++ .../conversations/http/HttpUploadConnection.java | 5 +++ 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index 8b76545c..fb3f08e3 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -131,42 +131,6 @@ public class HttpConnection implements Downloadable { mXmppConnectionService.updateConversationUi(); } - private void setupTrustManager(final HttpsURLConnection connection, - final boolean interactive) { - final X509TrustManager trustManager; - final HostnameVerifier hostnameVerifier; - if (interactive) { - trustManager = mXmppConnectionService.getMemorizingTrustManager(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager().wrapHostnameVerifier( - new StrictHostnameVerifier()); - } else { - trustManager = mXmppConnectionService.getMemorizingTrustManager() - .getNonInteractive(); - hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager() - .wrapHostnameVerifierNonInteractive( - new StrictHostnameVerifier()); - } - try { - final SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, new X509TrustManager[]{trustManager}, - mXmppConnectionService.getRNG()); - - final SSLSocketFactory sf = sc.getSocketFactory(); - final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( - sf.getSupportedCipherSuites()); - if (cipherSuites.length > 0) { - sc.getDefaultSSLParameters().setCipherSuites(cipherSuites); - - } - - connection.setSSLSocketFactory(sf); - connection.setHostnameVerifier(hostnameVerifier); - } catch (final KeyManagementException | NoSuchAlgorithmException ignored) { - } - } - private class FileSizeChecker implements Runnable { private boolean interactive = false; @@ -210,7 +174,7 @@ public class HttpConnection implements Downloadable { HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); connection.setRequestMethod("HEAD"); if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); } connection.connect(); String contentLength = connection.getHeaderField("Content-Length"); @@ -252,7 +216,7 @@ public class HttpConnection implements Downloadable { private void download() throws SSLHandshakeException, IOException { HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); } connection.connect(); BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index f141987b..4d6395e2 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -1,11 +1,22 @@ package eu.siacs.conversations.http; +import org.apache.http.conn.ssl.StrictHostnameVerifier; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; + import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; public class HttpConnectionManager extends AbstractConnectionManager { @@ -41,4 +52,39 @@ public class HttpConnectionManager extends AbstractConnectionManager { public void finishUploadConnection(HttpUploadConnection httpUploadConnection) { this.uploadConnections.remove(httpUploadConnection); } + + public void setupTrustManager(final HttpsURLConnection connection, final boolean interactive) { + final X509TrustManager trustManager; + final HostnameVerifier hostnameVerifier; + if (interactive) { + trustManager = mXmppConnectionService.getMemorizingTrustManager(); + hostnameVerifier = mXmppConnectionService + .getMemorizingTrustManager().wrapHostnameVerifier( + new StrictHostnameVerifier()); + } else { + trustManager = mXmppConnectionService.getMemorizingTrustManager() + .getNonInteractive(); + hostnameVerifier = mXmppConnectionService + .getMemorizingTrustManager() + .wrapHostnameVerifierNonInteractive( + new StrictHostnameVerifier()); + } + try { + final SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, new X509TrustManager[]{trustManager}, + mXmppConnectionService.getRNG()); + + final SSLSocketFactory sf = sc.getSocketFactory(); + final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( + sf.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sc.getDefaultSSLParameters().setCipherSuites(cipherSuites); + + } + + connection.setSSLSocketFactory(sf); + connection.setHostnameVerifier(hostnameVerifier); + } catch (final KeyManagementException | NoSuchAlgorithmException ignored) { + } + } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index d861f616..61e87715 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -10,6 +10,8 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Downloadable; @@ -133,6 +135,9 @@ public class HttpUploadConnection implements Downloadable { try { Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString()); connection = (HttpURLConnection) mPutUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true); + } connection.setRequestMethod("PUT"); connection.setFixedLengthStreamingMode((int) file.getExpectedSize()); connection.setDoOutput(true); -- cgit v1.2.3 From ce79f4bbe3e6f4254d143125807327ff02f1a29c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:11:03 +0200 Subject: renamed downloadable to transferable --- .../siacs/conversations/entities/Downloadable.java | 28 ------------------ .../entities/DownloadablePlaceholder.java | 34 ---------------------- .../eu/siacs/conversations/entities/Message.java | 24 +++++++-------- .../siacs/conversations/entities/Transferable.java | 28 ++++++++++++++++++ .../entities/TransferablePlaceholder.java | 34 ++++++++++++++++++++++ .../siacs/conversations/http/HttpConnection.java | 22 +++++--------- .../conversations/http/HttpUploadConnection.java | 10 +++---- .../conversations/persistance/FileBackend.java | 4 +-- .../services/NotificationService.java | 8 ++--- .../services/XmppConnectionService.java | 9 +++--- .../conversations/ui/ConversationFragment.java | 22 +++++++------- .../ui/adapter/ConversationAdapter.java | 6 ++-- .../conversations/ui/adapter/MessageAdapter.java | 22 +++++++------- .../eu/siacs/conversations/utils/UIHelper.java | 19 ++++++------ .../xmpp/jingle/JingleConnection.java | 31 ++++++++++---------- .../xmpp/jingle/JingleConnectionManager.java | 5 ++-- 16 files changed, 146 insertions(+), 160 deletions(-) delete mode 100644 src/main/java/eu/siacs/conversations/entities/Downloadable.java delete mode 100644 src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java create mode 100644 src/main/java/eu/siacs/conversations/entities/Transferable.java create mode 100644 src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java diff --git a/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/src/main/java/eu/siacs/conversations/entities/Downloadable.java deleted file mode 100644 index 8fae91bb..00000000 --- a/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ /dev/null @@ -1,28 +0,0 @@ -package eu.siacs.conversations.entities; - -public interface Downloadable { - - String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; - String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; - String[] WELL_KNOWN_EXTENSIONS = {"pdf","m4a"}; - - int STATUS_UNKNOWN = 0x200; - int STATUS_CHECKING = 0x201; - int STATUS_FAILED = 0x202; - int STATUS_OFFER = 0x203; - int STATUS_DOWNLOADING = 0x204; - int STATUS_DELETED = 0x205; - int STATUS_OFFER_CHECK_FILESIZE = 0x206; - int STATUS_UPLOADING = 0x207; - - - boolean start(); - - int getStatus(); - - long getFileSize(); - - int getProgress(); - - void cancel(); -} diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java b/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java deleted file mode 100644 index cce22ea3..00000000 --- a/src/main/java/eu/siacs/conversations/entities/DownloadablePlaceholder.java +++ /dev/null @@ -1,34 +0,0 @@ -package eu.siacs.conversations.entities; - -public class DownloadablePlaceholder implements Downloadable { - - private int status; - - public DownloadablePlaceholder(int status) { - this.status = status; - } - @Override - public boolean start() { - return false; - } - - @Override - public int getStatus() { - return status; - } - - @Override - public long getFileSize() { - return 0; - } - - @Override - public int getProgress() { - return 0; - } - - @Override - public void cancel() { - - } -} diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 078a4565..28ef89df 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -70,7 +70,7 @@ public class Message extends AbstractEntity { protected String remoteMsgId = null; protected String serverMsgId = null; protected Conversation conversation = null; - protected Downloadable downloadable = null; + protected Transferable transferable = null; private Message mNextMessage = null; private Message mPreviousMessage = null; @@ -308,12 +308,12 @@ public class Message extends AbstractEntity { this.trueCounterpart = trueCounterpart; } - public Downloadable getDownloadable() { - return this.downloadable; + public Transferable getTransferable() { + return this.transferable; } - public void setDownloadable(Downloadable downloadable) { - this.downloadable = downloadable; + public void setTransferable(Transferable transferable) { + this.transferable = transferable; } public boolean equals(Message message) { @@ -364,8 +364,8 @@ public class Message extends AbstractEntity { public boolean mergeable(final Message message) { return message != null && (message.getType() == Message.TYPE_TEXT && - this.getDownloadable() == null && - message.getDownloadable() == null && + this.getTransferable() == null && + message.getTransferable() == null && message.getEncryption() != Message.ENCRYPTION_PGP && this.getType() == message.getType() && //this.getStatus() == message.getStatus() && @@ -471,7 +471,7 @@ public class Message extends AbstractEntity { if (extensionParts.length == 2) { return extensionParts[extensionParts.length - 1]; } else if (extensionParts.length == 3 && Arrays - .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) + .asList(Transferable.VALID_CRYPTO_EXTENSIONS) .contains(extensionParts[extensionParts.length - 1])) { return extensionParts[extensionParts.length -2]; } @@ -517,8 +517,8 @@ public class Message extends AbstractEntity { } else { return Decision.NEVER; } - } else if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension) - || Arrays.asList(Downloadable.WELL_KNOWN_EXTENSIONS).contains(extension)) { + } else if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension) + || Arrays.asList(Transferable.WELL_KNOWN_EXTENSIONS).contains(extension)) { return Decision.SHOULD; } else { return Decision.NEVER; @@ -539,8 +539,8 @@ public class Message extends AbstractEntity { return params; } params = new FileParams(); - if (this.downloadable != null) { - params.size = this.downloadable.getFileSize(); + if (this.transferable != null) { + params.size = this.transferable.getFileSize(); } if (body == null) { return params; diff --git a/src/main/java/eu/siacs/conversations/entities/Transferable.java b/src/main/java/eu/siacs/conversations/entities/Transferable.java new file mode 100644 index 00000000..2db6e3c9 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/entities/Transferable.java @@ -0,0 +1,28 @@ +package eu.siacs.conversations.entities; + +public interface Transferable { + + String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; + String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; + String[] WELL_KNOWN_EXTENSIONS = {"pdf","m4a"}; + + int STATUS_UNKNOWN = 0x200; + int STATUS_CHECKING = 0x201; + int STATUS_FAILED = 0x202; + int STATUS_OFFER = 0x203; + int STATUS_DOWNLOADING = 0x204; + int STATUS_DELETED = 0x205; + int STATUS_OFFER_CHECK_FILESIZE = 0x206; + int STATUS_UPLOADING = 0x207; + + + boolean start(); + + int getStatus(); + + long getFileSize(); + + int getProgress(); + + void cancel(); +} diff --git a/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java b/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java new file mode 100644 index 00000000..e065953e --- /dev/null +++ b/src/main/java/eu/siacs/conversations/entities/TransferablePlaceholder.java @@ -0,0 +1,34 @@ +package eu.siacs.conversations.entities; + +public class TransferablePlaceholder implements Transferable { + + private int status; + + public TransferablePlaceholder(int status) { + this.status = status; + } + @Override + public boolean start() { + return false; + } + + @Override + public int getStatus() { + return status; + } + + @Override + public long getFileSize() { + return 0; + } + + @Override + public int getProgress() { + return 0; + } + + @Override + public void cancel() { + + } +} diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index fb3f08e3..74e16e7b 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -5,34 +5,26 @@ import android.net.Uri; import android.os.SystemClock; import android.util.Log; -import org.apache.http.conn.ssl.StrictHostnameVerifier; - import java.io.BufferedInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; import java.util.Arrays; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; -public class HttpConnection implements Downloadable { +public class HttpConnection implements Transferable { private HttpConnectionManager mHttpConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -40,7 +32,7 @@ public class HttpConnection implements Downloadable { private URL mUrl; private Message message; private DownloadableFile file; - private int mStatus = Downloadable.STATUS_UNKNOWN; + private int mStatus = Transferable.STATUS_UNKNOWN; private boolean acceptedAutomatically = false; private int mProgress = 0; private long mLastGuiRefresh = 0; @@ -65,12 +57,12 @@ public class HttpConnection implements Downloadable { } public void init(Message message) { - init(message,false); + init(message, false); } public void init(Message message, boolean interactive) { this.message = message; - this.message.setDownloadable(this); + this.message.setTransferable(this); try { mUrl = new URL(message.getBody()); String[] parts = mUrl.getPath().toLowerCase().split("\\."); @@ -110,7 +102,7 @@ public class HttpConnection implements Downloadable { public void cancel() { mHttpConnectionManager.finishConnection(this); - message.setDownloadable(null); + message.setTransferable(null); mXmppConnectionService.updateConversationUi(); } @@ -118,7 +110,7 @@ public class HttpConnection implements Downloadable { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); mXmppConnectionService.sendBroadcast(intent); - message.setDownloadable(null); + message.setTransferable(null); mHttpConnectionManager.finishConnection(this); mXmppConnectionService.updateConversationUi(); if (acceptedAutomatically) { diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 61e87715..dd842754 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -14,7 +14,7 @@ import javax.net.ssl.HttpsURLConnection; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.persistance.FileBackend; @@ -27,7 +27,7 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -public class HttpUploadConnection implements Downloadable { +public class HttpUploadConnection implements Transferable { private HttpConnectionManager mHttpConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -76,13 +76,13 @@ public class HttpUploadConnection implements Downloadable { private void fail() { mHttpConnectionManager.finishUploadConnection(this); - message.setDownloadable(null); + message.setTransferable(null); mXmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); } public void init(Message message) { this.message = message; - message.setDownloadable(this); + message.setTransferable(this); mXmppConnectionService.markMessage(message,Message.STATUS_UNSEND); this.account = message.getConversation().getAccount(); this.file = mXmppConnectionService.getFileBackend().getFile(message, false); @@ -164,7 +164,7 @@ public class HttpUploadConnection implements Downloadable { mGetUrl = new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)); } mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl); - message.setDownloadable(null); + message.setTransferable(null); message.setCounterpart(message.getConversation().getJid().toBareJid()); if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { mXmppConnectionService.getPgpEngine().encrypt(message, new UiCallback() { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 52373fef..ee53e90e 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -33,7 +33,7 @@ import android.webkit.MimeTypeMap; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; @@ -80,7 +80,7 @@ public class FileBackend { if (path.startsWith("/")) { return new DownloadableFile(path); } else { - if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension)) { return new DownloadableFile(getConversationsFileDirectory() + path); } else { return new DownloadableFile(getConversationsImageDirectory() + path); diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 49543eeb..2b59e473 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -18,7 +18,6 @@ import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.TaskStackBuilder; import android.text.Html; import android.util.DisplayMetrics; -import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; @@ -42,7 +41,6 @@ import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.ui.TimePreference; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.xmpp.XmppConnection; public class NotificationService { @@ -303,7 +301,7 @@ public class NotificationService { final ArrayList tmp = new ArrayList<>(); for (final Message msg : messages) { if (msg.getType() == Message.TYPE_TEXT - && msg.getDownloadable() == null) { + && msg.getTransferable() == null) { tmp.add(msg); } } @@ -335,7 +333,7 @@ public class NotificationService { private Message getImage(final Iterable messages) { for (final Message message : messages) { if (message.getType() == Message.TYPE_IMAGE - && message.getDownloadable() == null + && message.getTransferable() == null && message.getEncryption() != Message.ENCRYPTION_PGP) { return message; } @@ -346,7 +344,7 @@ public class NotificationService { private Message getFirstDownloadableMessage(final Iterable messages) { for (final Message message : messages) { if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && - message.getDownloadable() != null) { + message.getTransferable() != null) { return message; } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e3cfb09e..2dd0f04c 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -57,12 +57,11 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.Transferable; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; -import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.generator.MessageGenerator; import eu.siacs.conversations.generator.PresenceGenerator; @@ -975,7 +974,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onMessageFound(Message message) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); } } }); @@ -986,7 +985,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Message message = conversation.findMessageWithFileAndUuid(uuid); if (message != null) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); updateConversationUi(); } return; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 20c6681b..fb7070ee 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -45,9 +45,9 @@ import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presences; @@ -439,14 +439,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa MenuItem downloadFile = menu.findItem(R.id.download_file); MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE) - && m.getDownloadable() == null + && m.getTransferable() == null && !GeoHelper.isGeoUri(m.getBody()) && m.treatAsDownloadable() != Message.Decision.MUST) { copyText.setVisible(true); } if ((m.getType() != Message.TYPE_TEXT && m.getType() != Message.TYPE_PRIVATE - && m.getDownloadable() == null) + && m.getTransferable() == null) || (GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(true); } @@ -458,11 +458,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa || m.treatAsDownloadable() == Message.Decision.MUST) { copyUrl.setVisible(true); } - if (m.getType() == Message.TYPE_TEXT && m.getDownloadable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) { + if (m.getType() == Message.TYPE_TEXT && m.getTransferable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) { downloadFile.setVisible(true); downloadFile.setTitle(activity.getString(R.string.download_x_file,UIHelper.getFileDescriptionString(activity, m))); } - if ((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) + if ((m.getTransferable() != null && !(m.getTransferable() instanceof TransferablePlaceholder)) || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING || m.getStatus() == Message.STATUS_OFFERED))) { cancelTransmission.setVisible(true); @@ -529,7 +529,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); - message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); return; } } @@ -561,9 +561,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } private void cancelTransmission(Message message) { - Downloadable downloadable = message.getDownloadable(); - if (downloadable != null) { - downloadable.cancel(); + Transferable transferable = message.getTransferable(); + if (transferable != null) { + transferable.cancel(); } else { activity.xmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); } @@ -757,7 +757,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getEncryption() == Message.ENCRYPTION_PGP && (message.getStatus() == Message.STATUS_RECEIVED || message .getStatus() >= Message.STATUS_SEND) - && message.getDownloadable() == null) { + && message.getTransferable() == null) { if (!mEncryptedMessages.contains(message)) { mEncryptedMessages.add(message); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 5cbc73ec..bfe44326 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -21,7 +21,7 @@ import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.XmppActivity; @@ -69,8 +69,8 @@ public class ConversationAdapter extends ArrayAdapter { } if (message.getFileParams().width > 0 - && (message.getDownloadable() == null - || message.getDownloadable().getStatus() != Downloadable.STATUS_DELETED)) { + && (message.getTransferable() == null + || message.getTransferable().getStatus() != Transferable.STATUS_DELETED)) { mLastMessage.setVisibility(View.GONE); imagePreview.setVisibility(View.VISIBLE); activity.loadBitmap(message, imagePreview); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index d0a05c37..4d4e2679 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -29,7 +29,7 @@ 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.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message.FileParams; @@ -99,14 +99,14 @@ public class MessageAdapter extends ArrayAdapter { } boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI && message.getMergedStatus() <= Message.STATUS_RECEIVED; - if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getDownloadable() != null) { + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) { FileParams params = message.getFileParams(); if (params.size > (1.5 * 1024 * 1024)) { filesize = params.size / (1024 * 1024)+ " MiB"; } else if (params.size > 0) { filesize = params.size / 1024 + " KiB"; } - if (message.getDownloadable() != null && message.getDownloadable().getStatus() == Downloadable.STATUS_FAILED) { + if (message.getTransferable() != null && message.getTransferable().getStatus() == Transferable.STATUS_FAILED) { error = true; } } @@ -115,7 +115,7 @@ public class MessageAdapter extends ArrayAdapter { info = getContext().getString(R.string.waiting); break; case Message.STATUS_UNSEND: - Downloadable d = message.getDownloadable(); + Transferable d = message.getTransferable(); if (d!=null) { info = getContext().getString(R.string.sending_file,d.getProgress()); } else { @@ -482,11 +482,11 @@ public class MessageAdapter extends ArrayAdapter { } }); - final Downloadable downloadable = message.getDownloadable(); - if (downloadable != null && downloadable.getStatus() != Downloadable.STATUS_UPLOADING) { - if (downloadable.getStatus() == Downloadable.STATUS_OFFER) { + final Transferable transferable = message.getTransferable(); + if (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING) { + if (transferable.getStatus() == Transferable.STATUS_OFFER) { displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); - } else if (downloadable.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { + } else if (transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); } else { displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first); @@ -536,9 +536,9 @@ public class MessageAdapter extends ArrayAdapter { } public void startDownloadable(Message message) { - Downloadable downloadable = message.getDownloadable(); - if (downloadable != null) { - if (!downloadable.start()) { + Transferable transferable = message.getTransferable(); + if (transferable != null) { + if (!transferable.start()) { Toast.makeText(activity, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show(); } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index ddc4781c..8047993a 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,5 @@ package eu.siacs.conversations.utils; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -10,7 +9,7 @@ import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.xmpp.jid.Jid; @@ -142,24 +141,24 @@ public class UIHelper { } public static Pair getMessagePreview(final Context context, final Message message) { - final Downloadable d = message.getDownloadable(); + final Transferable d = message.getTransferable(); if (d != null ) { switch (d.getStatus()) { - case Downloadable.STATUS_CHECKING: + case Transferable.STATUS_CHECKING: return new Pair<>(context.getString(R.string.checking_image),true); - case Downloadable.STATUS_DOWNLOADING: + case Transferable.STATUS_DOWNLOADING: return new Pair<>(context.getString(R.string.receiving_x_file, getFileDescriptionString(context,message), d.getProgress()),true); - case Downloadable.STATUS_OFFER: - case Downloadable.STATUS_OFFER_CHECK_FILESIZE: + case Transferable.STATUS_OFFER: + case Transferable.STATUS_OFFER_CHECK_FILESIZE: return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context,message)),true); - case Downloadable.STATUS_DELETED: + case Transferable.STATUS_DELETED: return new Pair<>(context.getString(R.string.file_deleted),true); - case Downloadable.STATUS_FAILED: + case Transferable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed),true); - case Downloadable.STATUS_UPLOADING: + case Transferable.STATUS_UPLOADING: if (message.getStatus() == Message.STATUS_OFFERED) { return new Pair<>(context.getString(R.string.offering_x_file, getFileDescriptionString(context, message)), true); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 8e4282a9..33534724 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -1,6 +1,5 @@ package eu.siacs.conversations.xmpp.jingle; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -16,9 +15,9 @@ import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.DownloadablePlaceholder; +import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; @@ -29,7 +28,7 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; import eu.siacs.conversations.xmpp.jingle.stanzas.Reason; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -public class JingleConnection implements Downloadable { +public class JingleConnection implements Transferable { private JingleConnectionManager mJingleConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -43,7 +42,7 @@ public class JingleConnection implements Downloadable { private int ibbBlockSize = 4096; private int mJingleStatus = -1; - private int mStatus = Downloadable.STATUS_UNKNOWN; + private int mStatus = Transferable.STATUS_UNKNOWN; private Message message; private String sessionId; private Account account; @@ -199,8 +198,8 @@ public class JingleConnection implements Downloadable { this.contentCreator = "initiator"; this.contentName = this.mJingleConnectionManager.nextRandomId(); this.message = message; - this.message.setDownloadable(this); - this.mStatus = Downloadable.STATUS_UPLOADING; + this.message.setTransferable(this); + this.mStatus = Transferable.STATUS_UPLOADING; this.account = message.getConversation().getAccount(); this.initiator = this.account.getJid(); this.responder = this.message.getCounterpart(); @@ -256,8 +255,8 @@ public class JingleConnection implements Downloadable { packet.getFrom().toBareJid(), false); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); this.message.setStatus(Message.STATUS_RECEIVED); - this.mStatus = Downloadable.STATUS_OFFER; - this.message.setDownloadable(this); + this.mStatus = Transferable.STATUS_OFFER; + this.message.setTransferable(this); final Jid from = packet.getFrom(); this.message.setCounterpart(from); this.account = account; @@ -408,7 +407,7 @@ public class JingleConnection implements Downloadable { private void sendAccept() { mJingleStatus = JINGLE_STATUS_ACCEPTED; - this.mStatus = Downloadable.STATUS_DOWNLOADING; + this.mStatus = Transferable.STATUS_DOWNLOADING; mXmppConnectionService.updateConversationUi(); this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() { @Override @@ -639,7 +638,7 @@ public class JingleConnection implements Downloadable { this.disconnectSocks5Connections(); this.mJingleStatus = JINGLE_STATUS_FINISHED; this.message.setStatus(Message.STATUS_RECEIVED); - this.message.setDownloadable(null); + this.message.setTransferable(null); this.mXmppConnectionService.updateMessage(message); this.mJingleConnectionManager.finishConnection(this); } @@ -716,7 +715,7 @@ public class JingleConnection implements Downloadable { if (this.transport != null && this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); } - this.message.setDownloadable(null); + this.message.setTransferable(null); this.mJingleConnectionManager.finishConnection(this); } @@ -728,7 +727,7 @@ public class JingleConnection implements Downloadable { this.sendCancel(); this.mJingleConnectionManager.finishConnection(this); if (this.responder.equals(account.getJid())) { - this.message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); if (this.file!=null) { file.delete(); } @@ -736,7 +735,7 @@ public class JingleConnection implements Downloadable { } else { this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED); - this.message.setDownloadable(null); + this.message.setTransferable(null); } } @@ -748,7 +747,7 @@ public class JingleConnection implements Downloadable { } if (this.message != null) { if (this.responder.equals(account.getJid())) { - this.message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); if (this.file!=null) { file.delete(); } @@ -756,7 +755,7 @@ public class JingleConnection implements Downloadable { } else { this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED); - this.message.setDownloadable(null); + this.message.setTransferable(null); } } this.mJingleConnectionManager.finishConnection(this); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index f0cf5d8a..cadf9df3 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -9,14 +9,13 @@ import android.annotation.SuppressLint; import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; import eu.siacs.conversations.xmpp.stanzas.IqPacket; @@ -59,7 +58,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { } public JingleConnection createNewConnection(Message message) { - Downloadable old = message.getDownloadable(); + Transferable old = message.getTransferable(); if (old != null) { old.cancel(); } -- cgit v1.2.3 From 78aff1329fa43b568e66fb1cf4fbf7356cfbeb3a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:14:13 +0200 Subject: renamed HttpConnection to HttpDownloadConnection --- .../eu/siacs/conversations/crypto/PgpEngine.java | 2 +- .../siacs/conversations/http/HttpConnection.java | 269 --------------------- .../conversations/http/HttpConnectionManager.java | 16 +- .../conversations/http/HttpDownloadConnection.java | 269 +++++++++++++++++++++ .../siacs/conversations/parser/MessageParser.java | 2 +- .../conversations/ui/ConversationFragment.java | 2 +- .../conversations/ui/adapter/MessageAdapter.java | 2 +- 7 files changed, 281 insertions(+), 281 deletions(-) delete mode 100644 src/main/java/eu/siacs/conversations/http/HttpConnection.java create mode 100644 src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index cba80ba0..505c4b0f 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -61,7 +61,7 @@ public class PgpEngine { if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); + manager.createNewDownloadConnection(message); } callback.success(message); } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java deleted file mode 100644 index 74e16e7b..00000000 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ /dev/null @@ -1,269 +0,0 @@ -package eu.siacs.conversations.http; - -import android.content.Intent; -import android.net.Uri; -import android.os.SystemClock; -import android.util.Log; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLHandshakeException; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Transferable; -import eu.siacs.conversations.entities.DownloadableFile; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; - -public class HttpConnection implements Transferable { - - private HttpConnectionManager mHttpConnectionManager; - private XmppConnectionService mXmppConnectionService; - - private URL mUrl; - private Message message; - private DownloadableFile file; - private int mStatus = Transferable.STATUS_UNKNOWN; - private boolean acceptedAutomatically = false; - private int mProgress = 0; - private long mLastGuiRefresh = 0; - - public HttpConnection(HttpConnectionManager manager) { - this.mHttpConnectionManager = manager; - this.mXmppConnectionService = manager.getXmppConnectionService(); - } - - @Override - public boolean start() { - if (mXmppConnectionService.hasInternetConnection()) { - if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) { - checkFileSize(true); - } else { - new Thread(new FileDownloader(true)).start(); - } - return true; - } else { - return false; - } - } - - public void init(Message message) { - init(message, false); - } - - public void init(Message message, boolean interactive) { - this.message = message; - this.message.setTransferable(this); - try { - mUrl = new URL(message.getBody()); - String[] parts = mUrl.getPath().toLowerCase().split("\\."); - String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; - String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; - if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { - this.message.setEncryption(Message.ENCRYPTION_PGP); - } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { - this.message.setEncryption(Message.ENCRYPTION_NONE); - } - String extension; - if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(lastPart)) { - extension = secondToLast; - } else { - extension = lastPart; - } - message.setRelativeFilePath(message.getUuid()+"."+extension); - this.file = mXmppConnectionService.getFileBackend().getFile(message, false); - String reference = mUrl.getRef(); - if (reference != null && reference.length() == 96) { - this.file.setKey(CryptoHelper.hexToBytes(reference)); - } - - if (this.message.getEncryption() == Message.ENCRYPTION_OTR - && this.file.getKey() == null) { - this.message.setEncryption(Message.ENCRYPTION_NONE); - } - checkFileSize(true); - } catch (MalformedURLException e) { - this.cancel(); - } - } - - private void checkFileSize(boolean interactive) { - new Thread(new FileSizeChecker(interactive)).start(); - } - - public void cancel() { - mHttpConnectionManager.finishConnection(this); - message.setTransferable(null); - mXmppConnectionService.updateConversationUi(); - } - - private void finish() { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(file)); - mXmppConnectionService.sendBroadcast(intent); - message.setTransferable(null); - mHttpConnectionManager.finishConnection(this); - mXmppConnectionService.updateConversationUi(); - if (acceptedAutomatically) { - mXmppConnectionService.getNotificationService().push(message); - } - } - - private void changeStatus(int status) { - this.mStatus = status; - mXmppConnectionService.updateConversationUi(); - } - - private class FileSizeChecker implements Runnable { - - private boolean interactive = false; - - public FileSizeChecker(boolean interactive) { - this.interactive = interactive; - } - - @Override - public void run() { - long size; - try { - size = retrieveFileSize(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER_CHECK_FILESIZE); - HttpConnection.this.acceptedAutomatically = false; - HttpConnection.this.mXmppConnectionService.getNotificationService().push(message); - return; - } catch (IOException e) { - Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); - if (interactive) { - mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); - } - cancel(); - return; - } - file.setExpectedSize(size); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { - HttpConnection.this.acceptedAutomatically = true; - new Thread(new FileDownloader(interactive)).start(); - } else { - changeStatus(STATUS_OFFER); - HttpConnection.this.acceptedAutomatically = false; - HttpConnection.this.mXmppConnectionService.getNotificationService().push(message); - } - } - - private long retrieveFileSize() throws IOException { - Log.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } - try { - return Long.parseLong(contentLength, 10); - } catch (NumberFormatException e) { - throw new IOException(); - } - } - - } - - private class FileDownloader implements Runnable { - - private boolean interactive = false; - - public FileDownloader(boolean interactive) { - this.interactive = interactive; - } - - @Override - public void run() { - try { - changeStatus(STATUS_DOWNLOADING); - download(); - updateImageBounds(); - finish(); - } catch (SSLHandshakeException e) { - changeStatus(STATUS_OFFER); - } catch (IOException e) { - mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); - cancel(); - } - } - - private void download() throws SSLHandshakeException, IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); - file.getParentFile().mkdirs(); - file.createNewFile(); - OutputStream os = file.createOutputStream(); - if (os == null) { - throw new IOException(); - } - long transmitted = 0; - long expected = file.getExpectedSize(); - int count = -1; - byte[] buffer = new byte[1024]; - while ((count = is.read(buffer)) != -1) { - transmitted += count; - os.write(buffer, 0, count); - updateProgress((int) ((((double) transmitted) / expected) * 100)); - } - os.flush(); - os.close(); - is.close(); - } - - private void updateImageBounds() { - message.setType(Message.TYPE_FILE); - mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); - mXmppConnectionService.updateMessage(message); - } - - } - - public void updateProgress(int i) { - this.mProgress = i; - if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { - this.mLastGuiRefresh = SystemClock.elapsedRealtime(); - mXmppConnectionService.updateConversationUi(); - } - } - - @Override - public int getStatus() { - return this.mStatus; - } - - @Override - public long getFileSize() { - if (this.file != null) { - return this.file.getExpectedSize(); - } else { - return 0; - } - } - - @Override - public int getProgress() { - return this.mProgress; - } -} diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java index 4d6395e2..58a6d1e3 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java @@ -24,17 +24,17 @@ public class HttpConnectionManager extends AbstractConnectionManager { super(service); } - private List connections = new CopyOnWriteArrayList<>(); + private List downloadConnections = new CopyOnWriteArrayList<>(); private List uploadConnections = new CopyOnWriteArrayList<>(); - public HttpConnection createNewConnection(Message message) { - return this.createNewConnection(message,false); + public HttpDownloadConnection createNewDownloadConnection(Message message) { + return this.createNewDownloadConnection(message, false); } - public HttpConnection createNewConnection(Message message,boolean interactive) { - HttpConnection connection = new HttpConnection(this); + public HttpDownloadConnection createNewDownloadConnection(Message message, boolean interactive) { + HttpDownloadConnection connection = new HttpDownloadConnection(this); connection.init(message,interactive); - this.connections.add(connection); + this.downloadConnections.add(connection); return connection; } @@ -45,8 +45,8 @@ public class HttpConnectionManager extends AbstractConnectionManager { return connection; } - public void finishConnection(HttpConnection connection) { - this.connections.remove(connection); + public void finishConnection(HttpDownloadConnection connection) { + this.downloadConnections.remove(connection); } public void finishUploadConnection(HttpUploadConnection httpUploadConnection) { diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java new file mode 100644 index 00000000..6fcd8c87 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -0,0 +1,269 @@ +package eu.siacs.conversations.http; + +import android.content.Intent; +import android.net.Uri; +import android.os.SystemClock; +import android.util.Log; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLHandshakeException; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Transferable; +import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; + +public class HttpDownloadConnection implements Transferable { + + private HttpConnectionManager mHttpConnectionManager; + private XmppConnectionService mXmppConnectionService; + + private URL mUrl; + private Message message; + private DownloadableFile file; + private int mStatus = Transferable.STATUS_UNKNOWN; + private boolean acceptedAutomatically = false; + private int mProgress = 0; + private long mLastGuiRefresh = 0; + + public HttpDownloadConnection(HttpConnectionManager manager) { + this.mHttpConnectionManager = manager; + this.mXmppConnectionService = manager.getXmppConnectionService(); + } + + @Override + public boolean start() { + if (mXmppConnectionService.hasInternetConnection()) { + if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) { + checkFileSize(true); + } else { + new Thread(new FileDownloader(true)).start(); + } + return true; + } else { + return false; + } + } + + public void init(Message message) { + init(message, false); + } + + public void init(Message message, boolean interactive) { + this.message = message; + this.message.setTransferable(this); + try { + mUrl = new URL(message.getBody()); + String[] parts = mUrl.getPath().toLowerCase().split("\\."); + String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; + String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; + if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { + this.message.setEncryption(Message.ENCRYPTION_PGP); + } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { + this.message.setEncryption(Message.ENCRYPTION_NONE); + } + String extension; + if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(lastPart)) { + extension = secondToLast; + } else { + extension = lastPart; + } + message.setRelativeFilePath(message.getUuid()+"."+extension); + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + String reference = mUrl.getRef(); + if (reference != null && reference.length() == 96) { + this.file.setKey(CryptoHelper.hexToBytes(reference)); + } + + if (this.message.getEncryption() == Message.ENCRYPTION_OTR + && this.file.getKey() == null) { + this.message.setEncryption(Message.ENCRYPTION_NONE); + } + checkFileSize(true); + } catch (MalformedURLException e) { + this.cancel(); + } + } + + private void checkFileSize(boolean interactive) { + new Thread(new FileSizeChecker(interactive)).start(); + } + + public void cancel() { + mHttpConnectionManager.finishConnection(this); + message.setTransferable(null); + mXmppConnectionService.updateConversationUi(); + } + + private void finish() { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(file)); + mXmppConnectionService.sendBroadcast(intent); + message.setTransferable(null); + mHttpConnectionManager.finishConnection(this); + mXmppConnectionService.updateConversationUi(); + if (acceptedAutomatically) { + mXmppConnectionService.getNotificationService().push(message); + } + } + + private void changeStatus(int status) { + this.mStatus = status; + mXmppConnectionService.updateConversationUi(); + } + + private class FileSizeChecker implements Runnable { + + private boolean interactive = false; + + public FileSizeChecker(boolean interactive) { + this.interactive = interactive; + } + + @Override + public void run() { + long size; + try { + size = retrieveFileSize(); + } catch (SSLHandshakeException e) { + changeStatus(STATUS_OFFER_CHECK_FILESIZE); + HttpDownloadConnection.this.acceptedAutomatically = false; + HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + return; + } catch (IOException e) { + Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); + if (interactive) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + } + cancel(); + return; + } + file.setExpectedSize(size); + if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { + HttpDownloadConnection.this.acceptedAutomatically = true; + new Thread(new FileDownloader(interactive)).start(); + } else { + changeStatus(STATUS_OFFER); + HttpDownloadConnection.this.acceptedAutomatically = false; + HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message); + } + } + + private long retrieveFileSize() throws IOException { + Log.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + if (contentLength == null) { + throw new IOException(); + } + try { + return Long.parseLong(contentLength, 10); + } catch (NumberFormatException e) { + throw new IOException(); + } + } + + } + + private class FileDownloader implements Runnable { + + private boolean interactive = false; + + public FileDownloader(boolean interactive) { + this.interactive = interactive; + } + + @Override + public void run() { + try { + changeStatus(STATUS_DOWNLOADING); + download(); + updateImageBounds(); + finish(); + } catch (SSLHandshakeException e) { + changeStatus(STATUS_OFFER); + } catch (IOException e) { + mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + cancel(); + } + } + + private void download() throws SSLHandshakeException, IOException { + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); + file.getParentFile().mkdirs(); + file.createNewFile(); + OutputStream os = file.createOutputStream(); + if (os == null) { + throw new IOException(); + } + long transmitted = 0; + long expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[1024]; + while ((count = is.read(buffer)) != -1) { + transmitted += count; + os.write(buffer, 0, count); + updateProgress((int) ((((double) transmitted) / expected) * 100)); + } + os.flush(); + os.close(); + is.close(); + } + + private void updateImageBounds() { + message.setType(Message.TYPE_FILE); + mXmppConnectionService.getFileBackend().updateFileParams(message, mUrl); + mXmppConnectionService.updateMessage(message); + } + + } + + public void updateProgress(int i) { + this.mProgress = i; + if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { + this.mLastGuiRefresh = SystemClock.elapsedRealtime(); + mXmppConnectionService.updateConversationUi(); + } + } + + @Override + public int getStatus() { + return this.mStatus; + } + + @Override + public long getFileSize() { + if (this.file != null) { + return this.file.getExpectedSize(); + } else { + return 0; + } + } + + @Override + public int getProgress() { + return this.mProgress; + } +} diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 72f822ca..d46ff195 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -362,7 +362,7 @@ public class MessageParser extends AbstractParser implements } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); + manager.createNewDownloadConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index fb7070ee..7983fdca 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -557,7 +557,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private void downloadFile(Message message) { activity.xmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + .createNewDownloadConnection(message); } private void cancelTransmission(Message message) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 4d4e2679..167f3f02 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -543,7 +543,7 @@ public class MessageAdapter extends ArrayAdapter { Toast.LENGTH_SHORT).show(); } } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { - activity.xmppConnectionService.getHttpConnectionManager().createNewConnection(message); + activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message); } } -- cgit v1.2.3 From fce613e4a6ff389feac23fb843c813276c78203b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:15:44 +0200 Subject: version bump to 1.5.0-beta --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e93f3946..ca78ddea 100644 --- a/build.gradle +++ b/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 75 - versionName "1.4.7" + versionCode 76 + versionName "1.5.0-beta" } compileOptions { -- cgit v1.2.3 From 81af16fb6cf71ac5a3e6732cb937e182b9134e2f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:21:16 +0200 Subject: added changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1170e5a2..8489e9db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +####Version 1.5.0 +* upload files to HTTP host and share them in MUCs. requiers new [HttpUploadComponent](https://github.com/siacs/HttpUploadComponent) on server side + ####Version 1.4.5 * fixes to message parser to not display some ejabberd muc status messages -- cgit v1.2.3 From c4876fab1b2adcbc6c107695d5b48ebe555c93a5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2015 20:00:40 +0200 Subject: spelling --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8489e9db..2fe23833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ###Changelog ####Version 1.5.0 -* upload files to HTTP host and share them in MUCs. requiers new [HttpUploadComponent](https://github.com/siacs/HttpUploadComponent) on server side +* upload files to HTTP host and share them in MUCs. requires new [HttpUploadComponent](https://github.com/siacs/HttpUploadComponent) on server side ####Version 1.4.5 * fixes to message parser to not display some ejabberd muc status messages -- cgit v1.2.3 From 5dd83a5fe685dd3268986ca0a73f21c4dcbc6af5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2015 21:23:58 +0200 Subject: null check otr fingerprint before display --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 466bc409..2dec203d 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -91,7 +91,9 @@ public final class CryptoHelper { } public static String prettifyFingerprint(String fingerprint) { - if (fingerprint.length() < 40) { + if (fingerprint==null) { + return ""; + } else if (fingerprint.length() < 40) { return fingerprint; } StringBuilder builder = new StringBuilder(fingerprint); -- cgit v1.2.3 From 4274fe90ac8d08cd7e837d7c03a91ed9ea0f9b19 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2015 21:24:30 +0200 Subject: try to catch weird npe in android sdk --- src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index ee53e90e..ab191285 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -235,6 +235,8 @@ public class FileBackend { } else { throw new FileCopyException(R.string.error_out_of_memory); } + } catch (NullPointerException e) { + throw new FileCopyException(R.string.error_io_exception); } finally { close(os); close(is); -- cgit v1.2.3 From 58bc4cba0656d2dcdd554097ae5f8362bfb478a0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2015 21:24:51 +0200 Subject: only try to change affilations for known jids --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2dd0f04c..ee212aed 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1699,7 +1699,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) { List jids = new ArrayList<>(); for (MucOptions.User user : conference.getMucOptions().getUsers()) { - if (user.getAffiliation() == before) { + if (user.getAffiliation() == before && user.getJid() != null) { jids.add(user.getJid()); } } -- cgit v1.2.3 From 558d065d48b43c190cac706870cf8d97c70ecbfd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2015 17:59:22 +0200 Subject: made lock button reflect encryption status of the next messages instead of the last --- .../conversations/ui/ConversationActivity.java | 26 +++++++++------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a507a5fe..a488e3f2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -374,8 +374,7 @@ public class ConversationActivity extends XmppActivity } else { menuAdd.setVisible(!isConversationsOverviewHideable()); if (this.getSelectedConversation() != null) { - if (this.getSelectedConversation().getLatestMessage() - .getEncryption() != Message.ENCRYPTION_NONE) { + if (this.getSelectedConversation().getNextEncryption(forceEncryption()) != Message.ENCRYPTION_NONE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { menuSecure.setIcon(R.drawable.ic_lock_white_24dp); } else { @@ -740,14 +739,11 @@ public class ConversationActivity extends XmppActivity break; case R.id.encryption_choice_pgp: if (hasPgp()) { - if (conversation.getAccount().getKeys() - .has("pgp_signature")) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); + if (conversation.getAccount().getKeys().has("pgp_signature")) { + conversation.setNextEncryption(Message.ENCRYPTION_PGP); item.setChecked(true); } else { - announcePgp(conversation.getAccount(), - conversation); + announcePgp(conversation.getAccount(),conversation); } } else { showInstallPgpDialog(); @@ -757,16 +753,16 @@ public class ConversationActivity extends XmppActivity conversation.setNextEncryption(Message.ENCRYPTION_NONE); break; } - xmppConnectionService.databaseBackend - .updateConversation(conversation); + xmppConnectionService.databaseBackend.updateConversation(conversation); fragment.updateChatMsgHint(); + invalidateOptionsMenu(); return true; } }); popup.inflate(R.menu.encryption_choices); MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr); - MenuItem none = popup.getMenu().findItem( - R.id.encryption_choice_none); + MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none); + MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp); if (conversation.getMode() == Conversation.MODE_MULTI) { otr.setEnabled(false); } else { @@ -782,12 +778,10 @@ public class ConversationActivity extends XmppActivity otr.setChecked(true); break; case Message.ENCRYPTION_PGP: - popup.getMenu().findItem(R.id.encryption_choice_pgp) - .setChecked(true); + pgp.setChecked(true); break; default: - popup.getMenu().findItem(R.id.encryption_choice_none) - .setChecked(true); + none.setChecked(true); break; } popup.show(); -- cgit v1.2.3 From 84bfe8c72132923bfb6ac6f6adb2c56d1d037172 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2015 20:17:12 +0200 Subject: catch exception on broken android phones --- src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 7983fdca..d254ece7 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.ui; import android.app.AlertDialog; import android.app.Fragment; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -513,7 +514,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } shareIntent.setType(mime); } - activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); + try { + activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); + } catch (ActivityNotFoundException e) { + //This should happen only on faulty androids because normally chooser is always available + Toast.makeText(activity,R.string.no_application_found_to_open_file,Toast.LENGTH_SHORT).show(); + } } private void copyText(Message message) { -- cgit v1.2.3 From ffffca10f0c3e399fbbcde200ea4758acc5ba03f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 13 Jul 2015 12:55:13 +0200 Subject: renamed colors --- .../services/NotificationService.java | 2 +- .../eu/siacs/conversations/ui/XmppActivity.java | 20 +++---- src/main/res/drawable/es_slidingpane_shadow.xml | 2 +- src/main/res/drawable/grey.xml | 2 +- src/main/res/drawable/infocard_border.xml | 4 +- src/main/res/drawable/message_border.xml | 2 +- src/main/res/drawable/snackbar.xml | 2 +- .../fragment_conversations_overview.xml | 6 +- src/main/res/layout/account_row.xml | 4 +- src/main/res/layout/actionview_search.xml | 4 +- src/main/res/layout/activity_about.xml | 4 +- src/main/res/layout/activity_change_password.xml | 22 ++++---- src/main/res/layout/activity_contact_details.xml | 12 ++-- src/main/res/layout/activity_edit_account.xml | 64 +++++++++++----------- src/main/res/layout/activity_muc_details.xml | 12 ++-- .../layout/activity_publish_profile_picture.xml | 16 +++--- .../res/layout/activity_start_conversation.xml | 2 +- src/main/res/layout/activity_verify_otr.xml | 24 ++++---- src/main/res/layout/contact.xml | 6 +- src/main/res/layout/contact_key.xml | 4 +- src/main/res/layout/conversation_list_row.xml | 12 ++-- src/main/res/layout/create_contact_dialog.xml | 8 +-- src/main/res/layout/fragment_conversation.xml | 14 ++--- .../res/layout/fragment_conversations_overview.xml | 6 +- src/main/res/layout/join_conference_dialog.xml | 8 +-- src/main/res/layout/list_item_tag.xml | 2 +- src/main/res/layout/manage_accounts.xml | 4 +- src/main/res/layout/message_received.xml | 8 +-- src/main/res/layout/message_sent.xml | 8 +-- src/main/res/layout/message_status.xml | 2 +- src/main/res/layout/quickedit.xml | 2 +- src/main/res/values-v21/themes.xml | 4 +- src/main/res/values/colors.xml | 28 +++++----- src/main/res/values/strings.xml | 1 + src/main/res/values/styles.xml | 2 +- src/main/res/values/themes.xml | 4 +- 36 files changed, 162 insertions(+), 165 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 2b59e473..956f704e 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -178,7 +178,7 @@ public class NotificationService { } private void setNotificationColor(final Builder mBuilder) { - mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); + mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.green500)); } private void updateNotification(final boolean notify) { diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index ddad1e30..7c994c31 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -334,14 +334,14 @@ public abstract class XmppActivity extends Activity { super.onCreate(savedInstanceState); metrics = getResources().getDisplayMetrics(); ExceptionHelper.init(getApplicationContext()); - mPrimaryTextColor = getResources().getColor(R.color.primarytext); - mSecondaryTextColor = getResources().getColor(R.color.secondarytext); - mColorRed = getResources().getColor(R.color.red); - mColorOrange = getResources().getColor(R.color.orange); - mColorGreen = getResources().getColor(R.color.green); - mPrimaryColor = getResources().getColor(R.color.primary); - mPrimaryBackgroundColor = getResources().getColor(R.color.primarybackground); - mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); + mPrimaryTextColor = getResources().getColor(R.color.black87); + mSecondaryTextColor = getResources().getColor(R.color.black54); + mColorRed = getResources().getColor(R.color.red500); + mColorOrange = getResources().getColor(R.color.orange500); + mColorGreen = getResources().getColor(R.color.green500); + mPrimaryColor = getResources().getColor(R.color.green500); + mPrimaryBackgroundColor = getResources().getColor(R.color.grey50); + mSecondaryBackgroundColor = getResources().getColor(R.color.grey200); this.mTheme = findTheme(); setTheme(this.mTheme); this.mUsingEnterKey = usingEnterKey(); @@ -719,10 +719,6 @@ public abstract class XmppActivity extends Activity { return this.mColorRed; } - public int getPrimaryColor() { - return this.mPrimaryColor; - } - public int getOnlineColor() { return this.mColorGreen; } diff --git a/src/main/res/drawable/es_slidingpane_shadow.xml b/src/main/res/drawable/es_slidingpane_shadow.xml index 44ffd4ea..de96e08f 100644 --- a/src/main/res/drawable/es_slidingpane_shadow.xml +++ b/src/main/res/drawable/es_slidingpane_shadow.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/src/main/res/drawable/infocard_border.xml b/src/main/res/drawable/infocard_border.xml index 7c7ded57..e01e1442 100644 --- a/src/main/res/drawable/infocard_border.xml +++ b/src/main/res/drawable/infocard_border.xml @@ -1,13 +1,13 @@ - + + android:color="@color/black12" > - + \ No newline at end of file diff --git a/src/main/res/drawable/snackbar.xml b/src/main/res/drawable/snackbar.xml index 951d7aee..2645b136 100644 --- a/src/main/res/drawable/snackbar.xml +++ b/src/main/res/drawable/snackbar.xml @@ -1,7 +1,7 @@ - + diff --git a/src/main/res/layout-w945dp/fragment_conversations_overview.xml b/src/main/res/layout-w945dp/fragment_conversations_overview.xml index 50039c03..7ae1788d 100644 --- a/src/main/res/layout-w945dp/fragment_conversations_overview.xml +++ b/src/main/res/layout-w945dp/fragment_conversations_overview.xml @@ -9,15 +9,15 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:background="@color/primarybackground" + android:background="@color/grey50" android:orientation="vertical" > diff --git a/src/main/res/layout/account_row.xml b/src/main/res/layout/account_row.xml index 0e73dd64..06716a10 100644 --- a/src/main/res/layout/account_row.xml +++ b/src/main/res/layout/account_row.xml @@ -32,7 +32,7 @@ android:layout_height="wrap_content" android:scrollHorizontally="false" android:singleLine="true" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeHeadline" /> diff --git a/src/main/res/layout/actionview_search.xml b/src/main/res/layout/actionview_search.xml index cc5fc9d7..8b657f4a 100644 --- a/src/main/res/layout/actionview_search.xml +++ b/src/main/res/layout/actionview_search.xml @@ -14,6 +14,8 @@ android:layout_height="wrap_content" android:focusable="true" android:inputType="textEmailAddress|textNoSuggestions" - android:textColor="@color/ondarktext" /> + android:textColor="@color/white" + android:textColorHint="@color/white70" + android:hint="@string/search_for_contacts_or_groups"/> \ No newline at end of file diff --git a/src/main/res/layout/activity_about.xml b/src/main/res/layout/activity_about.xml index ab0e34eb..d7d23f0f 100644 --- a/src/main/res/layout/activity_about.xml +++ b/src/main/res/layout/activity_about.xml @@ -1,7 +1,7 @@ @@ -15,7 +15,7 @@ android:layout_marginRight="@dimen/activity_horizontal_margin" android:layout_marginTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" - android:textColor="@color/primarytext" + android:textColor="@color/black87" android:textSize="?attr/TextSizeBody" android:typeface="monospace"/> diff --git a/src/main/res/layout/activity_change_password.xml b/src/main/res/layout/activity_change_password.xml index 28d531c2..1a4d00d8 100644 --- a/src/main/res/layout/activity_change_password.xml +++ b/src/main/res/layout/activity_change_password.xml @@ -2,7 +2,7 @@ + android:background="@color/grey50"> @@ -94,7 +94,7 @@ android:layout_height="fill_parent" android:layout_marginBottom="7dp" android:layout_marginTop="7dp" - android:background="@color/divider"/> + android:background="@color/black12"/>