aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--art/conversations_baloon.svg691
-rw-r--r--build.gradle4
-rw-r--r--src/main/AndroidManifest.xml1
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java3
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java136
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java27
-rw-r--r--src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java30
-rw-r--r--src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java9
-rw-r--r--src/main/java/eu/siacs/conversations/ui/XmppActivity.java25
-rw-r--r--src/main/java/eu/siacs/conversations/utils/DNSHelper.java121
-rw-r--r--src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java57
-rw-r--r--src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java62
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java178
-rw-r--r--src/main/res/drawable-hdpi/ic_launcher.pngbin4486 -> 4581 bytes
-rw-r--r--src/main/res/drawable-hdpi/message_bubble_received.9.pngbin765 -> 765 bytes
-rw-r--r--src/main/res/drawable-hdpi/message_bubble_received_warning.9.pngbin757 -> 757 bytes
-rw-r--r--src/main/res/drawable-hdpi/message_bubble_received_white.9.pngbin779 -> 779 bytes
-rw-r--r--src/main/res/drawable-hdpi/message_bubble_sent.9.pngbin687 -> 687 bytes
-rw-r--r--src/main/res/drawable-mdpi/ic_launcher.pngbin2762 -> 2841 bytes
-rw-r--r--src/main/res/drawable-mdpi/message_bubble_received.9.pngbin594 -> 594 bytes
-rw-r--r--src/main/res/drawable-mdpi/message_bubble_received_warning.9.pngbin598 -> 598 bytes
-rw-r--r--src/main/res/drawable-mdpi/message_bubble_received_white.9.pngbin610 -> 610 bytes
-rw-r--r--src/main/res/drawable-mdpi/message_bubble_sent.9.pngbin558 -> 558 bytes
-rw-r--r--src/main/res/drawable-xhdpi/ic_launcher.pngbin6377 -> 6549 bytes
-rw-r--r--src/main/res/drawable-xhdpi/message_bubble_received.9.pngbin929 -> 929 bytes
-rw-r--r--src/main/res/drawable-xhdpi/message_bubble_received_warning.9.pngbin921 -> 921 bytes
-rw-r--r--src/main/res/drawable-xhdpi/message_bubble_received_white.9.pngbin935 -> 935 bytes
-rw-r--r--src/main/res/drawable-xhdpi/message_bubble_sent.9.pngbin857 -> 857 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/ic_launcher.pngbin10254 -> 10495 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/message_bubble_received.9.pngbin1334 -> 1334 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.pngbin1308 -> 1308 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/message_bubble_received_white.9.pngbin1344 -> 1344 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/message_bubble_sent.9.pngbin1190 -> 1190 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/ic_launcher.pngbin14117 -> 14630 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/message_bubble_received.9.pngbin1714 -> 1714 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.pngbin1674 -> 1674 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.pngbin1705 -> 1705 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/message_bubble_sent.9.pngbin1499 -> 1499 bytes
-rw-r--r--src/main/res/layout/activity_edit_account.xml75
-rw-r--r--src/main/res/layout/conversation_list_row.xml4
-rw-r--r--src/main/res/values-de/strings.xml38
-rw-r--r--src/main/res/values/strings.xml19
43 files changed, 901 insertions, 587 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83505761f..1a746552f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
###Changelog
-####Versin 1.8.4
+####Version 1.9.0
+* Per conference notification settings
+* Let user decide whether to compress pictures
+* Support for XEP-0368
+* Ask user to exclude Conversations from battery optimizations
+
+####Version 1.8.4
* prompt to trust own OMEMO devices
* fixed rotation issues in avatar publication
* invite non-contact JIDs to conferences
diff --git a/art/conversations_baloon.svg b/art/conversations_baloon.svg
index 140a84c7c..96b17d2b4 100644
--- a/art/conversations_baloon.svg
+++ b/art/conversations_baloon.svg
@@ -2,6 +2,7 @@
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
@@ -10,298 +11,256 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="512"
- height="512"
- id="svg2"
+ width="57mm"
+ height="57mm"
+ viewBox="0 0 201.96849 201.96849"
+ id="svg4211"
version="1.1"
- inkscape:version="0.48.5 r10040"
- sodipodi:docname="conversations_baloon.svg"
- inkscape:export-filename="/home/diesys/diesys/grafica/conversation/conversation_bubble.png"
- inkscape:export-xdpi="100"
- inkscape:export-ydpi="100">
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="conversations_baloon.svg">
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ showgrid="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ showguides="false"
+ inkscape:zoom="2.2196812"
+ inkscape:cx="39.109276"
+ inkscape:cy="132.27753"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer8" />
<defs
- id="defs4">
+ id="defs4213">
<linearGradient
- inkscape:collect="always"
- id="linearGradient3874">
+ osb:paint="solid"
+ id="linearGradient5393">
<stop
- style="stop-color:#00a000;stop-opacity:1;"
+ id="stop5395"
offset="0"
- id="stop3876" />
- <stop
- style="stop-color:#00a000;stop-opacity:0;"
- offset="1"
- id="stop3878" />
+ style="stop-color:#ffffff;stop-opacity:1;" />
</linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3913">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop3915" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop3917" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3818">
- <stop
- style="stop-color:#669900;stop-opacity:1"
- offset="0"
- id="stop3820" />
- <stop
- style="stop-color:#99cc00;stop-opacity:1"
- offset="1"
- id="stop3822" />
- </linearGradient>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3818"
- id="radialGradient3824"
- cx="212.07048"
- cy="1045.9178"
- fx="212.07048"
- fy="1045.9178"
- r="238.57143"
- gradientTransform="matrix(1.9491621,-0.90817722,0.65829208,1.4128498,-879.63121,-248.98648)"
- gradientUnits="userSpaceOnUse" />
+ <clipPath
+ id="clipPath4831"
+ clipPathUnits="userSpaceOnUse">
+ <circle
+ style="display:inline;opacity:1;fill:#a00e00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="circle4833"
+ cx="883.16943"
+ cy="677.19611"
+ r="229.80969" />
+ </clipPath>
+ <clipPath
+ id="clipPath4859"
+ clipPathUnits="userSpaceOnUse">
+ <circle
+ style="display:inline;opacity:1;fill:#a00e00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="circle4861"
+ cx="883.16943"
+ cy="677.19611"
+ r="229.80969" />
+ </clipPath>
+ <clipPath
+ id="clipPath5624"
+ clipPathUnits="userSpaceOnUse">
+ <g
+ style="display:inline"
+ id="g5626"
+ transform="matrix(0.3835576,0,0,0.3835576,-250.60108,-156.11014)">
+ <path
+ sodipodi:nodetypes="ccsssc"
+ inkscape:connector-curvature="0"
+ id="path5628"
+ d="m 1120.8042,772.36056 -118.0025,103.66316 118.5792,46.01918 c 8.4859,3.29325 19.6524,7.94481 27.2622,0.71376 7.3868,-7.01907 5.6502,-14.13839 3.0935,-24.54095 z"
+ style="display:inline;fill:#4caf50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <circle
+ transform="matrix(1.0878566,0,0,1.0878566,-57.401992,-79.686482)"
+ clip-path="url(#clipPath4859)"
+ r="229.80969"
+ cy="677.19611"
+ cx="883.16943"
+ id="circle5630"
+ style="display:inline;opacity:1;fill:#4caf50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath10653">
+ <g
+ style="display:inline"
+ id="g10655"
+ transform="matrix(0.3835576,0,0,0.3835576,-250.60108,-156.11015)"
+ inkscape:export-xdpi="100"
+ inkscape:export-ydpi="100">
+ <path
+ sodipodi:nodetypes="ccsssc"
+ inkscape:connector-curvature="0"
+ id="path10657"
+ d="m 1120.8042,772.36056 -118.0025,103.66316 118.5792,46.01918 c 8.4859,3.29325 19.6524,7.94481 27.2622,0.71376 7.3868,-7.01907 5.6502,-14.13839 3.0935,-24.54095 z"
+ style="display:inline;fill:#4caf50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <circle
+ transform="matrix(1.0878566,0,0,1.0878566,-57.401992,-79.686482)"
+ clip-path="url(#clipPath4859)"
+ r="229.80969"
+ cy="677.19611"
+ cx="883.16943"
+ id="circle10659"
+ style="display:inline;opacity:1;fill:#4caf50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ </clipPath>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3913"
- id="radialGradient3919"
- cx="362.98563"
- cy="379.77524"
- fx="362.98563"
- fy="379.77524"
- r="139.95312"
- gradientTransform="matrix(1.3800477,1.0445431,-1.3325077,1.7605059,339.09383,-577.83938)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
+ id="radialGradient3883"
gradientUnits="userSpaceOnUse"
- y2="-155.75885"
- x2="114.59022"
- y1="35.545681"
- x1="114.55434"
- id="linearGradient3794"
- xlink:href="#linearGradient3788"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient3788">
- <stop
- id="stop3790"
- offset="0"
- style="stop-color:#1eed00;stop-opacity:1;" />
- <stop
- id="stop3792"
- offset="1"
- style="stop-color:#abff28;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3821">
- <stop
- style="stop-color:#ff283d;stop-opacity:1;"
- offset="0"
- id="stop3823" />
- <stop
- style="stop-color:#ff28ae;stop-opacity:1;"
- offset="1"
- id="stop3825" />
- </linearGradient>
- <linearGradient
- id="linearGradient4543">
- <stop
- style="stop-color:#2e45bf;stop-opacity:1;"
- offset="0"
- id="stop4545" />
- <stop
- style="stop-color:#28a7ff;stop-opacity:1;"
- offset="1"
- id="stop4547" />
- </linearGradient>
+ gradientTransform="matrix(0.68662089,-0.30388739,0.24146012,0.54605188,-300.74233,-264.46964)"
+ cx="262.33273"
+ cy="945.23846"
+ fx="262.33273"
+ fy="945.23846"
+ r="185.49754" />
<linearGradient
inkscape:collect="always"
- id="linearGradient4098">
+ id="linearGradient3913">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
- id="stop4100" />
+ id="stop3915" />
<stop
- style="stop-color:#e6e6e6;stop-opacity:1"
+ style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
- id="stop4102" />
+ id="stop3917" />
</linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4098"
- id="linearGradient3833"
- x1="273.81851"
- y1="764.74677"
- x2="304.14023"
- y2="936.47272"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4098"
- id="linearGradient3853"
- gradientUnits="userSpaceOnUse"
- x1="273.81851"
- y1="764.74677"
- x2="304.14023"
- y2="936.47272" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3818"
- id="radialGradient3863"
- cx="262.33273"
- cy="945.23846"
- fx="262.33273"
- fy="945.23846"
- r="185.49754"
- gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,170.11831)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3818"
- id="radialGradient3866"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,170.11831)"
- cx="262.33273"
- cy="945.23846"
- fx="262.33273"
- fy="945.23846"
- r="185.49754" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3913"
- id="radialGradient3873"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.3800477,1.0445431,-1.3325077,1.7605059,339.09383,-577.83938)"
- cx="321.75275"
- cy="386.38751"
- fx="321.75275"
- fy="386.38751"
- r="139.95312" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3818"
- id="radialGradient3880"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.2253203,-0.54206726,0.43090148,0.97403458,-466.4135,-370.24387)"
- cx="262.33273"
- cy="945.23846"
- fx="262.33273"
- fy="945.23846"
- r="185.49754" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3913"
- id="radialGradient3883"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.4430075,-0.63865195,0.50745433,1.1475866,-594.40824,44.803037)"
- cx="262.33273"
- cy="945.23846"
- fx="262.33273"
- fy="945.23846"
- r="185.49754" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath5315">
+ <g
+ inkscape:export-ydpi="100"
+ inkscape:export-xdpi="100"
+ transform="matrix(0.3835576,0,0,0.3835576,-246.60108,-156.11013)"
+ id="g5317"
+ style="display:inline;fill:#00a000;fill-opacity:1">
+ <path
+ style="display:inline;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 1120.8042,772.36056 -118.0025,103.66316 118.5792,46.01918 c 8.4859,3.29325 19.6524,7.94481 27.2622,0.71376 7.3868,-7.01907 5.6502,-14.13839 3.0935,-24.54095 z"
+ id="path5319"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsssc" />
+ <circle
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="circle5321"
+ cx="883.16943"
+ cy="677.19611"
+ r="229.80969"
+ clip-path="url(#clipPath4859)"
+ transform="matrix(1.0878566,0,0,1.0878566,-57.401992,-79.686482)" />
+ </g>
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6882">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6884"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6886">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6888"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6890">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6892"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6894">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6896"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6898">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6900"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6902">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6904"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6906">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6908"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6910">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6912"
+ d="M 99.88867,-2.3837657e-4 A 95.889392,95.889392 0 0 0 4,95.888436 95.889392,95.889392 0 0 0 99.88867,191.77906 95.889392,95.889392 0 0 0 142.59375,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.7793,95.888466 95.889392,95.889392 0 0 0 99.88867,-2.0837657e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
<filter
inkscape:collect="always"
- id="filter3895">
+ style="color-interpolation-filters:sRGB"
+ id="filter5640"
+ x="-0.012227737"
+ width="1.0244555"
+ y="-0.011780591"
+ height="1.0235612">
<feGaussianBlur
inkscape:collect="always"
- stdDeviation="2.0013623"
- id="feGaussianBlur3897" />
+ stdDeviation="0.9782166"
+ id="feGaussianBlur5642" />
</filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3874"
- id="radialGradient3881"
- cx="150.35715"
- cy="236.28571"
- fx="150.35715"
- fy="236.28571"
- r="26.887305"
- gradientTransform="matrix(1,0,0,0.98671703,0,3.1385771)"
- gradientUnits="userSpaceOnUse" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath5745">
+ <path
+ inkscape:connector-curvature="0"
+ id="path5747"
+ d="M 99.908581,-2.3831968e-4 A 95.889392,95.889392 0 0 0 4.0199102,95.888436 95.889392,95.889392 0 0 0 99.908581,191.77906 95.889392,95.889392 0 0 0 142.61366,181.70093 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 L 183.8285,142.24002 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 195.79921,95.888466 95.889392,95.889392 0 0 0 99.908581,-2.0831968e-4 Z"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
</defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.4142136"
- inkscape:cx="385.13513"
- inkscape:cy="237.84331"
- inkscape:document-units="px"
- inkscape:current-layer="layer4"
- showgrid="false"
- inkscape:window-width="2560"
- inkscape:window-height="1020"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:snap-to-guides="true"
- inkscape:snap-grids="false"
- inkscape:object-paths="true"
- inkscape:object-nodes="false"
- inkscape:snap-nodes="false">
- <sodipodi:guide
- orientation="1,0"
- position="0,534.28571"
- id="guide3004" />
- <sodipodi:guide
- orientation="0,1"
- position="394.28571,511.42857"
- id="guide3006" />
- <sodipodi:guide
- orientation="1,0"
- position="511.42857,320"
- id="guide3008" />
- <sodipodi:guide
- orientation="0,1"
- position="401.42857,0"
- id="guide3010" />
- <sodipodi:guide
- orientation="1,0"
- position="17.142857,258.57143"
- id="guide3012" />
- <sodipodi:guide
- orientation="0,1"
- position="327.14286,494.28571"
- id="guide3014" />
- <sodipodi:guide
- orientation="0,1"
- position="324.28571,17.142857"
- id="guide3016" />
- <sodipodi:guide
- orientation="1,0"
- position="494.28571,237.14286"
- id="guide3018" />
- <sodipodi:guide
- orientation="1,0"
- position="255.71429,302.85714"
- id="guide3022" />
- <sodipodi:guide
- orientation="1,0"
- position="660,-315"
- id="guide3904" />
- <sodipodi:guide
- orientation="0,1"
- position="554.28571,475.71429"
- id="guide3931" />
- <sodipodi:guide
- orientation="0,1"
- position="581.42857,244.28571"
- id="guide3933" />
- </sodipodi:namedview>
<metadata
- id="metadata7">
+ id="metadata4216">
<rdf:RDF>
<cc:Work
rdf:about="">
@@ -313,78 +272,156 @@
</rdf:RDF>
</metadata>
<g
- inkscape:label="Layer 1"
inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-540.36218)"
+ id="layer9"
+ inkscape:label="shaddow"
+ transform="translate(-4,2.6816164)"
style="display:inline">
<path
- d="m 253.34375,605.78125 c -107.90463,0 -195.9375,85.86121 -195.9375,191.84375 0,105.98253 88.02779,191.90625 195.9375,191.90625 33.55862,0 59.4324,-6.89467 88.96875,-17.625 l 93.8125,37.81255 A 12.359798,12.359798 0 0 0 452.75,995.28125 L 427.34375,892.59375 C 443.67389,863.93074 449.25,831.2919 449.25,797.625 449.25,691.64506 361.24842,605.78125 253.34375,605.78125 z"
- id="path3885"
- style="opacity:0.6;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter3895)"
- inkscape:original="M 253.34375 618.125 C 151.96941 618.125 69.75 698.4746 69.75 797.625 C 69.75 896.77539 151.96941 977.1875 253.34375 977.1875 C 287.00054 977.1875 311.5728 970.27778 342.65625 958.71875 L 440.75 998.25 L 414.1875 890.8125 C 431.0772 863.65332 436.90625 831.73711 436.90625 797.625 C 436.90625 698.4746 354.71813 618.125 253.34375 618.125 z "
- inkscape:radius="12.358562"
- sodipodi:type="inkscape:offset"
- transform="matrix(1.1776575,0,0,1.1781783,-45.132882,-150.91395)" />
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="12.358562"
- inkscape:original="M 253.34375 618.125 C 151.96941 618.125 69.75 698.4746 69.75 797.625 C 69.75 896.77539 151.96941 977.1875 253.34375 977.1875 C 287.00054 977.1875 311.5728 970.27778 342.65625 958.71875 L 440.75 998.25 L 414.1875 890.8125 C 431.0772 863.65332 436.90625 831.73711 436.90625 797.625 C 436.90625 698.4746 354.71813 618.125 253.34375 618.125 z "
- style="fill:#00a000;fill-opacity:1;stroke:none"
- id="path3868"
- d="m 253.34375,605.78125 c -107.90463,0 -195.9375,85.86121 -195.9375,191.84375 0,105.98253 88.02779,191.90625 195.9375,191.90625 33.55862,0 59.4324,-6.89467 88.96875,-17.625 l 93.8125,37.81255 A 12.359798,12.359798 0 0 0 452.75,995.28125 L 427.34375,892.59375 C 443.67389,863.93074 449.25,831.2919 449.25,797.625 449.25,691.64506 361.24842,605.78125 253.34375,605.78125 z"
- transform="matrix(1.1776575,0,0,1.1781783,-45.132882,-155.6267)" />
+ inkscape:connector-curvature="0"
+ id="path6914"
+ d="M 104.88867,0.06226191 A 95.889392,95.889392 0 0 0 8.9999996,95.950936 95.889392,95.889392 0 0 0 104.88867,191.84156 95.889392,95.889392 0 0 0 147.59375,181.76343 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 l -11.34766,-46.16797 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 200.7793,95.950966 95.889392,95.889392 0 0 0 104.88867,0.06229191 Z"
+ style="display:inline;opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter5640)" />
+ </g>
+ <g
+ style="display:inline"
+ inkscape:label="bubble"
+ id="layer4"
+ inkscape:groupmode="layer"
+ transform="translate(-4,2.6816348)">
<path
- style="opacity:0.19211821;fill:url(#radialGradient3883);fill-opacity:1;stroke:none"
- d="m 442.08605,700.89397 c -129.66422,0 -234.75863,103.19621 -234.75863,230.48113 0,26.84957 4.6841,52.62718 13.28548,76.5811 10.65333,1.4828 21.54531,2.2461 32.60637,2.2461 39.52053,0 69.99101,-8.1231 104.7747,-20.7651 l 110.479,44.5494 a 14.555607,14.562048 0 0 0 19.57853,-17.0097 L 458.13167,895.99293 c 19.23127,-33.77016 25.79804,-72.22452 25.79804,-111.89014 0,-28.84573 -5.53074,-56.41202 -15.60395,-81.77294 -8.61503,-0.94041 -17.37147,-1.43588 -26.23971,-1.43588 z"
- id="path3878"
+ style="display:inline;opacity:1;fill:#00a000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 104.88867,-1.9377566 A 95.889392,95.889392 0 0 0 8.9999996,93.950918 95.889392,95.889392 0 0 0 104.88867,189.84154 95.889392,95.889392 0 0 0 147.59375,179.76341 l 0.12695,0.0137 40.79297,15.83204 c 3.25479,1.26313 7.53628,3.04697 10.45508,0.27343 2.83326,-2.69222 2.16811,-5.42213 1.1875,-9.41211 L 188.80859,140.3025 a 95.889392,95.889392 0 0 1 -0.002,0.002 l 0,-0.008 0.002,0.006 A 95.889392,95.889392 0 0 0 200.7793,93.950948 95.889392,95.889392 0 0 0 104.88867,-1.9377266 Z"
+ id="circle6661"
inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:125px;line-height:1000%;font-family:Sans;letter-spacing:-10.89000034px;word-spacing:5px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="85.862968"
+ y="-55.271603"
+ id="text6634"
+ sodipodi:linespacing="1000%"><tspan
+ sodipodi:role="line"
+ id="tspan6636"
+ x="85.862968"
+ y="-55.271603" /></text>
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer8"
+ inkscape:label="dotted line"
+ style="display:inline"
+ transform="translate(-4,2.6816164)">
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6910)"
+ d="m 145.16406,11.183594 -5.13232,9.649402 c -0.77924,1.465076 -0.65974,2.41396 0.66876,3.18097 9.66686,5.488467 18.12303,12.874168 24.86104,21.711122 1.05534,1.616079 2.08054,1.713076 3.67763,0.571565 L 178.04883,40 C 169.45271,27.990203 158.19857,18.128379 145.16406,11.183594 Z"
+ id="path7364"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csccscc"
+ transform="translate(4.9999996,-1.9374999)" />
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6906)"
+ d="m 193.80469,75.615234 -9.62713,2.062751 c -2.66266,0.570512 -3.40763,1.172953 -2.90593,3.917433 0.85823,4.714633 1.30424,9.497137 1.33189,14.293254 -0.028,5.578758 -0.62194,11.137108 -1.77093,16.589918 -0.86591,3.23162 0.13682,3.77092 3.16149,4.58138 l 8.98639,2.30136 c 1.98177,-7.66828 3.00584,-15.55255 3.04883,-23.472658 -0.0187,-6.817681 -0.76446,-13.613926 -2.22461,-20.273438 z"
+ id="path7366"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csccccccc"
+ transform="translate(4.9999996,-1.9374999)" />
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6902)"
+ d="m 14.264281,102.76512 -10.2076406,0.87943 c 1.2093798,14.83154 5.8540346,29.17808 13.5664056,41.90429 l 8.544301,-5.23239 c 2.394983,-1.46665 1.895406,-3.37834 0.986202,-5.04513 -5.118253,-9.40257 -8.359018,-19.71635 -9.536202,-30.36553 0,-2.09418 -1.881577,-2.26744 -3.353066,-2.14067 z"
+ id="path7372"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sccsccs"
+ transform="translate(4.9999996,-1.9374999)" />
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6898)"
+ d="m 51.504371,166.60235 -5.82273,8.50898 c 12.710503,8.71282 27.333669,14.23394 42.630859,16.0957 l 1.220329,-9.90843 c 0.355066,-2.88295 -1.085712,-3.52946 -3.332252,-3.90256 -10.402329,-1.73697 -20.373956,-5.45322 -29.373754,-10.94516 -1.647505,-1.06744 -3.639993,-2.30718 -5.322452,0.15147 z"
+ id="path7370"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sccsccs"
+ transform="translate(4.9999996,-1.9374999)" />
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6894)"
+ d="M 32.208984,27.683594 C 21.779177,38.079001 13.883707,50.736882 9.1347656,64.675781 L 19.33617,68.090365 c 1.658147,0.55501 2.832564,-0.120955 3.374272,-1.591979 3.777598,-10.021698 9.470788,-19.210103 16.759132,-27.052307 1.561136,-1.561136 1.567283,-2.960058 0.447507,-4.076606 z"
+ id="path7374"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccsc"
+ transform="translate(4.9999996,-1.9374999)" />
+ <path
+ style="opacity:1;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6890)"
+ d="M 99.888672,-0.25 C 87.701045,-0.2239408 75.630114,2.1252837 64.322266,6.671875 l 3.530435,8.74898 c 1.063314,2.635062 1.616754,3.526314 4.973913,2.352259 8.692057,-3.031338 17.839027,-4.588849 27.062058,-4.599286 5.555828,0 6.486278,0.350026 6.780788,-3.4460223 l 0.74851,-9.64772758 C 104.9135,-0.12857239 102.40179,-0.23868346 99.888672,-0.25 Z"
+ id="path7376"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccscc"
+ transform="translate(4.9999996,-1.9374999)" />
<path
- sodipodi:nodetypes="ccsssscc"
+ style="display:inline;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6886)"
+ d="m 138.72416,168.48439 c -4.17634,2.25458 -8.55959,4.09055 -13.0504,5.63418 -1.00363,0.34498 -1.20742,1.18222 -0.8682,2.27372 l 3.44056,11.0706 c 4.92985,-1.53124 9.72799,-3.45808 14.34766,-5.76172 l 0.12695,0.0137 14.0293,5.44532 4.12174,-10.20577 c 0.7548,-1.86894 -0.0184,-2.7016 -1.59462,-3.31324 l -14.72114,-5.71251 c -1.86679,-0.7244 -3.68834,-0.60144 -5.83185,0.55572 z"
+ id="path5005"
inkscape:connector-curvature="0"
- id="path3845"
- d="M 478.64112,1025.218 447.36049,898.60749 c 19.89028,-31.99834 26.74288,-69.57172 26.74288,-109.76189 0,-116.81686 -96.79943,-211.48385 -216.18374,-211.48385 -119.38425,0 -216.183656,94.66699 -216.183656,211.48385 0,116.81685 96.799406,211.5536 216.183656,211.5536 39.63617,0 68.58847,-8.14219 105.19417,-21.76075 z"
- style="opacity:0;fill:none;stroke:#000000;stroke-width:23.55835724;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:94.23343197, 94.23343197;stroke-dashoffset:0" />
+ sodipodi:nodetypes="cssccccsssc"
+ transform="translate(4.9999996,-1.9374999)" />
<path
+ style="display:inline;fill:#80d080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ clip-path="url(#clipPath6882)"
+ d="m 186.53125,152.80469 -10.6386,2.70888 c -0.78879,0.20085 -1.67397,1.02386 -1.35494,2.33801 l 9.75918,40.15428 c 8.56713,5.97538 15.30408,3.06731 11.01563,-9.47266 z"
+ id="path5071"
inkscape:connector-curvature="0"
- id="path3855"
- d="m 253.18246,561.05889 c -5.38379,-0.002 -10.7413,0.0871 -12.77023,0.22089 -16.80965,1.10727 -29.68729,3.05317 -44.38296,6.77453 -5.64799,1.43026 -9.96811,2.69833 -15.19914,4.41816 -3.34052,1.09828 -8.41764,2.85364 -8.68521,3.01909 -0.082,0.0507 3.32705,9.32907 7.98597,21.79631 0.0466,0.12496 0.17057,0.13832 0.33123,0.0736 1.11322,-0.44815 6.45699,-2.29745 8.94283,-3.09273 21.39718,-6.84518 43.95735,-10.19531 66.31683,-9.86723 3.14874,0.0461 7.13319,0.15915 8.83245,0.25775 1.69921,0.0987 3.12161,0.15378 3.16493,0.11037 0.0685,-0.0684 1.53237,-23.21444 1.47209,-23.26905 -0.0122,-0.0117 -1.41064,-0.10943 -3.12817,-0.22089 -2.0869,-0.13546 -7.49683,-0.21852 -12.88062,-0.22088 z m 110.81021,28.16581 c -0.10125,0.10911 -11.15095,20.28455 -11.15095,20.36043 0,0.0184 0.50701,0.31641 1.14084,0.66267 8.38104,4.57856 17.56037,10.63803 25.90897,17.04889 3.23527,2.48434 6.34578,5.02146 9.23674,7.54561 4.2123,3.67784 8.41256,7.68117 12.42754,11.81905 6.38417,6.5796 12.29989,13.4994 17.05071,19.99177 0.65274,0.89212 0.79099,1.01157 1.03047,0.84681 1.13402,-0.7802 18.39736,-13.76959 18.40089,-13.84358 0.005,-0.1 -3.33561,-4.52525 -4.74744,-6.29593 -5.64395,-7.07831 -10.59769,-12.59166 -17.26005,-19.25582 -8.26499,-8.26722 -16.14264,-15.121 -25.02569,-21.71453 -2.5667,-1.90515 -5.21733,-3.78858 -7.9855,-5.6781 -6.60132,-4.50598 -18.71149,-11.82683 -19.02653,-11.48727 z m -274.762206,39.94759 -2.428914,2.57732 c -21.579098,22.69359 -38.068397,49.23025 -48.467963,78.05431 -0.50904,1.41091 -0.957247,2.67589 -0.993643,2.83498 -0.04781,0.20904 2.956962,1.31003 10.78292,3.93954 5.956638,2.00143 10.92488,3.63791 11.040538,3.64502 0.115645,0.007 0.916879,-1.94564 1.803285,-4.34458 9.098432,-24.62317 23.187184,-47.25662 41.659643,-66.93523 l 3.05453,-3.27681 -8.206806,-8.24726 z m 388.222146,115.167 -9.89972,1.91451 c -5.44839,1.06994 -10.56998,2.07187 -11.40857,2.20908 -1.04711,0.17137 -1.54564,0.35016 -1.54564,0.55228 0,0.16187 0.23325,1.63204 0.51522,3.2768 2.70275,15.76547 3.28356,34.63258 1.69287,55.26394 -0.7281,9.44363 -2.34823,21.04449 -3.90099,28.01857 -0.23345,1.0486 -0.37949,1.97667 -0.33118,2.02499 0.0483,0.0483 5.12585,1.1561 11.29809,2.46683 6.17232,1.31067 11.30751,2.37915 11.3718,2.39315 0.0641,0.014 0.45734,-1.73307 0.88322,-3.90272 3.35867,-17.11028 4.82653,-33.18977 4.85786,-53.27572 0.0219,-14.08945 -0.79161,-24.35571 -2.87056,-36.96537 z m -427.268845,64.06345 -0.772838,0.11039 c -0.421858,0.0612 -5.59823,0.67716 -11.482161,1.36226 -5.883927,0.68512 -10.759171,1.30169 -10.819725,1.36228 -0.141991,0.142 0.252313,2.91986 1.140854,8.32086 4.869392,29.59836 15.038358,56.25732 31.539139,82.61977 0.450701,0.72005 0.931445,1.27763 1.06725,1.25182 0.361709,-0.0685 19.423106,-12.2036 19.431349,-12.3709 0.0036,-0.0779 -0.796734,-1.40341 -1.766487,-2.94542 -4.266677,-6.78447 -9.935035,-17.45299 -13.064635,-24.5945 -7.52905,-17.18062 -12.488823,-34.71382 -15.051936,-53.27567 z M 462.40066,926.44149 c -0.46898,0.009 -22.08567,5.38002 -22.2283,5.52269 -0.098,0.0981 22.04129,90.06142 22.37549,91.01382 0.40286,1.1482 3.73284,10.5298 13.56323,8.9156 10.95786,-2.3434 9.8458,-14.6677 8.99628,-14.4751 -0.11284,0.025 -5.02627,-20.61508 -11.18774,-45.58033 -8.79763,-35.64656 -11.26829,-45.40142 -11.51896,-45.39668 z M 143.91794,953.1714 c -0.40943,0.0131 -1.21588,1.3276 -6.29312,9.64634 -3.31435,5.43031 -6.03549,9.92123 -6.03549,9.9777 0,0.13674 3.42858,2.19027 7.06593,4.27089 22.35182,12.78549 47.08561,21.82095 72.42596,26.43487 3.59043,0.654 5.67261,1.0064 11.04051,1.804 0.69401,0.1031 1.36954,0.2073 1.50889,0.2212 0.31484,0.031 0.24386,0.6279 1.87691,-11.45018 0.75094,-5.5542 1.40492,-10.43428 1.47207,-10.86126 0.11781,-0.74877 0.0863,-0.77677 -0.58887,-0.88362 -0.38487,-0.0607 -2.68651,-0.4127 -5.11543,-0.77322 -22.30454,-3.3101 -45.25895,-10.90321 -65.32317,-21.57538 -3.55401,-1.89038 -10.16752,-5.64292 -11.85018,-6.73769 -0.0531,-0.0345 -0.12551,-0.0755 -0.18401,-0.0737 z m 214.22322,9.09404 c -1.98095,0.13013 -4.60205,1.01767 -10.4517,3.12954 -11.29964,4.0795 -24.13159,8.26507 -29.91986,9.75681 -0.83741,0.21582 -1.5445,0.50692 -1.54566,0.62592 -0.002,0.21503 5.72469,22.22722 5.81468,22.34847 0.0552,0.075 6.34708,-1.70267 10.2677,-2.90858 5.09669,-1.5677 13.67295,-4.44246 19.79936,-6.62722 l 6.07232,-2.17225 22.30187,8.98356 c 18.14341,7.31671 22.30098,8.95081 22.41231,8.68881 0.9061,-2.1322 8.61707,-21.32757 8.57483,-21.35419 -0.38803,-0.24492 -49.13929,-19.77601 -49.90327,-19.99221 -1.25781,-0.35596 -2.23399,-0.55669 -3.42258,-0.47866 z"
- style="opacity:0.5;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:5.88958931;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- sodipodi:nodetypes="ccssccssscccccccssssscccsssscccscsssccccccssssssssssccccscssccsscccsscsscsssssccsccsscsscsccscccccssc" />
+ sodipodi:nodetypes="cssccc"
+ transform="translate(4.9999996,-1.9374999)" />
</g>
<g
+ style="display:inline"
+ inkscape:label="dots"
+ id="layer2"
inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Dots">
- <path
- sodipodi:type="arc"
- style="opacity:0.928;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path3047"
- sodipodi:cx="173.57143"
- sodipodi:cy="241.28571"
- sodipodi:rx="26.428572"
- sodipodi:ry="20"
- d="m 200,241.28571 a 26.428572,20 0 1 1 -52.85715,0 26.428572,20 0 1 1 52.85715,0 z"
- transform="matrix(0.94594594,0,0,1.25,-18.332045,-54.607132)" />
- <path
- sodipodi:type="arc"
- style="opacity:0.928;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path3047-1"
- sodipodi:cx="173.57143"
- sodipodi:cy="241.28571"
- sodipodi:rx="26.428572"
- sodipodi:ry="20"
- d="m 200,241.28571 a 26.428572,20 0 1 1 -52.85715,0 26.428572,20 0 1 1 52.85715,0 z"
- transform="matrix(0.94594594,0,0,1.25,91.38502,-54.607132)" />
+ transform="translate(-4,2.6816348)">
+ <g
+ inkscape:export-ydpi="100"
+ inkscape:export-xdpi="100"
+ style="fill:#f5f5f5;fill-opacity:1"
+ transform="matrix(0.3835576,0,0,0.3835576,-248.17635,-138.86977)"
+ id="g5126">
+ <circle
+ r="27.299093"
+ style="opacity:1;fill:#f5f5f5;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ id="path3047-4"
+ cx="799.11273"
+ cy="609.86285" />
+ <circle
+ r="27.299093"
+ style="opacity:1;fill:#f5f5f5;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ id="path3047-1-2"
+ cx="918.91962"
+ cy="609.86285" />
+ <circle
+ r="27.299093"
+ style="opacity:1;fill:#f5f5f5;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ id="path3047-1-8-6"
+ cx="1039.0352"
+ cy="609.86285" />
+ </g>
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer1"
+ inkscape:label="light"
+ style="display:inline"
+ transform="translate(-4,2.6816164)">
<path
- sodipodi:type="arc"
- style="opacity:0.928;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path3047-1-8"
- sodipodi:cx="173.57143"
- sodipodi:cy="241.28571"
- sodipodi:rx="26.428572"
- sodipodi:ry="20"
- d="m 200,241.28571 a 26.428572,20 0 1 1 -52.85715,0 26.428572,20 0 1 1 52.85715,0 z"
- transform="matrix(0.94594594,0,0,1.25,201.38502,-54.607132)" />
+ style="display:inline;opacity:0.19211821;fill:url(#radialGradient3883);fill-opacity:1;stroke:none"
+ d="m 192.44891,47.715674 c -61.69765,0 -111.704333,49.103472 -111.704333,109.668976 0,12.77573 2.228815,25.0414 6.321575,36.4393 5.069139,0.70557 10.251828,1.06876 15.514978,1.06876 18.80489,0 30.91434,7.28449 47.46533,1.26909 l 54.00234,6.06606 c 5.24363,2.11897 11.63381,1.37954 10.27166,-4.11162 l -14.23663,-57.56735 c 9.15073,-16.06873 12.27539,-34.36633 12.27539,-53.240271 0,-13.72556 -2.63167,-26.842322 -7.42478,-38.909717 -4.09925,-0.447474 -8.2658,-0.683228 -12.48553,-0.683228 z"
+ id="path3878"
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath5745)"
+ transform="translate(4.9800894,-1.9374999)"
+ sodipodi:nodetypes="sscsccccscs" />
</g>
</svg>
diff --git a/build.gradle b/build.gradle
index 4c841f048..5448660a1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -57,8 +57,8 @@ android {
minSdkVersion 14
targetSdkVersion 23
- versionCode 116
- versionName "1.9.0-beta"
+ versionCode 118
+ versionName "1.9.0-beta.3"
project.ext.set(archivesBaseName, archivesBaseName + "-" + versionName);
}
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 7efd0a92a..521deac59 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.NFC"/>
+ <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
index 3077c4889..c73a05647 100644
--- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -577,6 +577,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
public void writeRoster(final Roster roster) {
final Account account = roster.getAccount();
final SQLiteDatabase db = this.getWritableDatabase();
+ db.beginTransaction();
for (Contact contact : roster.getContacts()) {
if (contact.getOption(Contact.Options.IN_ROSTER)) {
db.insert(Contact.TABLENAME, null, contact.getContentValues());
@@ -586,6 +587,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.delete(Contact.TABLENAME, where, whereArgs);
}
}
+ db.setTransactionSuccessful();
+ db.endTransaction();
account.setRosterVersion(roster.getVersion());
updateAccount(account);
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 4f9011366..4e57d7f81 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -1,6 +1,5 @@
package eu.siacs.conversations.ui;
-import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.AlertDialog;
@@ -18,6 +17,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
import android.util.Log;
@@ -38,6 +38,8 @@ import android.widget.Toast;
import net.java.otr4j.session.SessionStatus;
+import org.openintents.openpgp.util.OpenPgpApi;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -66,7 +68,6 @@ import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.chatstate.ChatState;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
-import org.openintents.openpgp.util.OpenPgpApi;
public class ConversationActivity extends XmppActivity
implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast {
@@ -207,7 +208,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onItemClick(AdapterView<?> arg0, View clickedView,
- int position, long arg3) {
+ int position, long arg3) {
if (getSelectedConversation() != conversationList.get(position)) {
setSelectedConversation(conversationList.get(position));
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
@@ -296,7 +297,7 @@ public class ConversationActivity extends XmppActivity
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
mSlidingPaneLayout.setParallaxDistance(150);
mSlidingPaneLayout
- .setShadowResource(R.drawable.es_slidingpane_shadow);
+ .setShadowResource(R.drawable.es_slidingpane_shadow);
mSlidingPaneLayout.setSliderFadeColor(0);
mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() {
@@ -307,7 +308,7 @@ public class ConversationActivity extends XmppActivity
hideKeyboard();
if (xmppConnectionServiceBound) {
xmppConnectionService.getNotificationService()
- .setOpenConversation(null);
+ .setOpenConversation(null);
}
closeContextMenu();
}
@@ -504,7 +505,7 @@ public class ConversationActivity extends XmppActivity
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.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
intent.setType("image/*");
chooser = true;
@@ -571,16 +572,16 @@ public class ConversationActivity extends XmppActivity
}
switch (attachmentChoice) {
case ATTACHMENT_CHOICE_LOCATION:
- getPreferences().edit().putString("recently_used_quick_action","location").apply();
+ getPreferences().edit().putString("recently_used_quick_action", "location").apply();
break;
case ATTACHMENT_CHOICE_RECORD_VOICE:
- getPreferences().edit().putString("recently_used_quick_action","voice").apply();
+ getPreferences().edit().putString("recently_used_quick_action", "voice").apply();
break;
case ATTACHMENT_CHOICE_TAKE_PHOTO:
- getPreferences().edit().putString("recently_used_quick_action","photo").apply();
+ getPreferences().edit().putString("recently_used_quick_action", "photo").apply();
break;
case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
- getPreferences().edit().putString("recently_used_quick_action","picture").apply();
+ getPreferences().edit().putString("recently_used_quick_action", "picture").apply();
break;
}
final Conversation conversation = getSelectedConversation();
@@ -620,19 +621,19 @@ public class ConversationActivity extends XmppActivity
selectPresenceToAttachFile(attachmentChoice, encryption);
} else {
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
- .findFragmentByTag("conversation");
+ .findFragmentByTag("conversation");
if (fragment != null) {
fragment.showNoPGPKeyDialog(false,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
- int which) {
+ int which) {
conversation
- .setNextEncryption(Message.ENCRYPTION_NONE);
+ .setNextEncryption(Message.ENCRYPTION_NONE);
xmppConnectionService.databaseBackend
- .updateConversation(conversation);
- selectPresenceToAttachFile(attachmentChoice,Message.ENCRYPTION_NONE);
+ .updateConversation(conversation);
+ selectPresenceToAttachFile(attachmentChoice, Message.ENCRYPTION_NONE);
}
});
}
@@ -647,19 +648,6 @@ public class ConversationActivity extends XmppActivity
}
}
- public boolean hasStoragePermission(int attachmentChoice) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, attachmentChoice);
- return false;
- } else {
- return true;
- }
- } else {
- return true;
- }
- }
-
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (grantResults.length > 0)
@@ -672,8 +660,8 @@ public class ConversationActivity extends XmppActivity
attachFile(requestCode);
}
} else {
- Toast.makeText(this,R.string.no_storage_permission,Toast.LENGTH_SHORT).show();
- }
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
+ }
}
public void startDownloadable(Message message) {
@@ -684,14 +672,14 @@ public class ConversationActivity extends XmppActivity
Transferable transferable = message.getTransferable();
if (transferable != null) {
if (!transferable.start()) {
- Toast.makeText(this, R.string.not_connected_try_again,Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show();
}
} else if (message.treatAsDownloadable() != Message.Decision.NEVER) {
xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, true);
}
}
- @Override
+ @Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (item.getItemId() == android.R.id.home) {
showConversationsOverview();
@@ -762,9 +750,9 @@ public class ConversationActivity extends XmppActivity
this.mConversationFragment.reInit(getSelectedConversation());
} else {
setSelectedConversation(null);
- if (mRedirected.compareAndSet(false,true)) {
+ if (mRedirected.compareAndSet(false, true)) {
Intent intent = new Intent(this, StartConversationActivity.class);
- intent.putExtra("init",true);
+ intent.putExtra("init", true);
startActivity(intent);
finish();
}
@@ -779,7 +767,7 @@ public class ConversationActivity extends XmppActivity
View dialogView = getLayoutInflater().inflate(
R.layout.dialog_clear_history, null);
final CheckBox endConversationCheckBox = (CheckBox) dialogView
- .findViewById(R.id.end_conversation_checkbox);
+ .findViewById(R.id.end_conversation_checkbox);
builder.setView(dialogView);
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.delete_messages),
@@ -881,7 +869,7 @@ public class ConversationActivity extends XmppActivity
}
PopupMenu popup = new PopupMenu(this, menuItemView);
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
- .findFragmentByTag("conversation");
+ .findFragmentByTag("conversation");
if (fragment != null) {
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@@ -902,7 +890,7 @@ public class ConversationActivity extends XmppActivity
conversation.setNextEncryption(Message.ENCRYPTION_PGP);
item.setChecked(true);
} else {
- announcePgp(conversation.getAccount(),conversation);
+ announcePgp(conversation.getAccount(), conversation);
}
} else {
showInstallPgpDialog();
@@ -1008,7 +996,7 @@ public class ConversationActivity extends XmppActivity
int rotation = getWindowManager().getDefaultDisplay().getRotation();
final int upKey;
final int downKey;
- switch(rotation) {
+ switch (rotation) {
case Surface.ROTATION_90:
upKey = KeyEvent.KEYCODE_DPAD_LEFT;
downKey = KeyEvent.KEYCODE_DPAD_RIGHT;
@@ -1032,7 +1020,7 @@ public class ConversationActivity extends XmppActivity
} else if (modifier && key == downKey) {
if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
showConversationsOverview();
- }
+ }
return selectDownConversation();
} else if (modifier && key == upKey) {
if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
@@ -1169,11 +1157,11 @@ public class ConversationActivity extends XmppActivity
public void onSaveInstanceState(final Bundle savedInstanceState) {
Conversation conversation = getSelectedConversation();
if (conversation != null) {
- savedInstanceState.putString(STATE_OPEN_CONVERSATION,conversation.getUuid());
+ savedInstanceState.putString(STATE_OPEN_CONVERSATION, conversation.getUuid());
} else {
savedInstanceState.remove(STATE_OPEN_CONVERSATION);
}
- savedInstanceState.putBoolean(STATE_PANEL_OPEN,isConversationsOverviewVisable());
+ savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable());
if (this.mPendingImageUris.size() >= 1) {
savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUris.get(0).toString());
} else {
@@ -1200,7 +1188,7 @@ public class ConversationActivity extends XmppActivity
}
if (xmppConnectionService.getAccounts().size() == 0) {
- if (mRedirected.compareAndSet(false,true)) {
+ if (mRedirected.compareAndSet(false, true)) {
if (Config.X509_VERIFICATION) {
startActivity(new Intent(this, ManageAccountActivity.class));
} else {
@@ -1209,9 +1197,9 @@ public class ConversationActivity extends XmppActivity
finish();
}
} else if (conversationList.size() <= 0) {
- if (mRedirected.compareAndSet(false,true)) {
+ if (mRedirected.compareAndSet(false, true)) {
Intent intent = new Intent(this, StartConversationActivity.class);
- intent.putExtra("init",true);
+ intent.putExtra("init", true);
startActivity(intent);
finish();
}
@@ -1243,7 +1231,7 @@ public class ConversationActivity extends XmppActivity
this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
}
- if(!forbidProcessingPendings) {
+ if (!forbidProcessingPendings) {
for (Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
Uri foo = i.next();
attachImageToConversation(getSelectedConversation(), foo);
@@ -1260,7 +1248,9 @@ public class ConversationActivity extends XmppActivity
}
forbidProcessingPendings = false;
- ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
+ if (!ExceptionHelper.checkForCrash(this, this.xmppConnectionService)) {
+ openBatteryOptimizationDialogIfNeeded();
+ }
setIntent(new Intent());
}
@@ -1269,14 +1259,14 @@ public class ConversationActivity extends XmppActivity
final String downloadUuid = intent.getStringExtra(MESSAGE);
final String text = intent.getStringExtra(TEXT);
final String nick = intent.getStringExtra(NICK);
- final boolean pm = intent.getBooleanExtra(PRIVATE_MESSAGE,false);
+ final boolean pm = intent.getBooleanExtra(PRIVATE_MESSAGE, false);
if (selectConversationByUuid(uuid)) {
this.mConversationFragment.reInit(getSelectedConversation());
if (nick != null) {
if (pm) {
Jid jid = getSelectedConversation().getJid();
try {
- Jid next = Jid.fromParts(jid.getLocalpart(),jid.getDomainpart(),nick);
+ Jid next = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), nick);
this.mConversationFragment.privateMessageWith(next);
} catch (final InvalidJidException ignored) {
//do nothing
@@ -1326,7 +1316,7 @@ public class ConversationActivity extends XmppActivity
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) {
+ for (int i = 0; i < clipData.getItemCount(); ++i) {
uris.add(clipData.getItemAt(i).getUri());
}
} else {
@@ -1336,8 +1326,7 @@ public class ConversationActivity extends XmppActivity
}
@Override
- 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 (resultCode == RESULT_OK) {
if (requestCode == REQUEST_DECRYPT_PGP) {
@@ -1365,15 +1354,15 @@ public class ConversationActivity extends XmppActivity
mPendingImageUris.clear();
mPendingImageUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
- attachImageToConversation(getSelectedConversation(),i.next());
+ for (Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ attachImageToConversation(getSelectedConversation(), i.next());
}
}
} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_FILE || requestCode == ATTACHMENT_CHOICE_RECORD_VOICE) {
mPendingFileUris.clear();
mPendingFileUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- for(Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
+ for (Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
attachFileToConversation(getSelectedConversation(), i.next());
}
}
@@ -1391,9 +1380,9 @@ public class ConversationActivity extends XmppActivity
mPendingImageUris.clear();
}
} else if (requestCode == ATTACHMENT_CHOICE_LOCATION) {
- double latitude = data.getDoubleExtra("latitude",0);
- double longitude = data.getDoubleExtra("longitude",0);
- this.mPendingGeoUri = Uri.parse("geo:"+String.valueOf(latitude)+","+String.valueOf(longitude));
+ double latitude = data.getDoubleExtra("latitude", 0);
+ double longitude = data.getDoubleExtra("longitude", 0);
+ this.mPendingGeoUri = Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude));
if (xmppConnectionServiceBound) {
attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
this.mPendingGeoUri = null;
@@ -1408,6 +1397,39 @@ public class ConversationActivity extends XmppActivity
if (requestCode == ConversationActivity.REQUEST_DECRYPT_PGP) {
mConversationFragment.onActivityResult(requestCode, resultCode, data);
}
+ if (requestCode == REQUEST_BATTERY_OP) {
+ setNeverAskForBatteryOptimizationsAgain();
+ }
+ }
+ }
+
+ private void setNeverAskForBatteryOptimizationsAgain() {
+ getPreferences().edit().putBoolean("show_battery_optimization", false).commit();
+ }
+
+ private void openBatteryOptimizationDialogIfNeeded() {
+ if (showBatteryOptimizationWarning() && getPreferences().getBoolean("show_battery_optimizationF", true)) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.battery_optimizations_enabled);
+ builder.setMessage(R.string.battery_optimizations_enabled_dialog);
+ builder.setPositiveButton(R.string.next, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ Uri uri = Uri.parse("package:" + getPackageName());
+ intent.setData(uri);
+ startActivityForResult(intent, REQUEST_BATTERY_OP);
+ }
+ });
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ setNeverAskForBatteryOptimizationsAgain();
+ }
+ });
+ }
+ builder.create().show();
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
index 1545de0f3..22b875c2e 100644
--- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java
@@ -5,9 +5,10 @@ import android.app.AlertDialog.Builder;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.Settings;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
import android.text.Editable;
@@ -52,16 +53,17 @@ import eu.siacs.conversations.xmpp.pep.Avatar;
public class EditAccountActivity extends XmppActivity implements OnAccountUpdate,
OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast {
- private LinearLayout mMainLayout;
private AutoCompleteTextView mAccountJid;
private EditText mPassword;
private EditText mPasswordConfirm;
private CheckBox mRegisterNew;
private Button mCancelButton;
private Button mSaveButton;
+ private Button mDisableBatterOptimizations;
private TableLayout mMoreTable;
private LinearLayout mStats;
+ private RelativeLayout mBatteryOptimizations;
private TextView mServerInfoSm;
private TextView mServerInfoRosterVersion;
private TextView mServerInfoCarbons;
@@ -311,6 +313,14 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
});
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_BATTERY_OP) {
+ updateAccountInformation(mAccount == null);
+ }
+ }
+
protected void updateSaveButton() {
if (accountInfoEdited() && !mInitMode) {
this.mSaveButton.setText(R.string.save);
@@ -372,7 +382,6 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_account);
- this.mMainLayout = (LinearLayout) findViewById(R.id.account_main_layout);
this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid);
this.mAccountJid.addTextChangedListener(this.mTextWatcher);
this.mAccountJidLabel = (TextView) findViewById(R.id.account_jid_label);
@@ -387,6 +396,17 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
this.mAvatar.setOnClickListener(this.mAvatarClickListener);
this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new);
this.mStats = (LinearLayout) findViewById(R.id.stats);
+ this.mBatteryOptimizations = (RelativeLayout) findViewById(R.id.battery_optimization);
+ this.mDisableBatterOptimizations = (Button) findViewById(R.id.batt_op_disable);
+ this.mDisableBatterOptimizations.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ Uri uri = Uri.parse("package:"+getPackageName());
+ intent.setData(uri);
+ startActivityForResult(intent,REQUEST_BATTERY_OP);
+ }
+ });
this.mSessionEst = (TextView) findViewById(R.id.session_est);
this.mServerInfoRosterVersion = (TextView) findViewById(R.id.server_info_roster_version);
this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons);
@@ -595,6 +615,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
}
if (this.mAccount.isOnlineAndConnected() && !this.mFetchingAvatar) {
this.mStats.setVisibility(View.VISIBLE);
+ this.mBatteryOptimizations.setVisibility(showBatteryOptimizationWarning() ? View.VISIBLE : View.GONE);
this.mSessionEst.setText(UIHelper.readableTimeDifferenceFull(this, this.mAccount.getXmppConnection()
.getLastSessionEstablished()));
Features features = this.mAccount.getXmppConnection().getFeatures();
diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
index 3313ce318..edd6cf150 100644
--- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
@@ -3,6 +3,7 @@ package eu.siacs.conversations.ui;
import android.app.PendingIntent;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
@@ -137,16 +138,35 @@ public class PublishProfilePictureActivity extends XmppActivity {
@Override
public void onClick(View v) {
- Intent attachFileIntent = new Intent();
- attachFileIntent.setType("image/*");
- attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
- Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file));
- startActivityForResult(chooser, REQUEST_CHOOSE_FILE);
+ if (hasStoragePermission(REQUEST_CHOOSE_FILE)) {
+ chooseAvatar();
+ }
+
}
});
this.defaultUri = PhoneHelper.getSefliUri(getApplicationContext());
}
+ private void chooseAvatar() {
+ Intent attachFileIntent = new Intent();
+ attachFileIntent.setType("image/*");
+ attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
+ Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file));
+ startActivityForResult(chooser, REQUEST_CHOOSE_FILE);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+ if (grantResults.length > 0)
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ if (requestCode == REQUEST_CHOOSE_FILE) {
+ chooseAvatar();
+ }
+ } else {
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
+ }
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
diff --git a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java
index 2e6d32466..bc319108c 100644
--- a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java
@@ -42,6 +42,8 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
private Button mSaveButton;
private Button mCancelButton;
+ private AxolotlService.FetchStatus lastFetchReport = AxolotlService.FetchStatus.SUCCESS;
+
private final Map<String, Boolean> ownKeysToTrust = new HashMap<>();
private final Map<String, Boolean> foreignKeysToTrust = new HashMap<>();
@@ -160,7 +162,11 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
} else {
if (!hasForeignKeys && hasNoOtherTrustedKeys()) {
keyErrorMessageCard.setVisibility(View.VISIBLE);
- keyErrorMessage.setText(R.string.error_no_keys_to_trust);
+ if (lastFetchReport == AxolotlService.FetchStatus.ERROR) {
+ keyErrorMessage.setText(R.string.error_no_keys_to_trust_server_error);
+ } else {
+ keyErrorMessage.setText(R.string.error_no_keys_to_trust);
+ }
ownKeys.removeAllViews(); ownKeysCard.setVisibility(View.GONE);
foreignKeys.removeAllViews(); foreignKeysCard.setVisibility(View.GONE);
}
@@ -216,6 +222,7 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate
@Override
public void onKeyStatusUpdated(final AxolotlService.FetchStatus report) {
if (report != null) {
+ lastFetchReport = report;
runOnUiThread(new Runnable() {
@Override
public void run() {
diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
index be6255127..85077c9df 100644
--- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
@@ -1,5 +1,6 @@
package eu.siacs.conversations.ui;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActionBar;
@@ -35,6 +36,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.InputType;
@@ -91,6 +93,7 @@ public abstract class XmppActivity extends Activity {
protected static final int REQUEST_ANNOUNCE_PGP = 0x0101;
protected static final int REQUEST_INVITE_TO_CONVERSATION = 0x0102;
protected static final int REQUEST_CHOOSE_PGP_ID = 0x0103;
+ protected static final int REQUEST_BATTERY_OP = 0x13849ff;
public XmppConnectionService xmppConnectionService;
public boolean xmppConnectionServiceBound = false;
@@ -375,6 +378,15 @@ public abstract class XmppActivity extends Activity {
}
}
+ protected boolean showBatteryOptimizationWarning() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
+ return !pm.isIgnoringBatteryOptimizations(getPackageName());
+ } else {
+ return false;
+ }
+ }
+
protected boolean usingEnterKey() {
return getPreferences().getBoolean("display_enter_key", false);
}
@@ -785,6 +797,19 @@ public abstract class XmppActivity extends Activity {
builder.create().show();
}
+ public boolean hasStoragePermission(int requestCode) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+
public void selectPresence(final Conversation conversation,
final OnPresenceSelected listener) {
final Contact contact = conversation.getContact();
diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java
index e07df627e..87790d64d 100644
--- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java
@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;
+import java.util.Map;
import java.util.regex.Pattern;
import de.measite.minidns.Client;
@@ -57,7 +58,7 @@ public class DNSHelper {
if (!b.containsKey("values")) {
Log.d(Config.LOGTAG,"all dns queries failed. provide fallback A record");
ArrayList<Parcelable> values = new ArrayList<>();
- values.add(createNamePortBundle(host,5222));
+ values.add(createNamePortBundle(host, 5222, false));
b.putParcelableArrayList("values",values);
}
return b;
@@ -96,57 +97,73 @@ public class DNSHelper {
return servers;
}
- public static Bundle queryDNS(String host, InetAddress dnsServer) {
- Bundle bundle = new Bundle();
- try {
- client.setTimeout(Config.PING_TIMEOUT * 1000);
- 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());
-
- TreeMap<Integer, ArrayList<SRV>> priorities = new TreeMap<>();
- TreeMap<String, ArrayList<String>> ips4 = new TreeMap<>();
- TreeMap<String, ArrayList<String>> ips6 = new TreeMap<>();
-
- 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())) {
- SRV srv = (SRV) d;
- if (!priorities.containsKey(srv.getPriority())) {
- priorities.put(srv.getPriority(),new ArrayList<SRV>());
- }
- priorities.get(srv.getPriority()).add(srv);
+ private static class TlsSrv {
+ private final SRV srv;
+ private final boolean tls;
+
+ public TlsSrv(SRV srv, boolean tls) {
+ this.srv = srv;
+ this.tls = tls;
+ }
+ }
+
+ private static void fillSrvMaps(final String qname, final InetAddress dnsServer, final Map<Integer, List<TlsSrv>> priorities, final Map<String, List<String>> ips4, final Map<String, List<String>> ips6, final boolean tls) throws IOException {
+ final DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress());
+ 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())) {
+ SRV srv = (SRV) d;
+ if (!priorities.containsKey(srv.getPriority())) {
+ priorities.put(srv.getPriority(),new ArrayList<TlsSrv>());
}
- if (d instanceof A) {
- A a = (A) d;
- if (!ips4.containsKey(rr.getName())) {
- ips4.put(rr.getName(), new ArrayList<String>());
- }
- ips4.get(rr.getName()).add(a.toString());
+ priorities.get(srv.getPriority()).add(new TlsSrv(srv, tls));
+ }
+ if (d instanceof A) {
+ A a = (A) d;
+ if (!ips4.containsKey(rr.getName())) {
+ ips4.put(rr.getName(), new ArrayList<String>());
}
- if (d instanceof AAAA) {
- AAAA aaaa = (AAAA) d;
- if (!ips6.containsKey(rr.getName())) {
- ips6.put(rr.getName(), new ArrayList<String>());
- }
- ips6.get(rr.getName()).add("[" + aaaa.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<String>());
}
+ ips6.get(rr.getName()).add("[" + aaaa.toString() + "]");
}
}
+ }
+ }
+
+ public static Bundle queryDNS(String host, InetAddress dnsServer) {
+ Bundle bundle = new Bundle();
+ try {
+ client.setTimeout(Config.PING_TIMEOUT * 1000);
+ final String qname = "_xmpp-client._tcp." + host;
+ final String tlsQname = "_xmpps-client._tcp." + host;
+ Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host);
+
+ final Map<Integer, List<TlsSrv>> priorities = new TreeMap<>();
+ final Map<String, List<String>> ips4 = new TreeMap<>();
+ final Map<String, List<String>> ips6 = new TreeMap<>();
+
+ fillSrvMaps(qname, dnsServer, priorities, ips4, ips6, false);
+ fillSrvMaps(tlsQname, dnsServer, priorities, ips4, ips6, true);
- ArrayList<SRV> result = new ArrayList<>();
- for (ArrayList<SRV> s : priorities.values()) {
+ final List<TlsSrv> result = new ArrayList<>();
+ for (final List<TlsSrv> s : priorities.values()) {
result.addAll(s);
}
- ArrayList<Bundle> values = new ArrayList<>();
+ final ArrayList<Bundle> values = new ArrayList<>();
if (result.size() == 0) {
DNSMessage response;
try {
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()));
+ values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false));
}
} catch (SocketTimeoutException e) {
Log.d(Config.LOGTAG,"ignoring timeout exception when querying A record on "+dnsServer.getHostAddress());
@@ -154,37 +171,38 @@ public class DNSHelper {
try {
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()));
+ values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false));
}
} catch (SocketTimeoutException e) {
Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress());
}
- values.add(createNamePortBundle(host,5222));
+ values.add(createNamePortBundle(host, 5222, false));
bundle.putParcelableArrayList("values", values);
return bundle;
}
- for (SRV srv : result) {
+ for (final TlsSrv tlsSrv : result) {
+ final SRV srv = tlsSrv.srv;
if (ips6.containsKey(srv.getName())) {
- values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6));
+ values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6, tlsSrv.tls));
} else {
try {
DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress());
for (int i = 0; i < response.getAnswers().length; ++i) {
- values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload()));
+ values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload(), tlsSrv.tls));
}
} catch (SocketTimeoutException e) {
Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress());
}
}
if (ips4.containsKey(srv.getName())) {
- values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4));
+ values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4, tlsSrv.tls));
} 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(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload()));
+ values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload(), tlsSrv.tls));
}
}
- values.add(createNamePortBundle(srv.getName(), srv.getPort()));
+ values.add(createNamePortBundle(srv.getName(), srv.getPort(), tlsSrv.tls));
}
bundle.putParcelableArrayList("values", values);
} catch (SocketTimeoutException e) {
@@ -195,28 +213,31 @@ public class DNSHelper {
return bundle;
}
- private static Bundle createNamePortBundle(String name, int port) {
+ private static Bundle createNamePortBundle(String name, int port, final boolean tls) {
Bundle namePort = new Bundle();
namePort.putString("name", name);
+ namePort.putBoolean("tls", tls);
namePort.putInt("port", port);
return namePort;
}
- private static Bundle createNamePortBundle(String name, int port, TreeMap<String, ArrayList<String>> ips) {
+ private static Bundle createNamePortBundle(String name, int port, Map<String, List<String>> ips, final boolean tls) {
Bundle namePort = new Bundle();
namePort.putString("name", name);
+ namePort.putBoolean("tls", tls);
namePort.putInt("port", port);
if (ips!=null) {
- ArrayList<String> ip = ips.get(name);
+ List<String> ip = ips.get(name);
Collections.shuffle(ip, new Random());
namePort.putString("ip", ip.get(0));
}
return namePort;
}
- private static Bundle createNamePortBundle(String name, int port, Data data) {
+ private static Bundle createNamePortBundle(String name, int port, Data data, final boolean tls) {
Bundle namePort = new Bundle();
namePort.putString("name", name);
+ namePort.putBoolean("tls", tls);
namePort.putInt("port", port);
if (data instanceof A) {
namePort.putString("ip", data.toString());
diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java
index 6d1d1074d..f2c3ea18a 100644
--- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java
@@ -24,6 +24,7 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -35,14 +36,13 @@ public class ExceptionHelper {
}
}
- public static void checkForCrash(Context context,
- final XmppConnectionService service) {
+ public static boolean checkForCrash(ConversationActivity activity, final XmppConnectionService service) {
try {
final SharedPreferences preferences = PreferenceManager
- .getDefaultSharedPreferences(context);
+ .getDefaultSharedPreferences(activity);
boolean neverSend = preferences.getBoolean("never_send", false);
if (neverSend) {
- return;
+ return false;
}
List<Account> accounts = service.getAccounts();
Account account = null;
@@ -53,24 +53,25 @@ public class ExceptionHelper {
}
}
if (account == null) {
- return;
+ return false;
}
final Account finalAccount = account;
- FileInputStream file = context.openFileInput("stacktrace.txt");
+ FileInputStream file = activity.openFileInput("stacktrace.txt");
InputStreamReader inputStreamReader = new InputStreamReader(file);
BufferedReader stacktrace = new BufferedReader(inputStreamReader);
final StringBuilder report = new StringBuilder();
- PackageManager pm = context.getPackageManager();
+ PackageManager pm = activity.getPackageManager();
PackageInfo packageInfo = null;
try {
- packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
+ packageInfo = pm.getPackageInfo(activity.getPackageName(), 0);
report.append("Version: " + packageInfo.versionName + '\n');
report.append("Last Update: "
- + DateUtils.formatDateTime(context,
- packageInfo.lastUpdateTime,
- DateUtils.FORMAT_SHOW_TIME
- | DateUtils.FORMAT_SHOW_DATE) + '\n');
+ + DateUtils.formatDateTime(activity,
+ packageInfo.lastUpdateTime,
+ DateUtils.FORMAT_SHOW_TIME
+ | DateUtils.FORMAT_SHOW_DATE) + '\n');
} catch (NameNotFoundException e) {
+ return false;
}
String line;
while ((line = stacktrace.readLine()) != null) {
@@ -78,11 +79,11 @@ public class ExceptionHelper {
report.append('\n');
}
file.close();
- context.deleteFile("stacktrace.txt");
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(context.getString(R.string.crash_report_title));
- builder.setMessage(context.getText(R.string.crash_report_message));
- builder.setPositiveButton(context.getText(R.string.send_now),
+ activity.deleteFile("stacktrace.txt");
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(activity.getString(R.string.crash_report_title));
+ builder.setMessage(activity.getText(R.string.crash_report_message));
+ builder.setPositiveButton(activity.getText(R.string.send_now),
new OnClickListener() {
@Override
@@ -91,18 +92,19 @@ public class ExceptionHelper {
Log.d(Config.LOGTAG, "using account="
+ finalAccount.getJid().toBareJid()
+ " to send in stack trace");
- Conversation conversation = null;
- try {
- conversation = service.findOrCreateConversation(finalAccount,
- Jid.fromString("bugs@pix-art.de"), false);
- } catch (final InvalidJidException ignored) {
- }
- Message message = new Message(conversation, report
+
+ Conversation conversation = null;
+ try {
+ conversation = service.findOrCreateConversation(finalAccount,
+ Jid.fromString("bugs@pix-art.de"), false);
+ } catch (final InvalidJidException ignored) {
+ }
+ Message message = new Message(conversation, report
.toString(), Message.ENCRYPTION_NONE);
service.sendMessage(message);
}
});
- builder.setNegativeButton(context.getText(R.string.send_never),
+ builder.setNegativeButton(activity.getText(R.string.send_never),
new OnClickListener() {
@Override
@@ -112,8 +114,9 @@ public class ExceptionHelper {
}
});
builder.create().show();
+ return true;
} catch (final IOException ignored) {
- }
-
+ return false;
+ }
}
}
diff --git a/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java b/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java
new file mode 100644
index 000000000..49e9a81ad
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java
@@ -0,0 +1,62 @@
+package eu.siacs.conversations.utils;
+
+import java.lang.reflect.Method;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class SSLSocketHelper {
+
+ public static void setSecurity(final SSLSocket sslSocket) throws NoSuchAlgorithmException {
+ final String[] supportProtocols;
+ final Collection<String> supportedProtocols = new LinkedList<>(
+ Arrays.asList(sslSocket.getSupportedProtocols()));
+ supportedProtocols.remove("SSLv3");
+ supportProtocols = supportedProtocols.toArray(new String[supportedProtocols.size()]);
+
+ sslSocket.setEnabledProtocols(supportProtocols);
+
+ final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites(
+ sslSocket.getSupportedCipherSuites());
+ if (cipherSuites.length > 0) {
+ sslSocket.setEnabledCipherSuites(cipherSuites);
+ }
+ }
+
+ public static void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) {
+ if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ ((android.net.SSLCertificateSocketFactory) factory).setHostname(socket, hostname);
+ } else {
+ try {
+ socket.getClass().getMethod("setHostname", String.class).invoke(socket, hostname);
+ } catch (Throwable e) {
+ // ignore any error, we just can't set the hostname...
+ }
+ }
+ }
+
+ public static void setAlpnProtocol(final SSLSocketFactory factory, final SSLSocket socket, final String protocol) {
+ try {
+ if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+ // can't call directly because of @hide?
+ //((android.net.SSLCertificateSocketFactory)factory).setAlpnProtocols(new byte[][]{protocol.getBytes("UTF-8")});
+ android.net.SSLCertificateSocketFactory.class.getMethod("setAlpnProtocols", byte[][].class).invoke(socket, new Object[]{new byte[][]{protocol.getBytes("UTF-8")}});
+ } else {
+ final Method method = socket.getClass().getMethod("setAlpnProtocols", byte[].class);
+ // the concatenation of 8-bit, length prefixed protocol names, just one in our case...
+ // http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4
+ final byte[] protocolUTF8Bytes = protocol.getBytes("UTF-8");
+ final byte[] lengthPrefixedProtocols = new byte[protocolUTF8Bytes.length + 1];
+ lengthPrefixedProtocols[0] = (byte) protocol.length(); // cannot be over 255 anyhow
+ System.arraycopy(protocolUTF8Bytes, 0, lengthPrefixedProtocols, 1, protocolUTF8Bytes.length);
+ method.invoke(socket, new Object[]{lengthPrefixedProtocols});
+ }
+ } catch (Throwable e) {
+ // ignore any error, we just can't set the alpn protocol...
+ }
+ }
+}
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index c64fa196d..a56a64aff 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -20,7 +20,6 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.math.BigInteger;
import java.net.ConnectException;
import java.net.IDN;
@@ -35,12 +34,9 @@ import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
@@ -66,6 +62,7 @@ import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.DNSHelper;
+import eu.siacs.conversations.utils.SSLSocketHelper;
import eu.siacs.conversations.utils.SocksSocketFactory;
import eu.siacs.conversations.utils.Xmlns;
import eu.siacs.conversations.xml.Element;
@@ -247,6 +244,7 @@ public class XmppConnection implements Runnable {
}
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": connect to "+destination+" via TOR");
socket = SocksSocketFactory.createSocketOverTor(destination,account.getPort());
+ startXmpp();
} else if (DNSHelper.isIp(account.getServer().toString())) {
socket = new Socket();
try {
@@ -254,13 +252,12 @@ public class XmppConnection implements Runnable {
} catch (IOException e) {
throw new UnknownHostException();
}
+ startXmpp();
} else {
- final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService);
+ final Bundle result = DNSHelper.getSRVRecord(account.getServer(), mXmppConnectionService);
final ArrayList<Parcelable>values = result.getParcelableArrayList("values");
- int i = 0;
- boolean socketError = true;
- while (socketError && values.size() > i) {
- final Bundle namePort = (Bundle) values.get(i);
+ for(Iterator<Parcelable> iterator = values.iterator(); iterator.hasNext();) {
+ final Bundle namePort = (Bundle) iterator.next();
try {
String srvRecordServer;
try {
@@ -271,48 +268,57 @@ public class XmppConnection implements Runnable {
}
final int srvRecordPort = namePort.getInt("port");
final String srvIpServer = namePort.getString("ip");
+ // if tls is true, encryption is implied and must not be started
+ features.encryptionEnabled = namePort.getBoolean("tls");
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);
+ + "[" + srvIpServer + "]:" + srvRecordPort + " tls: " + features.encryptionEnabled);
} else {
addr = new InetSocketAddress(srvRecordServer, srvRecordPort);
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ ": using values from dns "
- + srvRecordServer + ":" + srvRecordPort);
+ + srvRecordServer + ":" + srvRecordPort + " tls: " + features.encryptionEnabled);
}
- socket = new Socket();
- socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
- socketError = false;
+
+ if (!features.encryptionEnabled) {
+ socket = new Socket();
+ socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
+ } else {
+ final TlsFactoryVerifier tlsFactoryVerifier = getTlsFactoryVerifier();
+ socket = tlsFactoryVerifier.factory.createSocket();
+
+ if (socket == null) {
+ throw new IOException("could not initialize ssl socket");
+ }
+
+ SSLSocketHelper.setSecurity((SSLSocket) socket);
+ SSLSocketHelper.setSNIHost(tlsFactoryVerifier.factory, (SSLSocket) socket, account.getServer().getDomainpart());
+ SSLSocketHelper.setAlpnProtocol(tlsFactoryVerifier.factory, (SSLSocket) socket, "xmpp-client");
+
+ socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
+
+ if (!tlsFactoryVerifier.verifier.verify(account.getServer().getDomainpart(), ((SSLSocket) socket).getSession())) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": TLS certificate verification failed");
+ throw new SecurityException();
+ }
+ }
+
+ if (startXmpp())
+ break; // successfully connected to server that speaks xmpp
+ } catch(final SecurityException e) {
+ throw e;
} catch (final Throwable e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage() +"("+e.getClass().getName()+")");
- i++;
+ if (!iterator.hasNext()) {
+ throw new UnknownHostException();
+ }
}
}
- if (socketError) {
- throw new UnknownHostException();
- }
- }
- final OutputStream out = socket.getOutputStream();
- tagWriter.setOutputStream(out);
- final InputStream in = socket.getInputStream();
- tagReader.setInputStream(in);
- tagWriter.beginDocument();
- sendStartStream();
- Tag nextTag;
- while ((nextTag = tagReader.readTag()) != null) {
- if (nextTag.isStart("stream")) {
- processStream();
- break;
- } else {
- throw new IOException("unknown tag on connect");
- }
- }
- if (socket.isConnected()) {
- socket.close();
}
+ processStream();
} catch (final IncompatibleServerException e) {
this.changeStatus(Account.State.INCOMPATIBLE_SERVER);
} catch (final SecurityException e) {
@@ -344,6 +350,66 @@ public class XmppConnection implements Runnable {
}
}
+ /**
+ * Starts xmpp protocol, call after connecting to socket
+ * @return true if server returns with valid xmpp, false otherwise
+ * @throws IOException Unknown tag on connect
+ * @throws XmlPullParserException Bad Xml
+ * @throws NoSuchAlgorithmException Other error
+ */
+ private boolean startXmpp() throws IOException, XmlPullParserException, NoSuchAlgorithmException {
+ tagWriter.setOutputStream(socket.getOutputStream());
+ tagReader.setInputStream(socket.getInputStream());
+ tagWriter.beginDocument();
+ sendStartStream();
+ Tag nextTag;
+ while ((nextTag = tagReader.readTag()) != null) {
+ if (nextTag.isStart("stream")) {
+ return true;
+ } else {
+ throw new IOException("unknown tag on connect");
+ }
+ }
+ if (socket.isConnected()) {
+ socket.close();
+ }
+ return false;
+ }
+
+ private static class TlsFactoryVerifier {
+ private final SSLSocketFactory factory;
+ private final HostnameVerifier verifier;
+
+ public TlsFactoryVerifier(final SSLSocketFactory factory, final HostnameVerifier verifier) throws IOException {
+ this.factory = factory;
+ this.verifier = verifier;
+ if (factory == null || verifier == null) {
+ throw new IOException("could not setup ssl");
+ }
+ }
+ }
+
+ private TlsFactoryVerifier getTlsFactoryVerifier() throws NoSuchAlgorithmException, KeyManagementException, IOException {
+ final SSLContext sc = SSLContext.getInstance("TLS");
+ MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager();
+ KeyManager[] keyManager;
+ if (account.getPrivateKeyAlias() != null && account.getPassword().isEmpty()) {
+ keyManager = new KeyManager[]{mKeyManager};
+ } else {
+ keyManager = null;
+ }
+ sc.init(keyManager, new X509TrustManager[]{mInteractive ? trustManager : trustManager.getNonInteractive()}, mXmppConnectionService.getRNG());
+ final SSLSocketFactory factory = sc.getSocketFactory();
+ final HostnameVerifier verifier;
+ if (mInteractive) {
+ verifier = trustManager.wrapHostnameVerifier(new XmppDomainVerifier());
+ } else {
+ verifier = trustManager.wrapHostnameVerifierNonInteractive(new XmppDomainVerifier());
+ }
+
+ return new TlsFactoryVerifier(factory, verifier);
+ }
+
@Override
public void run() {
try {
@@ -605,53 +671,27 @@ public class XmppConnection implements Runnable {
tagWriter.writeTag(startTLS);
}
+
+
private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException {
tagReader.readTag();
try {
- final SSLContext sc = SSLContext.getInstance("TLS");
- MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager();
- KeyManager[] keyManager;
- if (account.getPrivateKeyAlias() != null && account.getPassword().isEmpty()) {
- keyManager = new KeyManager[]{ mKeyManager };
- } else {
- keyManager = null;
- }
- sc.init(keyManager,new X509TrustManager[]{mInteractive ? trustManager : trustManager.getNonInteractive()},mXmppConnectionService.getRNG());
- final SSLSocketFactory factory = sc.getSocketFactory();
- final HostnameVerifier verifier;
- if (mInteractive) {
- verifier = trustManager.wrapHostnameVerifier(new XmppDomainVerifier());
- } else {
- verifier = trustManager.wrapHostnameVerifierNonInteractive(new XmppDomainVerifier());
- }
+ final TlsFactoryVerifier tlsFactoryVerifier = getTlsFactoryVerifier();
final InetAddress address = socket == null ? null : socket.getInetAddress();
- if (factory == null || address == null || verifier == null) {
+ if (address == null) {
throw new IOException("could not setup ssl");
}
- final SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,address.getHostAddress(), socket.getPort(),true);
+ final SSLSocket sslSocket = (SSLSocket) tlsFactoryVerifier.factory.createSocket(socket, address.getHostAddress(), socket.getPort(), true);
if (sslSocket == null) {
throw new IOException("could not initialize ssl socket");
}
- final String[] supportProtocols;
- final Collection<String> supportedProtocols = new LinkedList<>(
- Arrays.asList(sslSocket.getSupportedProtocols()));
- supportedProtocols.remove("SSLv3");
- supportProtocols = supportedProtocols.toArray(new String[supportedProtocols.size()]);
-
- sslSocket.setEnabledProtocols(supportProtocols);
-
- final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites(
- sslSocket.getSupportedCipherSuites());
- //Log.d(Config.LOGTAG, "Using ciphers: " + Arrays.toString(cipherSuites));
- if (cipherSuites.length > 0) {
- sslSocket.setEnabledCipherSuites(cipherSuites);
- }
+ SSLSocketHelper.setSecurity(sslSocket);
- if (!verifier.verify(account.getServer().getDomainpart(),sslSocket.getSession())) {
+ if (!tlsFactoryVerifier.verifier.verify(account.getServer().getDomainpart(), sslSocket.getSession())) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
throw new SecurityException();
}
diff --git a/src/main/res/drawable-hdpi/ic_launcher.png b/src/main/res/drawable-hdpi/ic_launcher.png
index 25fc8591f..690400eb1 100644
--- a/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/src/main/res/drawable-hdpi/message_bubble_received.9.png b/src/main/res/drawable-hdpi/message_bubble_received.9.png
index 4445ca04a..dfd857cb2 100644
--- a/src/main/res/drawable-hdpi/message_bubble_received.9.png
+++ b/src/main/res/drawable-hdpi/message_bubble_received.9.png
Binary files differ
diff --git a/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png
index 1bd8cb51f..fd07bc20c 100644
--- a/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png
+++ b/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png
Binary files differ
diff --git a/src/main/res/drawable-hdpi/message_bubble_received_white.9.png b/src/main/res/drawable-hdpi/message_bubble_received_white.9.png
index 15d27cca8..bec207983 100644
--- a/src/main/res/drawable-hdpi/message_bubble_received_white.9.png
+++ b/src/main/res/drawable-hdpi/message_bubble_received_white.9.png
Binary files differ
diff --git a/src/main/res/drawable-hdpi/message_bubble_sent.9.png b/src/main/res/drawable-hdpi/message_bubble_sent.9.png
index 5d79264e9..10dc2e299 100644
--- a/src/main/res/drawable-hdpi/message_bubble_sent.9.png
+++ b/src/main/res/drawable-hdpi/message_bubble_sent.9.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/ic_launcher.png b/src/main/res/drawable-mdpi/ic_launcher.png
index 733e96158..9e076434e 100644
--- a/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/message_bubble_received.9.png b/src/main/res/drawable-mdpi/message_bubble_received.9.png
index ba63820b2..9835a7361 100644
--- a/src/main/res/drawable-mdpi/message_bubble_received.9.png
+++ b/src/main/res/drawable-mdpi/message_bubble_received.9.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png
index 6523e9a14..ff8f80b69 100644
--- a/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png
+++ b/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/message_bubble_received_white.9.png b/src/main/res/drawable-mdpi/message_bubble_received_white.9.png
index 2abd4fe1b..d7a3bb5dd 100644
--- a/src/main/res/drawable-mdpi/message_bubble_received_white.9.png
+++ b/src/main/res/drawable-mdpi/message_bubble_received_white.9.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/message_bubble_sent.9.png b/src/main/res/drawable-mdpi/message_bubble_sent.9.png
index dd23cf7d7..596699bbe 100644
--- a/src/main/res/drawable-mdpi/message_bubble_sent.9.png
+++ b/src/main/res/drawable-mdpi/message_bubble_sent.9.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/ic_launcher.png b/src/main/res/drawable-xhdpi/ic_launcher.png
index c9e48859a..c49b2cb11 100644
--- a/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/message_bubble_received.9.png b/src/main/res/drawable-xhdpi/message_bubble_received.9.png
index aa0fc16e4..c0eb47ebb 100644
--- a/src/main/res/drawable-xhdpi/message_bubble_received.9.png
+++ b/src/main/res/drawable-xhdpi/message_bubble_received.9.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png
index 79e6e1fdf..fe0324cee 100644
--- a/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png
+++ b/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png
index 771c3ff43..fdb6be0d1 100644
--- a/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png
+++ b/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png
index 9e01ebaca..cb5654b71 100644
--- a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png
+++ b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/ic_launcher.png b/src/main/res/drawable-xxhdpi/ic_launcher.png
index e69b9c8d5..873d4b140 100644
--- a/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png
index 0af666695..10e784089 100644
--- a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png
+++ b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png
index e128d58a6..53ecbecf7 100644
--- a/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png
+++ b/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png
index 94baefed9..436a1bd32 100644
--- a/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png
+++ b/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png
index de4f8784b..f78425d21 100644
--- a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png
+++ b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_launcher.png b/src/main/res/drawable-xxxhdpi/ic_launcher.png
index 668504dfb..baadfa780 100644
--- a/src/main/res/drawable-xxxhdpi/ic_launcher.png
+++ b/src/main/res/drawable-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png
index 8a35671d4..c474359ea 100644
--- a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png
+++ b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png
index 2b4e08b2b..1421768cc 100644
--- a/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png
+++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png
index 6ea852cec..ee89b6706 100644
--- a/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png
+++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png
index 5cbfdbb4b..d34038d07 100644
--- a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png
+++ b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png
Binary files differ
diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml
index 3e8dbb1e6..35d9efbb3 100644
--- a/src/main/res/layout/activity_edit_account.xml
+++ b/src/main/res/layout/activity_edit_account.xml
@@ -177,6 +177,48 @@
</LinearLayout>
</RelativeLayout>
+ <RelativeLayout
+ android:id="@+id/battery_optimization"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/activity_vertical_margin"
+ android:layout_marginLeft="@dimen/activity_horizontal_margin"
+ android:layout_marginRight="@dimen/activity_horizontal_margin"
+ android:layout_marginTop="@dimen/activity_vertical_margin"
+ android:background="@drawable/infocard_border"
+ android:orientation="vertical"
+ android:padding="@dimen/infocard_padding"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/batt_op_headline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/battery_optimizations_enabled"
+ android:textColor="@color/black87"
+ android:textSize="?attr/TextSizeHeadline"
+ android:textStyle="bold"/>
+ <TextView
+ android:id="@+id/batt_op_body"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/batt_op_headline"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:text="@string/battery_optimizations_enabled_explained"
+ android:textColor="@color/black87"
+ android:textSize="?attr/TextSizeBody"/>
+ <Button
+ android:id="@+id/batt_op_disable"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_marginRight="-8dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true" android:layout_below="@+id/batt_op_body"
+ android:text="@string/disable" android:textColor="@color/accent"/>
+ </RelativeLayout>
+
<LinearLayout
android:id="@+id/stats"
android:layout_width="fill_parent"
@@ -205,7 +247,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_session_established"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/session_est"
@@ -235,7 +277,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_pep"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_pep"
@@ -256,7 +298,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_blocking"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_blocking"
@@ -277,7 +319,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_stream_management"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_sm"
@@ -298,7 +340,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_roster_version"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_roster_version"
@@ -319,7 +361,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_carbon_messages"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_carbons"
@@ -340,7 +382,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_mam"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_mam"
@@ -361,7 +403,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_csi"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_csi"
@@ -382,7 +424,7 @@
android:layout_height="wrap_content"
android:text="@string/server_info_http_upload"
android:textColor="@color/black87"
- android:textSize="?attr/TextSizeBody" />
+ android:textSize="?attr/TextSizeBody"/>
<TextView
android:id="@+id/server_info_http_upload"
@@ -416,13 +458,14 @@
android:textColor="@color/black87"
android:textSize="?attr/TextSizeBody"
android:typeface="monospace" />
-
+
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/otr_fingerprint"
android:textColor="@color/black54"
android:textSize="?attr/TextSizeInfo" />
+
</LinearLayout>
<ImageButton
@@ -487,7 +530,7 @@
android:visibility="visible" />
<ImageButton
- android:id="@+id/action_regenerate_omemo_key"
+ android:id="@+id/action_regenerate_axolotl_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
@@ -495,7 +538,6 @@
android:padding="@dimen/image_button_padding"
android:src="?attr/icon_refresh"
android:visibility="gone" />
-
</LinearLayout>
</RelativeLayout>
</LinearLayout>
@@ -528,7 +570,8 @@
android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal"
android:orientation="vertical"
- android:showDividers="middle"></LinearLayout>
+ android:showDividers="middle">
+ </LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
@@ -550,14 +593,14 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"
- android:textColor="@color/black87" />
+ android:textColor="@color/black87"/>
<View
android:layout_width="1dp"
android:layout_height="fill_parent"
android:layout_marginBottom="7dp"
android:layout_marginTop="7dp"
- android:background="@color/black12" />
+ android:background="@color/black12"/>
<Button
android:id="@+id/save_button"
@@ -567,7 +610,7 @@
android:layout_weight="1"
android:enabled="false"
android:text="@string/save"
- android:textColor="@color/black54" />
+ android:textColor="@color/black54"/>
</LinearLayout>
</RelativeLayout> \ No newline at end of file
diff --git a/src/main/res/layout/conversation_list_row.xml b/src/main/res/layout/conversation_list_row.xml
index 5d69f965a..124223c81 100644
--- a/src/main/res/layout/conversation_list_row.xml
+++ b/src/main/res/layout/conversation_list_row.xml
@@ -6,13 +6,13 @@
<View
android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_height="match_parent"
android:background="@color/primary"/>
<FrameLayout
android:id="@+id/swipeable_item"
android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_height="wrap_content"
android:background="@color/grey50">
<RelativeLayout
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 65036b972..64e345f08 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -9,7 +9,7 @@
<string name="action_secure">Verschlüsselte Unterhaltung</string>
<string name="action_add_account">Konto hinzufügen</string>
<string name="action_edit_contact">Namen bearbeiten</string>
- <string name="action_add_phone_book">Zum Telefonbuch hinzufügen</string>
+ <string name="action_add_phone_book">Zu Telefonbuch hinzufügen</string>
<string name="action_delete_contact">Aus Kontaktliste entfernen</string>
<string name="action_block_contact">Kontakt sperren</string>
<string name="action_unblock_contact">Kontakt entsperren</string>
@@ -108,8 +108,6 @@
<string name="pref_vibrate_summary">Vibrieren bei Erhalt einer neuen Nachricht</string>
<string name="pref_sound">Benachrichtigungston</string>
<string name="pref_sound_summary">Benachrichtigungston wiedergeben</string>
- <string name="pref_conference_notifications">Benachrichtigungen in öffentlichen Konferenzen</string>
- <string name="pref_conference_notifications_summary">Bei jeder Nachricht in öffentlichen Konferenzen benachrichtigen und nicht nur, wenn ich angesprochen werde</string>
<string name="pref_notification_grace_period">Gnadenfrist</string>
<string name="pref_notification_grace_period_summary">Deaktiviere Benachrichtigungen für eine kurze Zeit nach Erhalt einer Nachricht, die von einem anderen deiner Clients kommt.</string>
<string name="pref_advanced_options">Erweiterte Optionen</string>
@@ -174,7 +172,7 @@
<string name="passwords_do_not_match">Passwörter stimmen nicht überein</string>
<string name="invalid_jid">Ungültige Jabber-ID</string>
<string name="error_out_of_memory">Zu wenig Speicher vorhanden. Das Bild ist zu groß</string>
- <string name="add_phone_book_text">Möchtest du %s zum Telefonbuch hinzufügen?</string>
+ <string name="add_phone_book_text">%s zum Telefonbuch hinzufügen</string>
<string name="contact_status_online">online</string>
<string name="contact_status_free_to_chat">bereit</string>
<string name="contact_status_away">abwesend</string>
@@ -244,7 +242,7 @@
<string name="add_back">Auch hinzufügen</string>
<string name="contact_has_read_up_to_this_point">%s hat bis zu diesem Punkt gelesen</string>
<string name="publish">Veröffentlichen</string>
- <string name="touch_to_choose_picture">Avatar anklicken, um ein Bild aus der Galerie auszuwählen</string>
+ <string name="touch_to_choose_picture">Avatar antippen, um Bild aus Galerie auszuwählen</string>
<string name="publish_avatar_explanation">Achtung: Jeder, der deinen Status sehen darf, sieht auch deinen Avatar.</string>
<string name="publishing">Veröffentliche…</string>
<string name="error_publish_avatar_server_reject">Der Server hat die Veröffentlichung des Avatars abgelehnt.</string>
@@ -263,7 +261,6 @@
<string name="skip">Überspringen</string>
<string name="disable_notifications">Benachrichtigungen deaktivieren</string>
<string name="disable_notifications_for_this_conversation">Benachrichtigungen für diese Unterhaltung deaktivieren</string>
- <string name="notifications_disabled">Benachrichtigungen sind deaktiviert</string>
<string name="enable">Aktivieren</string>
<string name="conference_requires_password">Konferenz ist passwortgeschützt</string>
<string name="enter_password">Passwort eingeben</string>
@@ -322,7 +319,6 @@
<string name="verify_otr">OTR prüfen</string>
<string name="remote_fingerprint">Fingerabdruck der Gegenseite</string>
<string name="scan">Scannen</string>
- <string name="or_touch_phones">(oder Touch-Handys)</string>
<string name="smp">Socialist Millionaire Protocol</string>
<string name="shared_secret_hint">Hinweis oder Frage</string>
<string name="shared_secret_secret">Gemeinsamer Schlüssel</string>
@@ -509,7 +505,7 @@
<string name="pref_away_when_screen_off">Abwesend bei abgeschaltetem Bildschirm</string>
<string name="pref_away_when_screen_off_summary">Setzt deinen Status auf \"abwesend\", solange dein Bildschirm abgeschaltet ist</string>
<string name="pref_xa_on_silent_mode">Nicht verfügbar bei Stummschaltung</string>
- <string name="pref_xa_on_silent_mode_summary">Setzt deinen Status auf \"nicht verfügbar\", solange dein Gerät stummgeschaltet ist</string>
+ <string name="pref_xa_on_silent_mode_summary">Setzt deinen Status auf \"nicht verfügbar\", solange dein Telefon lautlos ist</string>
<string name="action_add_account_with_certificate">Konto mit Zertifikat hinzufügen</string>
<string name="unable_to_parse_certificate">Zertifikat kann nicht gelesen werden</string>
<string name="authenticate_with_certificate">Leer lassen, um mit Zertifikat anzumelden</string>
@@ -536,7 +532,7 @@
<string name="send_omemo_x509_message">v\\OMEMO-verschlüsselte Nachricht senden</string>
<string name="verified_omemo_key_with_certificate">OMEMO Schlüssel mit Zertifikat bestätigt!</string>
<string name="pref_connection_options">Verbindungs-Optionen</string>
- <string name="pref_use_tor">Mit TOR verbinden</string>
+ <string name="pref_use_tor">Über TOR verbinden</string>
<string name="pref_use_tor_summary">Alle Verbindungen über das TOR-Netzwerk tunneln. Benötigt Orbot</string>
<string name="account_settings_hostname">Hostname</string>
<string name="account_settings_port">Port</string>
@@ -552,21 +548,25 @@
<string name="shared_image_with_x">Bild mit %s geteilt</string>
<string name="no_storage_permission">Pix-Art Messenger benötigt Zugriff auf externen Speicher</string>
<string name="sync_with_contacts">Mit Kontakten synchronisieren</string>
- <string name="sync_with_contacts_long">Pix-Art Messenger möchte deine Chat-Kontaktliste mit deinem Telefon-Kontakten abgleichen, um vollständige Namen und Avatare anzuzeigen.\n\nPix-Art Messenger wird deine Kontakte nur lokal lesen und abgleichen und benötigt keinen Abgleich mit dem Server.\n\nDu wirst gefragt, ob du den Zugriff auf deine Kontakte erlauben möchtest.</string>
- <string name="always">Immer</string>
- <string name="automatically">Automatisch</string>
- <string name="certicate_info_not_available">(nicht verfügbar)</string>
- <string name="certificate_cn">Gemeinsamer Name</string>
+ <string name="sync_with_contacts_long">Pix-Art Messenger möchte deine XMPP-Kontaktliste mit deinen Kontakten abgleichen, um deren vollständige Namen und Avatare anzuzeigen.\n\nConversations wird deine Kontakte nur lokal lesen und abgleichen und überträgt diese nicht auf den Server.\n\nDu wirst nun gefragt, ob du den Zugriff auf deine Kontakte erlauben möchtest.</string>
+ <string name="certificate_information">Zertifikatinformationen</string>
<string name="certificate_subject">Betreff</string>
- <string name="certificate_sha1"></string>
+ <string name="certificate_issuer">Aussteller</string>
+ <string name="certificate_cn">Gemeinsamer Name</string>
<string name="certificate_o">Organisation</string>
+ <string name="certificate_sha1">SHA1</string>
+ <string name="certicate_info_not_available">(Nicht verfügbar)</string>
<string name="certificate_not_found">Kein Zertifikat gefunden</string>
- <string name="certificate_issuer">Aussteller</string>
- <string name="certificate_information">Zertifikat-Information</string>
- <string name="notify_never">Benachrichtigungen deaktivierten</string>
<string name="notify_on_all_messages">Bei allen Nachrichten benachrichtigen</string>
<string name="notify_only_when_highlighted">Nur benachrichtigen, wenn ich angesprochen werde</string>
+ <string name="notify_never">Benachrichtigungen deaktiviert</string>
<string name="notify_paused">Benachrichtigungen pausiert</string>
<string name="pref_picture_compression">Bilder komprimieren</string>
- <string name="pref_picture_compression_summary">Bildgröße ändern und komprimieren</string>
+ <string name="pref_picture_compression_summary">Bildgröße anpassen und komprimieren</string>
+ <string name="always">Immer</string>
+ <string name="automatically">Automatisch</string>
+ <string name="battery_optimizations_enabled">Batterieoptimierung aktiv</string>
+ <string name="battery_optimizations_enabled_explained">Dein Telefon wendet Batterioptimierungen bei Conversations an, welche verspätete Benachrichtigungen oder Nachrichtenverlust verursachen können.\nEs ist empfehlenswert diese zu deaktivieren.</string>
+ <string name="battery_optimizations_enabled_dialog">Dein Telefon wendet Batterioptimierungen bei Conversations an, welche verspätete Benachrichtigungen oder Nachrichtenverlust verursachen können. Es ist empfehlenswert dies zu deaktivieren.</string>
+ <string name="disable">Deaktivieren</string>
</resources>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index ab969324b..ceddf390f 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -11,7 +11,7 @@
<string name="action_secure">Secure conversation</string>
<string name="action_add_account">Add account</string>
<string name="action_edit_contact">Edit name</string>
- <string name="action_add_phone_book">Add to phone book</string>
+ <string name="action_add_phone_book">Add to address book</string>
<string name="action_delete_contact">Delete from roster</string>
<string name="action_block_contact">Block contact</string>
<string name="action_unblock_contact">Unblock contact</string>
@@ -175,7 +175,7 @@
<string name="passwords_do_not_match">Passwords do not match</string>
<string name="invalid_jid">This is not a valid Jabber ID</string>
<string name="error_out_of_memory">Out of memory. Image is too large</string>
- <string name="add_phone_book_text">Do you want to add %s to your devices’s contact list?</string>
+ <string name="add_phone_book_text">Do you want to add %s to your address book?</string>
<string name="contact_status_online">online</string>
<string name="contact_status_free_to_chat">free to chat</string>
<string name="contact_status_away">away</string>
@@ -356,7 +356,6 @@
<string name="verify_otr">Verify OTR</string>
<string name="remote_fingerprint">Remote Fingerprint</string>
<string name="scan">scan</string>
- <string name="or_touch_phones">(or touch phones)</string>
<string name="smp">Socialist Millionaire Protocol</string>
<string name="shared_secret_hint">Hint or Question</string>
<string name="shared_secret_secret">Shared Secret</string>
@@ -410,6 +409,7 @@
<string name="purge_key">Purge key</string>
<string name="purge_key_desc_part1">Are you sure you want to purge this key?</string>
<string name="purge_key_desc_part2">It will irreversibly be considered compromised, and you can never build a session with it again.</string>
+ <string name="error_no_keys_to_trust_server_error">There are no usable keys available for this contact.\nFetching new keys from the server has been unsuccessful. Maybe there is something wrong with your contacts server.</string>
<string name="error_no_keys_to_trust">There are no usable keys available for this contact. If you have purged any of their keys, they need to generate new ones.</string>
<string name="error_trustkeys_title">Error</string>
<string name="fetching_history_from_server">Fetching history from server</string>
@@ -525,7 +525,6 @@
<string name="elv_undo">undo</string>
<string name="pref_use_white_background">Use white background</string>
<string name="pref_use_white_background_summary">Show received messages as black text on a white background</string>
- <string name="account_status_dns_timeout">Timeout in DNS</string>
<string name="action_check_update">Check for Updates</string>
<string name="title_activity_updater">Update Service</string>
<string name="update_available">Pix-Art Messenger %1$s with the following changes is available:\n\n%2$s\n\nUpdate Pix-Art Messenger %3$s to Pix-Art Messenger %1$s now?</string>
@@ -536,14 +535,14 @@
<string name="current_version">installed version:</string>
<string name="no_update_available">No update available</string>
<string name="download_started">Download started</string>
- <string name="account_status_tor_unavailable">TOR network unavailable</string>
+ <string name="account_status_tor_unavailable">Tor network unavailable</string>
<string name="server_info_broken">Broken</string>
<string name="pref_presence_settings">Presence settings</string>
<string name="pref_away_when_screen_off">Away when screen is off</string>
<string name="pref_away_when_screen_off_summary">Marks your resource as away when the screen is turned off</string>
<string name="pref_xa_on_silent_mode">Not available in silent mode</string>
- <string name="pref_xa_on_silent_mode_summary">Marks your resource as not available when phone is in silent mode</string>
<string name="update_info">Pix-Art Messenger is checking for an update. If an update is available you will be asked, if you want to update your version. The update process is downloading and installing the new version automatically.</string>
+ <string name="pref_xa_on_silent_mode_summary">Marks your resource as not available when device is in silent mode</string>
<string name="action_add_account_with_certificate">Add account with certificate</string>
<string name="unable_to_parse_certificate">Unable to parse certificate</string>
<string name="authenticate_with_certificate">Leave empty to authenticate w/ certificate</string>
@@ -562,8 +561,8 @@
<string name="pref_plugin_location">Share-Location</string>
<string name="pref_plugin_location_summary">Send and receive locations</string>
<string name="pref_connection_options">Connection options</string>
- <string name="pref_use_tor">Connect via TOR</string>
- <string name="pref_use_tor_summary">Tunnel all connections through the TOR network. Requires Orbot</string>
+ <string name="pref_use_tor">Connect via Tor</string>
+ <string name="pref_use_tor_summary">Tunnel all connections through the Tor network. Requires Orbot</string>
<string name="account_settings_hostname">Hostname</string>
<string name="account_settings_port">Port</string>
<string name="hostname_or_onion">Server- or .onion-Address</string>
@@ -595,4 +594,8 @@
<string name="pref_picture_compression_summary">Resize and compressed pictures</string>
<string name="always">Always</string>
<string name="automatically">Automatically</string>
+ <string name="battery_optimizations_enabled">Battery optimizations enabled</string>
+ <string name="battery_optimizations_enabled_explained">Your device is doing some heavy battery optimizations on Conversations that might lead to delayed notifications or even message loss.\nIt is recommended to disable those.</string>
+ <string name="battery_optimizations_enabled_dialog">Your device is doing some heavy battery optimizations on Conversations that might lead to delayed notifications or even message loss.\n\nYou will now be asked to disable those.</string>
+ <string name="disable">Disable</string>
</resources>