Merge branch 'siacs/master' into development
|
@ -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
|
||||
|
|
|
@ -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,29 +11,122 @@
|
|||
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>
|
||||
<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="radialGradient3883"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
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="linearGradient3913">
|
||||
|
@ -45,263 +139,128 @@
|
|||
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" />
|
||||
<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
|
||||
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>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4098">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4100" />
|
||||
<stop
|
||||
style="stop-color:#e6e6e6;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4102" />
|
||||
</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)" />
|
||||
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
|
||||
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)" />
|
||||
<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" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsssscc"
|
||||
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" />
|
||||
<path
|
||||
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" />
|
||||
<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="layer4"
|
||||
inkscape:label="Dots">
|
||||
id="layer8"
|
||||
inkscape:label="dotted line"
|
||||
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"
|
||||
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)" />
|
||||
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
|
||||
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)" />
|
||||
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
|
||||
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="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
|
||||
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"
|
||||
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"
|
||||
sodipodi:nodetypes="cssccc"
|
||||
transform="translate(4.9999996,-1.9374999)" />
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
inkscape:label="dots"
|
||||
id="layer2"
|
||||
inkscape:groupmode="layer"
|
||||
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
|
||||
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>
|
||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 25 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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>());
|
||||
}
|
||||
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>());
|
||||
}
|
||||
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);
|
||||
String qname = "_xmpp-client._tcp." + host;
|
||||
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);
|
||||
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<>();
|
||||
final Map<Integer, List<TlsSrv>> priorities = new TreeMap<>();
|
||||
final Map<String, List<String>> ips4 = new TreeMap<>();
|
||||
final Map<String, List<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);
|
||||
}
|
||||
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());
|
||||
}
|
||||
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() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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...
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()]);
|
||||
SSLSocketHelper.setSecurity(sslSocket);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 765 B After Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 757 B |
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 779 B |
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 687 B |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 594 B |
Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 598 B |
Before Width: | Height: | Size: 610 B After Width: | Height: | Size: 610 B |
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 558 B |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 929 B After Width: | Height: | Size: 929 B |
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 921 B |
Before Width: | Height: | Size: 935 B After Width: | Height: | Size: 935 B |
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 857 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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_o">Organisation</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="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="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>
|
||||
|
|
|
@ -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>
|
||||
|
|