commit d37a8465d1c8010d3d04200527f800184e1e8141 parent 845eac7af65727b84ae3a37ea7fbe651a8e2c22e Author: Nick Econopouly <wry@mm.st> Date: Sat, 20 Feb 2021 14:36:56 -0500 wiki: add a bunch of media from the former uploads dir Diffstat:
47 files changed, 2128 insertions(+), 0 deletions(-)
diff --git a/build-instructions/android.md b/build-instructions/android.md @@ -0,0 +1,144 @@ +# Building Jami on Android + ++ Please make sure Android SDK and NDK are installed, and their paths +are properly set. If you need more information, please visit +<https://github.com/savoirfairelinux/ring-client-android> ++ These instructions are for Ubuntu, check equivalent if you use a different distribution + +## Prepare environment + +- Install Java JDK 7 or 8 (Oracle or OpenJDK) + +<http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html> + +```bash +sudo apt install openjdk +``` + +<!-- --> + +- Install Android Studio: + <https://developer.android.com/studio/index.html> + + You can install all dependecies like ndk (side by side), lldb with android-studio in settings > appearance & behavior > system settings > android sdk > sdk tools + +<!-- --> + +- Install the Android NDK: + <https://developer.android.com/ndk/downloads/index.html> + +<!-- --> + +- Install required tools + +<!-- --> + +```bash +sudo apt install autoconf automake libtool autopoint swig python +``` + +Add these variables to your bash profile: + +```bash +export JAVA_HOME=<path_to_java_JDK> +export ANDROID_HOME=<path_to_root_folder_sdk> +export ANDROID_SDK=$ANDROID_HOME +export ANDROID_NDK=<path_to_root_folder_ndk> +export ANDROID_NDK_ROOT=$ANDROID_NDK +export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_NDK:$JAVA_HOME/bin +``` + +ie for Ubuntu : + +```bash +export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/ +export ANDROID_HOME=/home/{username}/Android/Sdk +export ANDROID_SDK=/home/{username}/Android/Sdk +export ANDROID_NDK_ROOT=/home/{username}/Android/Sdk/ndk-bundle/ +export ANDROID_NDK=/home/{username}/Android/Sdk/ndk-bundle/ +export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_NDK:$JAVA_HOME/bin +``` + +## Build and install locally + +- Clone whole project repository + +<!-- --> + +```bash +git clone --recurse-submodules https://review.jami.net/ring-project +``` + +- Initialize project + +<!-- --> +```bash +cd ring-project +./make-ring.py --init --distribution=Android +``` + + +- Compile + +<!-- --> + +```bash +ANDROID_ABI="armeabi-v7a arm64-v8a" ./make-ring.py --install --distribution=Android +``` + +**Output**: You can find the *.apk* file in the +*./client-android/ring-android/app/build/outputs* folder. + +**Errors** +- ```configure: error: source directory already configured; run "make distclean" there first``` + + It means you build for another distro like x86_64-pc-linux-gnu and builds are conflicting. The simpliest solution is to make another ring-project only for Android to avoid this conflict. + +## Troubleshooting + +- Check case in your sdk path. Since api 26, + /home/user/Android/**s**dk have become /home/user/Android/**S**dk + +<!-- --> + +- You can check each path with *echo*. e.g : echo $JAVA\_HOME + +<!-- --> + +- `sudo` will use root's bash profile. And you don't need it. + +<!-- --> + +- If build fails, you can try to clean contribs with: + +```bash +cd ring-project/ && git clean -xdf +cd ../daemon && git clean -xdf +``` + +- Makeinfo issue + makeinfo: command not found + WARNING: 'makeinfo' is missing on your system. + **Solution**: Install texinfo package containing makeinfo dep. + +<!-- --> + +- Unable to locate tools.jar + **Solution**: Your java installation is not pointing to a JDK. + Install one, or make JAVA_HOME point to it. + +<!-- --> + +- When building the apk error in build-tools + error while loading shared libraries: libstdc++.so.6 + **Solution**: Install lib32stdc++6 lib32z1-dev + +<!-- --> + +- When compiling on Fedora + error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory + **Solution***: sudo dnf install ncurses-compat-libs + +<!-- --> + +- When building, you may get a Gradle error. You should install Gradle 5.4.1 by running apt-get install or installing directly on android-studio. diff --git a/build-instructions/build-method.md b/build-instructions/build-method.md @@ -0,0 +1,6 @@ +# Which Build Method to Use + +The following flow chart should help you decide whether to build from +the [master repository](https://git.jami.net/savoirfairelinux/ring-project) or not: + +![flowchart](build_method_flowchart.png) diff --git a/build-instructions/build_method_flowchart.png b/build-instructions/build_method_flowchart.png Binary files differ. diff --git a/build-instructions/build_method_flowchart.svg b/build-instructions/build_method_flowchart.svg @@ -0,0 +1,357 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + 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#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07, custom)" + sodipodi:docname="build_method_flowchart.svg"> + <defs + id="defs2"> + <linearGradient + id="d" + x1="98" + x2="98" + y1="98" + y2="195.5" + gradientUnits="userSpaceOnUse"> + <stop + stop-color="#fff" + offset="0" + id="stop1106" /> + <stop + stop-color="#E9E5E5" + offset="1" + id="stop1108" /> + </linearGradient> + <linearGradient + id="c" + x1="104.61061" + x2="104.61061" + y2="37.039019" + gradientTransform="scale(0.29208988,3.4236038)" + y1="15.961631" + gradientUnits="userSpaceOnUse"> + <stop + stop-color="#0339F1" + offset="0" + id="stop1111" /> + <stop + stop-color="#01ADE5" + offset="1" + id="stop1113" /> + </linearGradient> + <linearGradient + id="b" + x1="54.804602" + x2="101.43272" + y1="58.307517" + y2="109.79727" + gradientTransform="scale(0.93053152,1.0746546)" + gradientUnits="userSpaceOnUse"> + <stop + stop-color="#0756EE" + offset="0" + id="stop1116" /> + <stop + stop-color="#00A3F5" + offset=".37448" + id="stop1118" /> + <stop + stop-color="#18B5B6" + offset=".71708" + id="stop1120" /> + <stop + stop-color="#80DF43" + offset="1" + id="stop1122" /> + </linearGradient> + <linearGradient + id="a" + x1="149.64282" + x2="201.0253" + y1="47.501322" + y2="108.70309" + gradientTransform="scale(0.82995643,1.2048825)" + gradientUnits="userSpaceOnUse"> + <stop + stop-color="#20BBA6" + offset="0" + id="stop1125" /> + <stop + stop-color="#9BEC23" + offset=".4988" + id="stop1127" /> + <stop + stop-color="#D9EF35" + offset="1" + id="stop1129" /> + </linearGradient> + <style + id="style1261">.a{fill:#3ddc84;}</style> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="4.7813953" + inkscape:cx="671.14859" + inkscape:cy="218.51491" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="948" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="91.655647" + y="74.477058" + id="text837-3-9"><tspan + sodipodi:role="line" + id="tspan835-5-1" + x="91.655647" + y="74.477058" + style="font-size:8.46667px;fill:#000000;fill-opacity:1;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none">iOS</tspan></text> + <path + d="m 88.811308,74.747456 c -0.35773,0.347169 -0.75242,0.293048 -1.12863,0.129361 -0.39997,-0.166985 -0.76562,-0.177543 -1.18803,0 -0.52603,0.227049 -0.80522,0.161047 -1.12203,-0.129361 -1.78864,-1.841447 -1.52464,-4.64652 0.50822,-4.752123 0.49303,0.0264 0.83822,0.272588 1.12863,0.293047 0.43165,-0.08778 0.84482,-0.339249 1.30683,-0.306246 0.55508,0.04488 0.97023,0.264005 1.24743,0.658034 -1.14183,0.686422 -0.87122,2.191261 0.17755,2.613668 -0.20989,0.551114 -0.47917,1.09563 -0.93063,1.498242 z m -1.84144,-4.771923 c -0.0535,-0.818422 0.60985,-1.491642 1.37283,-1.55764 0.10494,0.943822 -0.85802,1.650044 -1.37283,1.55764 z" + id="path1015-2" + style="stroke-width:0.00660015" /> + <rect + style="opacity:0.9985;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect833" + width="103.12037" + height="24.286444" + x="44.704578" + y="169.61264" + ry="5.8318963" /> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="63.574253" + y="183.79192" + id="text837"><tspan + sodipodi:role="line" + id="tspan835" + x="63.574253" + y="183.79192" + style="font-size:8.46667px;fill:#000000;fill-opacity:1;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none">use the master repo</tspan></text> + <rect + style="opacity:0.9985;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.799999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect833-3" + width="137.79369" + height="24.286438" + x="171.94162" + y="168.47379" + ry="5.8318963" /> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="181.95418" + y="182.64066" + id="text837-6"><tspan + sodipodi:role="line" + id="tspan835-7" + x="181.95418" + y="182.64066" + style="font-size:8.46667px;fill:#000000;fill-opacity:1;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none">build each component individually</tspan></text> + <rect + style="opacity:0.9985;fill:#4fff65;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.251655;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect860" + width="58.90266" + height="58.90266" + x="50.184956" + y="-99.792046" + ry="7.3381104" + transform="rotate(45)" /> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="75.378746" + y="8.4622536" + id="text864"><tspan + sodipodi:role="line" + id="tspan862" + x="75.378746" + y="8.4622536" + style="fill:#000000;fill-opacity:1;stroke-width:0.2">operating system?</tspan></text> + <rect + style="opacity:0.9985;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.799999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect833-5" + width="48.645531" + height="24.286442" + x="-6.172801" + y="55.844456" + ry="5.8318963" /> + <g + fill-rule="evenodd" + id="g1142" + transform="matrix(0.1378673,0,0,0.1378673,7.3438664,-19.682064)"> + <rect + x="1" + y="1" + width="194" + height="194" + rx="45" + fill="url(#d)" + stroke="#d9d9d9" + id="rect1134" + style="fill:url(#d)" /> + <path + d="M 32.882,137.54 H 28.3187 V 76.561 H 32.882 Z M 30.5354,61.613 c -1.9244,0 -3.5158,-1.5265 -3.5158,-3.4509 0,-1.9812 1.5833,-3.5158 3.5158,-3.5158 1.9812,0 3.5564,1.5265 3.5564,3.5158 0,1.9244 -1.5752,3.4509 -3.5564,3.4509 z" + fill="url(#c)" + id="path1136" + style="fill:url(#c)" /> + <path + d="m 77.205,138.73 c -22.313,0 -36.409,-16.248 -36.409,-42.076 0,-25.699 14.161,-42.011 36.409,-42.011 22.248,0 36.401,16.313 36.401,42.011 0,25.829 -14.096,42.076 -36.401,42.076 z m 0,-79.89 c -19.422,0 -31.821,14.664 -31.821,37.813 0,23.166 12.456,37.887 31.821,37.887 19.422,0 31.821,-14.721 31.821,-37.887 0,-23.157 -12.399,-37.813 -31.821,-37.813 z" + fill="url(#b)" + id="path1138" + style="fill:url(#b)" /> + <path + d="m 146.1,138.73 c -16.751,0 -28.76,-9.4595 -29.442,-22.987 h 4.474 c 0.68206,11.092 11.1,18.854 25.309,18.854 13.868,0 23.547,-7.8761 23.547,-18.513 0,-8.5582 -5.7731,-13.479 -19.471,-16.93 l -9.6787,-2.3791 c -15.111,-3.8569 -21.972,-9.971 -21.972,-20.21 0,-12.74 11.895,-21.915 26.787,-21.915 15.395,0 26.892,9.0616 27.404,21.063 h -4.474 c -0.62522,-9.7924 -10.19,-16.93 -23.044,-16.93 -12.293,0 -22.086,7.3646 -22.086,17.668 0,8.1603 6.0005,12.854 19.13,16.134 l 9.1184,2.3222 c 15.793,3.9056 22.873,9.971 22.873,20.835 0,13.527 -11.376,22.987 -28.476,22.987 z" + fill="url(#a)" + id="path1140" + style="fill:url(#a)" /> + </g> + <g + id="g1173" + transform="translate(2.8161789,1.0302956)"> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="12.696874" + y="69.718971" + id="text837-3"><tspan + sodipodi:role="line" + id="tspan835-5" + x="12.696874" + y="69.718971" + style="font-size:8.46667px;fill:#000000;fill-opacity:1;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none">iOS</tspan></text> + <path + d="m 9.8525369,69.98937 c -0.35773,0.347169 -0.75242,0.293048 -1.12863,0.129361 -0.39997,-0.166985 -0.76562,-0.177543 -1.18803,0 -0.52603,0.227049 -0.80522,0.161047 -1.12203,-0.129361 -1.78864,-1.841447 -1.52464,-4.64652 0.50822,-4.752123 0.49303,0.0264 0.83822,0.272588 1.12863,0.293047 0.43165,-0.08778 0.84482,-0.339249 1.30683,-0.306246 0.55508,0.04488 0.9702301,0.264005 1.2474301,0.658034 -1.1418301,0.686422 -0.8712201,2.191261 0.17755,2.613668 -0.20989,0.551114 -0.47917,1.09563 -0.9306301,1.498242 z m -1.84144,-4.771923 c -0.0535,-0.818422 0.60985,-1.491642 1.37283,-1.55764 0.10494,0.943822 -0.85802,1.650044 -1.37283,1.55764 z" + id="path1015" + style="stroke-width:0.00660015" /> + </g> + <rect + style="opacity:0.9985;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.799999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect833-5-6" + width="54.545307" + height="24.286442" + x="69.969788" + y="59.572247" + ry="5.8318963" /> + <g + id="g1287" + transform="translate(3.3476053,1.4689065)"> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="86.361671" + y="73.323875" + id="text1207"><tspan + sodipodi:role="line" + id="tspan1205" + x="86.361671" + y="73.323875" + style="stroke-width:0.2">Android</tspan></text> + <path + class="a" + d="m 81.502531,71.764169 a 0.47431654,0.47431654 0 1 1 0.474318,-0.474316 0.47431654,0.47431654 0 0 1 -0.474318,0.474316 m -5.222422,0 a 0.47431654,0.47431654 0 1 1 0.474317,-0.474316 0.47431654,0.47431654 0 0 1 -0.474317,0.474316 m 5.390409,-2.845897 0.948633,-1.635404 a 0.1958038,0.1958038 0 1 0 -0.340914,-0.192692 l -0.958516,1.655166 a 5.7895274,5.7895274 0 0 0 -2.425929,-0.523723 5.8870589,5.8870589 0 0 0 -2.430873,0.518785 l -0.958515,-1.655169 a 0.1958038,0.1958038 0 0 0 -0.340915,0.192692 l 0.943693,1.635404 a 5.5883876,5.5883876 0 0 0 -2.895307,4.46648 h 11.34901 a 5.5598792,5.5598792 0 0 0 -2.890367,-4.461539" + id="path1269" + style="fill:#000000;fill-opacity:1;stroke-width:0.049408" /> + </g> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="169.70874" + y="68.81044" + id="text837-3-9-7"><tspan + sodipodi:role="line" + id="tspan835-5-1-0" + x="169.70874" + y="68.81044" + style="font-size:8.46667px;fill:#000000;fill-opacity:1;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none">iOS</tspan></text> + <path + d="m 166.8644,69.080841 c -0.35773,0.347169 -0.75242,0.293048 -1.12863,0.129361 -0.39997,-0.166985 -0.76562,-0.177543 -1.18803,0 -0.52603,0.227049 -0.80522,0.161047 -1.12203,-0.129361 -1.78864,-1.841447 -1.52464,-4.64652 0.50822,-4.752123 0.49303,0.0264 0.83822,0.272588 1.12863,0.293047 0.43165,-0.08778 0.84482,-0.339249 1.30683,-0.306246 0.55508,0.04488 0.97023,0.264005 1.24743,0.658034 -1.14183,0.686422 -0.87122,2.191261 0.17755,2.613668 -0.20989,0.551114 -0.47917,1.09563 -0.93063,1.498242 z m -1.84144,-4.771923 c -0.0535,-0.818422 0.60985,-1.491642 1.37283,-1.55764 0.10494,0.943822 -0.85802,1.650044 -1.37283,1.55764 z" + id="path1015-2-9" + style="stroke-width:0.00660014" /> + <rect + style="opacity:0.9985;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.799999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + id="rect833-5-6-3" + width="54.545307" + height="24.286442" + x="148.02287" + y="53.905632" + ry="5.8318963" /> + <g + id="g1430" + transform="translate(-3.3875782,1.9324472)"> + <text + xml:space="preserve" + style="font-size:8.46667px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, ';opacity:0.9985;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.887308;stop-color:#000000" + x="166.99396" + y="66.989616" + id="text1327"><tspan + sodipodi:role="line" + id="tspan1325" + x="166.99396" + y="66.989616" + style="stroke-width:0.2">Windows</tspan></text> + <g + id="g1421" + transform="matrix(0.19671048,0,0,0.19671048,144.84878,52.74351)"> + <path + fill="#f25022" + d="M 69.216352,40.749778 H 85.43531 V 56.968736 H 69.216352 Z" + id="path1389" + style="fill:#000000;fill-opacity:1;stroke-width:0.264583" /> + <path + fill="#7fba00" + d="M 87.128643,40.749778 H 103.3476 V 56.968736 H 87.128643 Z" + id="path1391" + style="fill:#000000;fill-opacity:1;stroke-width:0.264583" /> + <path + fill="#00a4ef" + d="M 69.216352,58.662069 H 85.43531 V 74.881028 H 69.216352 Z" + id="path1393" + style="fill:#000000;fill-opacity:1;stroke-width:0.264583" /> + <path + fill="#ffb900" + d="M 87.128643,58.662069 H 103.3476 V 74.881028 H 87.128643 Z" + id="path1395" + style="fill:#000000;fill-opacity:1;stroke-width:0.264583" /> + </g> + </g> + </g> +</svg> diff --git a/build-instructions/building-individually.md b/build-instructions/building-individually.md @@ -0,0 +1,14 @@ +# Building Components Individually + +If you are building each component individually, simply ``git clone`` +each repository and follow the instructions in its README. Do it in +the following order: + + * [jami-daemon](https://git.jami.net/savoirfairelinux/ring-daemon) + * [libjamiclient](https://git.jami.net/savoirfairelinux/ring-lrc) (not used on Android) + * A client from <https://git.jami.net/savoirfairelinux>, such as the + [QT](https://git.jami.net/savoirfairelinux/jami-client-qt), + [GNOME](https://git.jami.net/savoirfairelinux/ring-client-gnome), + or + [macOS](https://git.jami.net/savoirfairelinux/ring-client-macosx) + clients. diff --git a/build-instructions/index.rst b/build-instructions/index.rst @@ -0,0 +1,37 @@ +################### +Build Instructions +################### + +A working Jami setup consists of three ingredients: + + * `jami-daemon <https://git.jami.net/savoirfairelinux/ring-daemon>`_, the core program, + * optionally, `libjamiclient + <https://git.jami.net/savoirfairelinux/ring-lrc>`_, a library used + by some of the clients + * A client, such as `the QT client + <https://git.jami.net/savoirfairelinux/jami-client-qt>`_ which + provides the user interface + + +There are two ways to build Jami: + + 1. Build each part individually. They must be built in the order given above. + 2. Build Jami using the `master repository + <https://git.jami.net/savoirfairelinux/ring-project>`_, which + provides a script to build all of the components at once. This + is easier for most people. + +Whichever method you choose, you should follow the build instructions +in the README or INSTALL file of your chosen repository. + +.. toctree:: + :maxdepth: 1 + + build-method + master-repository + building-individually + windows + linux + macos + android + ios diff --git a/build-instructions/ios.md b/build-instructions/ios.md @@ -0,0 +1,24 @@ +# Building Jami for iOS + +After installing [Brew](https://brew.sh) and Python3 (brew install +python3): + +```bash +git clone https://review.jami.net/ring-project +cd ring-project +./make-ring.py --init +./make-ring.py --dependencies --distribution iOS +./make-ring.py --install --distribution iOS +cd client-ios/Ring && ./fetch-dependencies.sh && cd .. +xcodebuild build -project Ring/Ring.xcodeproj/ -configuration "Release" -arch "x86_64" -destination "platform=iOS Simulator,name=iPhone $DATE,OS=11" -sdk iphonesimulator11.0 VALID_ARCHS="x86_64" + + +``` +it could be useful to do this if an error occurs: +```bash +ln -s /usr/local/opt/gettext/bin/autopoint /usr/local/bin +``` +if you get build errors linked to swift, you should upgrade swiftgen: +```bash +brew upgrade swiftgen +``` diff --git a/build-instructions/linux.rst b/build-instructions/linux.rst @@ -0,0 +1,63 @@ +Building Jami on Linux +====================== + +Simply follow the instructions in the README of the `master +repository <https://git.jami.net/savoirfairelinux/ring-project>`__. + +Alternatively, follow the build instructions for :doc:`each individual +component <building-individually>` if you choose to build them +separately. + +Dependencies +------------ + +Jami-daemon provides some dependencies in its ``contrib`` directory, +along with instructions for compiling them. However, some dependencies +should be installed with your package manager. + +Fedora +~~~~~~ + +.. code:: bash + + sudo yum groupinstall group "Development Tools" "Development Libraries" + sudo yum install gcc-c++ yasm intltool libyaml-devel alsa-lib-devel pulseaudio-libs-devel libsamplerate-devel dbus-c++-devel pcre-devel gsm-devel speex-devel speexdsp-devel expat-devel qttools5-dev libsndfile-devel gnutls-devel gettext-devel cmake libtool systemd-devel uuid-devel libXfixes-devel jsoncpp-devel autoconf-archive qt5-qtbase-devel qt5-qttools-devel + +For video support, you’ll also need ffmpeg, which is only available in +the RPMfusion repository as described here +http://rpmfusion.org/Configuration + +Then install ffmpeg: + +.. code:: bash + + sudo yum install ffmpeg-devel + +To build and run the tests with make check, you’ll also need + +.. code:: bash + + sudo yum install cppunit-devel cppcheck sipp dbus + +Debian-based +~~~~~~~~~~~~ + +Building dependencies/instructions for Debian, Ubuntu, Crunchbang Linux, +etc. + +.. code:: bash + + sudo apt-get install autoconf autoconf-archive automake autopoint cmake libpulse-dev libsamplerate0-dev libgsm1-dev libspeex-dev libtool libdbus-1-dev libasound2-dev libopus-dev libspeexdsp-dev libexpat1-dev libpcre3-dev libyaml-cpp-dev libboost-dev libdbus-c++-dev qttools5-dev libsndfile1-dev libsrtp-dev libjack-dev libupnp-dev libavcodec-dev libavformat-dev libswscale-dev libavdevice-dev libudev-dev yasm uuid-dev libgnutls28-dev libjsoncpp-dev libvdpau-dev libva-dev qtbase5-dev qttools5-dev and qttools5-dev-tools + +If you want to run tests (e.g. when setting up a new VM on Jenkins), you +must install cppunit and sipp + +.. code:: bash + + sudo apt-get install libcppunit-dev sip-tester dbus + +For H.264 support, you’ll need + +.. code:: bash + + sudo apt-get install libavcodec-extra-* diff --git a/build-instructions/macos.md b/build-instructions/macos.md @@ -0,0 +1,4 @@ +# Building Jami on macOS + +Simply follow the instructions in the README of the [master +repository](https://git.jami.net/savoirfairelinux/ring-project#on-osx). diff --git a/build-instructions/master-repository.md b/build-instructions/master-repository.md @@ -0,0 +1,23 @@ +# Using the Master Repository + +You must first install [Git](https://git-scm.com/). + +Run the following command to download the project: + +```bash +$ git clone https://review.jami.net/ring-project +``` + +Then follow the instructions in the +[README](https://git.jami.net/savoirfairelinux/ring-project). + +## Updating your copy + + +Due to high activity on the other projects, the Git submodules may need to +be manually updated next time you rebuild everything: + +``` +$ cd ring-project +$ git submodule update --init daemon lrc client-gnome +``` diff --git a/build-instructions/windows.md b/build-instructions/windows.md @@ -0,0 +1,4 @@ +# Building Jami on Windows + +Follow the instructions in the QT client's +[repository](https://git.jami.net/savoirfairelinux/jami-client-qt#building-on-native-windows). diff --git a/extra/SmokeTestsJami.ods b/extra/SmokeTestsJami.ods Binary files differ. diff --git a/extra/libjamiclient-documentation.md b/extra/libjamiclient-documentation.md @@ -0,0 +1,57 @@ +# LRC documentation + +NOTE: Had to delete a lot of image links that were broken, so this +page is pretty useless right now. + +*This page is a stub.* + +### Introduction + +- Lrc (Libringclient) is an interface between the clients and + the daemon. It ensures to get the same behaviour for all client + using it. + +note: red = missing feature. + +### DatabaseManager + +- this class is an interface between lrc and the sqlite database. This + class should not be called directly from the client. + +### NewCallModel class and NewCall namespace + +- NewCallModel is an interface used to manage the calls. + + +- When we need information about calls, members functions from the + model can return NewCall::Info. + + +- When we need to perform some operation on a call, we pass it callId + to the delegate performing the operation. + + +- note about the name : we are using New as prefix to avoid conflict + with the current CallModel and Call objects. + +### ContactModel class and Contact namespace + +- ContactModel is an interface to manage the contacts. + +- When we need information about contact(s), members functions from + the model can return Contact::Info + +- When we need to perform some operation on a contact, we pass it uri + to the delegate performing the operation. + +### ConversationModel class, Conversation namespace and Message namespace + +- ConversationModel is an interface used to manage conversations + and messages. + +- When we need information about some conversation(s), members + functions from the model can return Conversation::Info. + Conversation::Info contains Messages. + +- note about Message : so far, we didn't need a MessageModel, but this + could be come soon. diff --git a/extra/protocol.md b/extra/protocol.md @@ -0,0 +1,490 @@ +### Persisting the account + +Persisting a Ring account private key and certificate is implementation +defined. + +Access to a saved Ring account private key must be authenticated and +authorized. Authentication and authorization method to access the +account private key is implementation defined. + +### Adding a device to a Ring account + +*See [RFC 5280](https://tools.ietf.org/html/rfc5280)* + +A **device** is defined by an RSA key pair with a key length of at least +4096 bits. + +A **device certificate** is defined as an x509 certificate whose subject +is a device public key, signed with an account private key. The +certificate MUST be valid. The issuer UID field MUST be the hexadecimal +form of the account public key fingerprint. + +Persisting a device private key and certificate is implementation +defined. Access to a saved device private key should be authenticated. +Authentication method to access the device private key is implementation +defined. + +### Removing a device from a Ring account + +A device can be "removed" from a Ring account through revocation of the +device certificate. Revoked device certificates are added to one or more +standard x509 Certificate Revocation List (CRL). CRLs for revoked device +must be valid and signed with the corresponding CA key, which is the +Ring account private key. + +### Account transmission format + +The **account archive format** defines how to serialize an account +private key for transmission, for instance to sign a new device +certificate. + +The account archive is an encrypted JSON object with the following +structure: + +``` +{ + "ringAccountKey": (PEM-encoded account private key string), + "ringAccountCert": (PEM-encoded account certificate string), + "ringAccountCRL": (PEM-encoded account CRL string) +} +``` + +The JSON object can contain additional implementation-defined key-value +pairs. Implementation-defined key names shouldn't start with "ring". + +The string JSON object is encrypted using a key defined as : + +``` +salt = PIN + timestamp +key = argon2(password, salt) +``` + +Where PIN is a random 32bits number in hexadecimal form, "+" is string +concatenation, timestamp is the current UNIX timestamp divided by 1200 +(20 minutes) and password is a user-chosen password. + +The PIN should be shown to the user to be copied manually on the new +physical device along with the password. + +Contacting another account +-------------------------- + +### ICE descriptor exchange over OpenDHT + +- **Listening for incoming calls** + +A device listens for incoming call by performing a listen OpenDHT +operation on + +`h("callto"+deviceID)` + +where h is SHA1, "+" is the string concatenation and deviceID is the +hexadecimal form of the deviceID. + +Received OpenDHT values that are not encrypted or not properly signed +must be dropped. The value must be encrypted with the called device +public key and signed with the calling device private key according to +OpenDHT specifications. + +- **Sending the Initial Offer** + +*See [RFC 5245](https://tools.ietf.org/html/rfc5245)* + +RFC 5245 defines ICE (Interactive Connectivity Establishment), a +protocol for NAT traversal. + +ICE is used in Ring to establish a peer-to-peer communication between +two devices. + +The calling device gathers candidates and build an Initial Offer +according to the ICE specifications and starts the ICE negotiation +process. + +The calling device puts the encrypted ICE offer (the Initial Offer) on +the DHT at h("callto"+deviceID) where deviceID is the hexadecimal form +of the called deviceID. + +- **ICE serialization format** + +ICE messages exchanged between peers during a call setup use following +format. An ICE message is a chunk of binary data, following +[msgpack](http://msgpack.org/) data format. + +This protocol is a compound of msgpack values, successively packed in +this order: + + ++ an integer giving the version of ICE message format protocol used for the rest of the data. Current defined protocol version is **1**. ++ a 2-elements array of strings of the ICE local session ufrag and the ICE local session password ++ an integer giving the number of components in the ICE session ++ an array of string, of the previous number entries, where each string describe the ICE candidate, formated as an "a=" line (without the "a=" header) described in [rfc5245, section 4.3](https://tools.ietf.org/html/rfc5245#page-26) + +- **Sending the Answer** + +Upon reception of the encrypted and signed Initial ICE Offer (through +the listen operation), a called device should perform authorization +checks of the calling device, identified as the Initial Offer signer. +Authorization rules are implementation defined, but a typical +implementation would authorize known or trusted contacts. + +If the calling device is not authorized or if for any implementation +defined reason the called device refuses the incoming connection +request, the called device must ignore the Initial Offer and may log the +event. + +If the called device authorizes the caller and wish to accept the +connection it must build an ICE answer, start the ICE negotiation +process and send the encrypted and signed ICE answer at the same DHT +key. + +### DTLS negotiation + +Once a peer-to-peer communication channel has been established, the +called device listens on it for incoming DTLS connections (acting as a +DTLS server) while the caller initiates an outgoing DTLS connection +(acting as a DTLS client). + +The DTLS communication must be RFC6347 compliant +([1](https://tools.ietf.org/html/rfc6347)). + +Peers must only support PFS cypher suites. The set of supported cypher +suites is implementation defined but should include at least +ECDHE-AES-GCM (TODO: specify the exact suites recommended to support). + +During the DTLS handshake, both peers must provide their respective +device certificate chain and must authenticate the other peer, checking +that its public key is the same used during the DHT ICE exchange. + +### SIP call + +Once an encrypted and authenticated peer-to-peer communication channel +is available, the SIP protocol [2](https://tools.ietf.org/html/rfc3261) +must be used to place a call and send messages. The caller might send a +SIP INVITE as soon as the DTLS channel is established. + +The SIP implementation must support ICE and SRTP. + +Supported codecs are implementation defined, but Ring clients should +support the Opus audio coded and the H264 video codec. + +SRTP must be used when negotiating media with SIP, using a new random +key for each media and each negotiation. ICE should be used when +negotiating media with SIP. + +Cryptographic primitives +------------------------ + +### Password stretching + +*See [Argon2 +specifications](https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf)* + +Passwords are stretched using argon2i using t\_cost = 16, m\_cost = +2\^16 (64 MiB), mono-threaded, to generate a 512 bits hash. + +The result is then hashed again using SHA{1, 256, 512} depending on the +requested key size. + +### Encryption + +##### Using a provided key (128, 192 or 256 bits) + +Encryption uses standard AES-GCM as implemented by Nettle using a random +IV for each encryption. + +##### Using a text password + +The password is stretched to generate a 256 bits key and a random salt +of 128 bits. + +The input data is encrypted using AES-GCM (see above) and the salt is +appended at the beginning of the resulting cypher-text. + +##### During a call + +Audio/video data are exchanged using encrypted RTP channels between +peers. + +The protocol is a classic SRTP, with following supported crypto suites: + +- Ring account force AES\_CM\_128\_HMAC\_SHA1\_80 +- SIP can use AES\_CM\_128\_HMAC\_SHA1\_80 or + AES\_CM\_128\_HMAC\_SHA1\_32 + +The master key and salt is a random number, different for each call. On +call's master key is constant during the full live of a call. + +The keys are exchanged using SDES method: keys are written into the SIP +SDP messages during the SIP INVITE negotiation. When SDES is used, Ring +forces the underlaying transport to be secure (encrypted) to not +disclose these keys. Ring supports DTLS natively for SIP and Ring +accounts for such. The call cannot be done if this condition is not +fulfilled. + + + + +### Outgoing and Incoming calls + +- Contactable addresses (i.e. IP addresses) of the user are given to + peer only: + - When we call a peer (outgoing call). + - When a **trusted** peer is calling (incoming call). +- All combination forms of how a specific device can be contacted is + summarized by a ICE message: + - *[RFC 5245](https://tools.ietf.org/html/rfc5245)* defines ICE + (Interactive Connectivity Establishment), a protocol for + NAT traversal. + - ICE is used in Jami to establish a peer-to-peer communication + between two devices. + +#### Making an outgoing call + +1. The calling device gathers candidates and build an **Initial Offer** + according to the ICE specifications. +2. The calling device puts the encrypted ICE offer (the *Initial + Offer*) on the DHT at: + `h("`[`callto:"+DeviceID`](callto:%22+DeviceID)`)` where *h* is + SHA1, *+* is the string concatenation, *DeviceID* is in + hexadecimal form. +3. The calling device waits on the peer answer, with its own ICE + candidates lists. +4. At peer answer reception, the calling device starts the + ICE negotiation. +5. If the negotiation succeed, the process continues on a client-side + DTLS session establishment over the created ICE socket (see below). + +#### Listening for incoming calls + +1. A device listens for incoming calls by performing a listen OpenDHT + operation on `h("`[`callto:"+DeviceID`](callto:%22+DeviceID)`)` + where *h* is SHA1, *+* is the string concatenation and *DeviceID* is + in hexadecimal form. +2. At ICE *Initial Offer* reception, the called device **must** do a + security validation of the peer (see below). +3. If the security validation succeed, the called device starts the + ICE negotiation. +4. If the negotiation succeed, the process continues on a server-side + DTLS session establishment over the created ICE socket (see below). + +- *Note: OpenDHT drops values that are not properly encrypted or + signed, as specified by OpenDHT protocol.* + +#### ICE serialization format + +- ICE messages exchanged between peers during a call set up use + following format. +- An ICE message is a chunk of binary data, following + [msgpack](http://msgpack.org/) data format. + +``` +<8-bits unsigned integer> giving the version of ICE message format protocol used for the rest of the data, +<C++ std::pair of string> of the ICE local session ufrag and the ICE local session password, +<8-bits unsigned integer> giving the number of components in the ICE session, +<array of string> of the previous number entries, where each string describe the ICE candidate, formated as an "a=" line (without the "a=" header) described in [rfc5245, section 4.3](https://tools.ietf.org/html/rfc5245#page-26) +``` + +- **Current defined protocol is 1**: + +#### Security Validation of the Peer + +- Upon reception of the encrypted and signed Initial ICE Offer + (through the listen operation), a called device should perform + authorization checks of the calling device, identified as the + Initial Offer signer. +- Authorization rules are implementation defined, but a typical + implementation would authorize known or trusted contacts. +- If the calling device is not authorized or if for any implementation + defined reason the called device refuses the incoming connection + request, the called device must ignore the Initial Offer and may log + the event. +- If the called device authorizes the caller and wish to accept the + connection it must build an ICE answer, start the ICE negotiation + process and send the encrypted and signed ICE answer at the same + DHT key. + +#### DTLS negotiation + +- Once a peer-to-peer communication channel has been established by + ICE protocol, the called device starts a server-side DTLS session on + the ICE socket, while the caller starts a client-side DTLS session + on the other side of the ICE socket. +- The DTLS communication is + [RFC6347](https://tools.ietf.org/html/rfc6347) compliant using + gnutls library. +- To prevent peer certificates to be displayed in plain-text for the + call anonymity, the session handshake is done twice: + +1. A first handshake in **anonymous mode** to create a secure but + anonymous transport. +2. A second handshake in **certificate mode**, over the first one, to + prove the identity of peers. + +- Only PFS cipher suites are supported: + - The set of supported cipher suites is implementation defined but + should include at least ECDHE-AES-GCM. + - The actual cipher suites (in gnutls form) is: + - anonymous step: + `SECURE192:-KX-ALL:+ANON-ECDH:+ANON-DH:+SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION` + - certificate step: + `SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION` + +#### SIP signaling + +- Used over the DTLS session to signaling the call (vcard, media + negotiation, hangup, instant messaging, ...) +- Once an encrypted and authenticated peer-to-peer communication + channel is available, the [SIP + protocol](https://tools.ietf.org/html/rfc3261) must be used to place + a call and send messages. +- The caller might send a SIP INVITE as soon as the DTLS channel + is established. +- The SIP implementation must support ICE and SRTP. +- Supported codecs are implementation defined, but Jami clients should + support the Opus audio coded and the H264 video codec. +- SRTP must be used when negotiating media with SIP, using a new + random key for each media and each negotiation. ICE should be used + when negotiating media with SIP. + + +## extra + + +To add a new contact, you send them a trust request over the DHT +consisting of <check this> the account certificate. If they accept the +request, they will send you their account certificate + + +who do not know each other's IP address. + + + +So + + + + +## Usages + +- The JamiId: + - It's the DHT key where the list of account devices are published + and where all devices listen to synchronize on account + changes (i.e. adding or revoke a device). +- The Jami certificate RSA keys are used as long-term keys to + sign/encrypt/decrypt messages sent over the DHT: + - private key to sign-off and decrypt incoming messages and + device certificates. + - public key to encrypt messages (this is done by the message + issuer using the receiver public key). +- A device can be "removed" from a Jami account through revocation of + the device certificate: + - Revoked device certificates are added to one or more standard + x509 Certificate Revocation List (CRL). + - CRLs for revoked device must be valid and signed with the + corresponding CA key, which is the Jami account private key. + +### Long-term Storage + +- Why storing data? + +<!-- --> + +- - Jami needs to load certificates and key-pairs each time the + application is started. + - When Jami creates a new device, these information are also + needed, shared from another trusted device in a secure way. + - All platforms doesn't provide secure way to store data, Jami + supports this fact by encrypting data stored outside the + memory (i.e. on a file-system) using a user defined password + during the account creation. + +<!-- --> + +- These files are stored on user device (see below for details): + - a compressed and encrypted archive with private account data. + - the public certificates chain as a CRT file + - the device private key. + +#### Jami archive (export.gz) + +- Contains private account data. +- Currently transmitted over the DHT network when device is created + or revoked. +- It's a JSON compressed and encrypted file. + +<!-- --> + +- The current format is (could change at any time): + +``` +{ + ringCaKey: <base64 serialized PEM-encoded CA private key>, + ringAccountKey: <base64 serialized PEM-encoded Jami private key> + ringAccountCert: <base64 serialized PEM-encoded Jami certificate (public key)>, + ethKey: <base64 serialized of the optional 160-bits Etherium key used to register the JamiId on a public blockchain>, + ringAccountCRL: <base64 serialized of packet list of revoked device certificates PEM-encoded>, + ringAccountContacts: <JSON dictionary to export trusted user contacts> +} +``` + +- The JSON byte-stream is compressed using \*gzip\* algorithm. + +<!-- --> + +- Then the gzip-stream is encrypted using AES-GCM-256 symmetric cipher + with a 256-bits key. + - This key is derived from the user provided password, a PIN and a + timestamp, using + [Argon2](https://github.com/P-H-C/phc-winner-argon2) (a password + stretching and normalizer) as follow: + +``` +salt = PIN + timestamp +key = argon2(password, salt) + argon2 is the argon2i algorithm using t_cost = 16, m_cost = 2^16 (64 MiB), mono-threaded, to generate a 512-bits key and then hashed with SHA-256 to generate a 256-bits key. + PIN is a random 32bits number in hexadecimal form. + + is string concatenation operator. + timestamp is the current UNIX timestamp divided by 1200 (20 minutes). + password is a user-chosen password (given at account creation). +``` + +- The PIN should be shown to the user to be copied manually on the new + physical device along with the password to finish the device + creation process. +- NOTE: when exporting a file on the DHT or anywhere else, the daemon update the archive first, to write latest contacts. This is the reason why the password is needed when exporting (it's not just a copy of the archive somewhere else) + +#### Jami device certificate chain (ring\_device.crt) + +- PEM format +- Includes the Device certificate and parent certificates (Jami device + certificate and parents) + +#### Device private key (ring\_device.key) + +- PEM format +- not encrypted, we let the device file-system protect this file + +#### Exporting data (creating new devices) + +*TBD* + + +### Contact Request + +*TBD* + +### Instant Message + +*TBD* + +### Presence + +*TBD* + + +### Security / Privacy + +Jami provides perfect forward secrecy for calls and in call text +messages with different Eliptic Curve Diffie-Hellman key negociation at +every call. For out of call messaging single RSA-4096 is used. The +cryptography library used is GNUTLS diff --git a/general/introduction.rst b/general/introduction.rst @@ -0,0 +1,40 @@ +.. image:: https://jami.net/assets/images/logo-jami.svg + +Introduction +============ + +Jami is a free and private communication platform. + +It’s free and open source, end-to-end encrypted, and requires no central +authority. + +Features include text chats, voice and video calls, screen sharing, file +sharing, conference calls, and group chats (:ref:`coming +soon <general/technical-overview:swarms>`). Jami can also function as a +regular SIP client. + +Jami works on Windows, macOS, Linux, iOS, and Android. Multiple devices +can be linked to one account. No personal information is required to +create an account. + +How does it work? +----------------- + +Jami uses a `distributed hash +table <https://en.wikipedia.org/wiki/Distributed_hash_table>`__ to +connect peers. Jami accounts are asymmetric x.509 certificates generated +by the GnuTLS library. Calls are made over the SIP protocol after +negotiating a secure connection using TLS. + +For more in-depth information, see :doc:`the Technical +Overview <technical-overview>`. + +Who makes Jami? +--------------- + +This project is led by `Savoir-faire +Linux <https://www.savoirfairelinux.com/en/>`__ – a Canadian/Quebecois +GNU/Linux consulting company – and is supported by a global community. + +Jami is Free software: its sources are licensed under the +`GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>`__. diff --git a/guides/how-to-set-up-a-dhtproxy-or-bootstrap-server.rst b/guides/how-to-set-up-a-dhtproxy-or-bootstrap-server.rst @@ -0,0 +1,5 @@ +How to Set Up a DHTproxy or DHT Bootstrap Server +================================================ + +TODO (:doc:`contributions +welcome! <how-to-contribute-to-this-documentation>`) diff --git a/technical/advanced-features/androidCall.gif b/technical/advanced-features/androidCall.gif Binary files differ. diff --git a/technical/advanced-features/androidInstall.gif b/technical/advanced-features/androidInstall.gif Binary files differ. diff --git a/technical/advanced-features/androidPrefs.gif b/technical/advanced-features/androidPrefs.gif Binary files differ. diff --git a/technical/advanced-features/clienqtCall.gif b/technical/advanced-features/clienqtCall.gif Binary files differ. diff --git a/technical/advanced-features/clientqtInstall.gif b/technical/advanced-features/clientqtInstall.gif Binary files differ. diff --git a/technical/advanced-features/clientqtPrefs.gif b/technical/advanced-features/clientqtPrefs.gif Binary files differ. diff --git a/technical/advanced-features/create-a-plugin.rst b/technical/advanced-features/create-a-plugin.rst @@ -0,0 +1,755 @@ +Creating Plugins +================ + +**NOTE: this page introduces the Jami Plugins SDK.** + +As from September of 2020, Jami team has added plugins as a call feature +for GNU/Linux, Windows, and Android users. This meaning that now you can +personalize your call and chat experience by using one of our available +plugins. But that is not all, you can also transform your awesome ideas +into a brand new plugin! + +Here you will be guided throught the SDK that will help you start your +plugin developpment. The text is organized as: \* A description of our +`#SDK <#sdk>`__; \* An example of how to create your own base plugin +with our SDK - `#Create my first plugin <#create-my-first-plugin>`__. + +SDK +--- + +We developped a Plugin System for Jami and we have a few plugins +available to be used. However as an open source project, we now desire +users to be able to create, use, and distribute their own plugins. To +achieve that goal, we also developped a Jami Plugins SDK. This kit is +fully writen in python, and can be invoked running pluginMainSDK.py from +``<plugins>`` folder. To get started you must: + +.. code:: bash + + mkdir jami-plugins && cd jami-plugins + git clone https://review.jami.net/ring-daemon daemon + git clone https://review.jami.net/jami-plugins plugins + cd plugins + pip3 install -r SDK/requirements.txt + python3 SDK/pluginMainSDK.py + +You will notice that this script will generate a Jami Plugins SDK shell +that allows users to: + +- `Create full plugin skeleton <#create-full-plugin-skeleton>`__; +- `Create, modify or delete a + manifest.json <#create-modify-or-delete-manifest-json>`__; +- `Create a package.json <#create-a-package-json>`__; +- `Create or delete a preference <#create-or-delete-a-preference>`__; +- `Create functionality <#create-functionality>`__; +- `Create main <#create-main>`__; +- `Assemble files <#assemble-files>`__; +- `Build <#build>`__; +- `Merge jpls <#merge-jpls>`__. + +Each one of these functionalities will be detailled next. We also will +explain the importance of the files it generates and any related SDK +limitations. + +Create full plugin skeleton +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This option performs a sequence of actions to properly create all base +files needed to start a plugin development. The steps are: + +1. gather authorship information; +2. define a plugin name; +3. create manifest; +4. create functionalities and preferences; +5. create main file; +6. define basic package.json; +7. define basic build files (build.sh and CMakeLists.txt). + +If all is completed successfully, the plugin may be build, installed, +and loaded. Also the functionallities may be toggled, however, since +their data processes are not implemented, they will perform no action. +In our ``HelloWorld`` plugin, we implement a simple process using +**OpenCV**. For more complex options, you can refer to our available +plugins at +`jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. +Feel free to implement any ideas you may have, but you should respect +those constrains: \* use ffmpeg, opencv, and onnx from ring-daemon +project; \* if using tensorflow, choose version 2.1.0. Why? \* We have +all needed header files of tensorflow 2.1.0 in /contrib/libs.tar.gz; \* +We provide docker images with libraries for Tensorflow C++ API and +Tensorflow Lite, for both Android and Linux development. \* if you need +other libraries, check if we support it’s build with ring-daemon +project, otherwise, you will have to build it and ensure correct link to +the plugin libraries. + +To fully create a basic plugin with pre-implementation of desired +functionalities APIs, preferences, package, manifest, main file, and +basic build related files, from inside Jami Plugins SDK shell, the user +must call: + +:: + + (Jami Plugins SDK) plugin + +The SDK will ask other informations needed to correctly accomplish the +task. + +Create, modify or delete manifest.json +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Every plugin must have a manifest. This file contains the official name, +a description, and carries the plugin build version as in the example +bellow. Without it, the plugin system will not be able to find the +plugin library it should load. Due to it’s importance, every time Jami +Plugin SDK is told to create files to a non existing plugin or to a +plugin with no manifest, it will first create a new manifest. + +.. code:: bash + + { + "name": "HelloWorld", + "description" : "HelloWorld plugin will guide you throught Jami Plugins SDK use!", + "version" : "1.0.0" + } + +To create/modify (or to delete) a manifest.json, from inside Jami +Plugins SDK shell, the user must call: + +:: + + (Jami Plugins SDK) manifest (-del) + +The SDK will ask other informations needed to correctly accomplish the +task. + +Create a package.json +~~~~~~~~~~~~~~~~~~~~~ + +Jami currently supports plugins for GNU/Linux, Android and Windows. For +the latter, the build system used is the same as for Jami, it is, we +call the plugin build using a python script. This script will look for a +``package.json`` file to aquire build informations and commands. Without +this file our build pipeline for Windows will not work. + +An example package.json file is shown bellow. \* ``name`` and +``version`` in the package.json and manifest.json files should match. \* +``extractLibs`` indicates to the build system if the files under +``<jami-plugins>/contrib/libs.tar.gz`` will be used. This archive +contains header files for **Tensorflow**. Thus, you only need to set +``extractLibs`` to true if you plan to use this library. \* To play with +audio or video, the plugin is dependent of **ffmpeg**. By adding it to +``deps``, the build system will automatically compile this library from +``<ring-daemon>/contrib`` if needed. We also provide **OpenCV** build +from inside ``<ring-daemon>/contrib`` ! If you want to use Tensorflow, +we provide built libraries for GNU/Linux and Android with our docker +images +`here <https://hub.docker.com/repository/docker/sflagsantos/tensorflow-cuda>`__ +and +`here <https://hub.docker.com/repository/docker/sflagsantos/tensorflowlite>`__. +For more information about OpenCV and Tensorflow build, please refer to +`jami-plugins <plugins>`__ technical documentation. There we have a +step-by-step! \* If you’re using cmake, your can set configuration +definition in ``defines`` property. Exemple: if your configuration line +is of the form ``cmake -DCPU=TRUE ..`` you may set +``"defines": ["CPU=TRUE"]``. \* Any command directly related to the +plugin build can be defined inside ``custom_scripts``. Bellow we create +the build folder to with the plugins project will be configured with +``mkdir msvc`` and we also set the build command as +``cmake --build ./msvc --config Release``. Our example CMakeLists.txt +may have pre and post build instruction that are not listed here. + +.. code:: bash + + { + "name": "Hello World", + "version": "1.0.0", + "extractLibs": false, + "deps": [ + "ffmpeg" + ], + "defines": [], + "custom_scripts": { + "pre_build": [ + "mkdir msvc" + ], + "build": [ + "cmake --build ./msvc --config Release" + ], + "post_build": [] + } + } + +To create a package.json, from inside Jami Plugins SDK shell, the user +must call: + +:: + + (Jami Plugins SDK) package + +The SDK will ask other informations needed to correctly accomplish the +task. After the base package.json creation, the user must add or modify +any information not previewed by the SDK process. + +Create or delete a preference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A preference is a internal variable that will be used upon loading or +while running the plugin. There is limited types of preferences +supported by the plugin system and each of them must contain generic and +specific informations. Those informations must be placed under a certain +structure that will form one preference and each preference must be +listed inside a ``preference.json`` file. + +The generic properties of a preference are those that must be set by any +type of preference: ``category``, ``type``, ``key``, ``title``, +``summary``, ``defaultValue``, and ``scope``. The specific ones are +linked to the type of the preference constructed. For ``EDITTEXT`` +preferences there is no other property to be set. For ``PATH`` +preferences we have: ``mimeType``. For ``LIST`` preferences we have: +``entries`` and ``entryValues``. A ``LIST`` preference must have a list +of possible values to be used and a list of ‘names’ for these values. +For example: If you have two ``entriesValues``: ‘0’ and ‘1’, these +values may not be understandable by the user. Jami’s UI will take the +values from ``entries`` to be shown as ‘names’ for each one of these +``entryValues``. Then you can call ‘0’ and ‘1’ as ‘sent’ and ‘received’. +The UI will show these names that are more user friendly! It is +important to note that ``entries`` and ``entryValues`` must have the +same number of items. + +Another important point to be noted for the preferences is that their +values could be modified during runtime if, and only if, two conditions +are satisfied: + +1. the code that applies the new value is within your functionality + implementation and; +2. this functionality is listed in the preference’s ``scope`` property. + +To better explain, we have to detail what is a scope and how a +preference changement is implemented inside the plugin. + +- **Scope**: A scope is a list of functionalities that can modify a + preference value even if the functionality is under use. It is, + imagine you have a functionality called “Circle” that prints a + colored circle to your video. Consider also that the color of that + circle is set by a preference and that this preference lists “Circle” + as one of it’s scopes. In that scenario “Circle” will be able to + modify the default circle color to another one. +- **Code implementation**: Continuing our example above, “Circle” also + is the implementation of an abstract API class from Daemon (for more + details check `#Create functionality <#create-functionality>`__. When + a user changes a preference value, the plugin system will call the + ``setPreferenceAttribute`` implementation for each of the + functionalities listed by the preference’s scope. By it’s turn, this + function will match the preference unique ``key`` and call an + internal function to apply the new value. + +For a pratical example, you can check the ‘Foreground Segmentation’ +functionality of the GreenScreen plugin - +`pluginMediaHandler.cpp <https://git.jami.net/savoirfairelinux/jami-plugins/blob/master/GreenScreen/pluginMediaHandler.cpp>`__ +and +`preferences-onnx.json <https://git.jami.net/savoirfairelinux/jami-plugins/blob/master/GreenScreen/preferences-onnx.json>`__. +This plugin has both ``LIST`` and ``PATH`` preferences and also has one +preference that can be modified during runtime. Can you tell wich one? + +To create (or delete) a preference, from inside Jami Plugins SDK shell, +the user must call: + +:: + + (Jami Plugins SDK) preference (-del) + +The SDK will ask other informations needed to correctly accomplish the +task. If a preference is created from outside a functionality creation +pipeline, any API implementation will not be changed in order to avoid +overwrittings. Thus, if you want to allow values changement during +runtime, you may need to manually modify your functionality +implementation to fit running time changements conditions. + +Create functionality +~~~~~~~~~~~~~~~~~~~~ + +A Jami plugin may wrap one or multiple functionalities. It is, the same +plugins may have a functionality to change background and to draw a +circle to a video for example. Each functionality must implement an +abstract API class defined by Jami plugins System. That way, we can say +that one functionality is one implementation of an API. Currently we +have the ``MediaHandler`` which allows access to audio or video frames +and we have ``ChatHandler`` which allows acces to messages exchanged in +a conversation. + +When defining a new a functionality, the SDK will create basic header +and cpp files for you work on. However, your new functionality can not +be added to the scopes of a previously existing preference. For more +information, please refer to `Create or delete a +preference <#create-or-delete-a-preference>`__. + +To create a functionality, from inside Jami Plugins SDK shell, the user +must call: + +:: + + (Jami Plugins SDK) functionality + +The SDK will ask other informations needed to correctly accomplish the +task. + +Create main +~~~~~~~~~~~ + +This option create plugin’s ``main.cpp``. A file that implements the +plugin external loading function that Jami Plugin System will call to +initialize and register all functionalities for latter use. + +The SDK is set to rewrite the main file every time you create a new +functionality. Thus, if you want to manually create or delete a +functionality, we recomend calling this option instead. + +To create a ``main.cpp``, from inside Jami Plugins SDK shell, the user +must call: + +:: + + (Jami Plugins SDK) main + +The SDK will ask other informations needed to correctly accomplish the +task. + +Assemble files +~~~~~~~~~~~~~~ + +The final plugin file is an archive compressed to a ``JPL`` format. This +archive contains libraries, manifest.json, preferences.json, icons and +other custom important files for your plugin. OBS.: files added by the +developper must be organized under the ``data/`` folder. + +The SDK assemble option has two different behaviours: + +- it creates a build folder and copies there all files that will be + compressed to the final plugin archive. For linux host: + ``<plugins>/<HelloWorld>/build-local/jpl/`` and for a windows host: + ``<plugins>/<HelloWorld>/msvc/jpl/``; +- it compresses all files inside the build folder to the jpl archive + wich is output under ``<plugins>/build``. + +Both process should be called from inside the CMakeLists.txt as +POST_BUILD and PRE_BUILD commands, respectively. Also, the build.sh +script should call them. For more information about CMakeLists.txt and +build.sh files, please refere to `build <#build>`__ and to our available +plugins at +`jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. + +To create a build folder and copy all important files there, from inside +Jami Plugins SDK shell, the user must call: + +:: + + (Jami Plugins SDK) assemble -pre + +To compress all assembled to a jpl archive, from inside Jami Plugins SDK +shell, the user must call: + +:: + + (Jami Plugins SDK) assemble + +The SDK will ask other informations needed to correctly accomplish the +task. + +Build +~~~~~ + +The SDK build option has two different behaviours: + +- it creates basic CMakeLists.txt and buils.sh files; +- it build the plugin library with default options defined at the files + mentioned above. + +A description of thes CMakeLists.txt and buils.sh files are found +further in this section. + +To create basic CMakeLists.txt and buils.sh files, from inside Jami +Plugins SDK shell, the user must call: + +:: + + (Jami Plugins SDK) build -def + +To build plugin library with default configuration, from inside Jami +Plugins SDK shell, the user must call: + +:: + + (Jami Plugins SDK) build + +The SDK will ask other informations needed to correctly accomplish the +task. For the moment, the build option does not support +cross-compilation neither non default builds. If you have build +variables to be set differently than the default option, please directly +use the ``<plugins>/build-plugin.py`` script. + +CMakeLists.txt +^^^^^^^^^^^^^^ + +This file is used only by Jami’s Windows build pipeline. + +If you need to pass any defines to cmake generation, your definitions +can be in ``package.json`` as explained in the package section. The +package.json created specifies the default configuration that calling +the build from Jami Plugins SDK will consider. If you want to build with +no default configuration, you can: directly use the script mentioned +above and pass non-default definitions as an argument or; you also can +manually change your package.json file. For examples, you can refer to +our available plugins at +`jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. + +Another important information about CMakeLists.txt is that it has to add +custom commands. For PRE_BUILD, it must call the pre-assemble +functionality process. For POST_BUILD, it must copy the built library to +the build folder and call the assemble functionality process. In the +end, your jpl archive may be found under ``<plugins>/build``. The +CMakeLists.txt file automatically created by our SDK, already respects +these constraints. + +build.sh +^^^^^^^^ + +This file is used by Jami to build plugins for GNU/Linux and Android +platforms. + +The basic script consider the environment variable ``DAEMON`` that must +point to the ring-daemon folder. Besides, you can pass an argument for +the platform used like ``-t android`` if you want to cross-compile for +Android. Further custom definitions and environment variables should be +handled by the plugin developper. If you want to build with no default +configuration, you can modify the environment variables values and then +call the build. Ie: for android, you can set which ABI you want to build +with ``export ANDROID_ABI="arm64-v8a armeabi-v7a``. For other examples, +you can refer to our `technical +documentation <https://git.jami.net/savoirfairelinux/ring-project/wikis/technical/7.-Jami-plugins>`__ +and to our `available +plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. + +Another important information about build.sh is that it has to call pre +and post assemble. Before the build, it must call the pre-assemble +functionality process. After it, it must copy the built library to the +build folder and call the assemble functionality process. In the end, +your jpl archive may be found under ``<plugins>/build``. The build.sh +file automatically created by our SDK, already respects these +constraints. + +Merge jpls +~~~~~~~~~~ + +If you have more than one jpl archives, like one build for Android and +anothe for GNU/Linux platforms, you can merge them into one to easy it’s +distribution. However, you should know that merging two or more jpls may +inccur orverwritting some of the files inside them if they are not equal +for all archives. The only files that may not present conflicting +contents are the ones that do not repeate themselves. If conflicts +occur, files from the first jpl in the arguments will prevail over the +others. + +To merge two or more jpls, from inside Jami Plugins SDK shell, the user +must simple call: + +:: + + (Jami Plugins SDK) merge + +The SDK will ask other informations needed to correctly accomplish the +task. + +Create my first plugin +---------------------- + +Through this section we will present a step-by-step construction of a +``HelloWorld`` plugin using our SDK. Our goal is to print a coloured +circle in the midle of the video frames using **OpenCV**. The color of +that circle will be defined by a preference which will be changeable +during runtime. Also we can set a stream preferece to define if the +plugin will modify the video sent or the one received, this time we +don’t want to allow a changement during runtime. We can define a second +functionality that will aways draw a circle in the right top corner, +with the color defined by the same preference as the previous +functionality but that cannot be changed during runtime. At the end we +will exemplify how to build your plugin with and without the SDK. + +Step 1 - prepare developpment environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The first step towards plugin development is to properly prepare the +environment. + +.. code:: bash + + mkdir jami-plugins && cd jami-plugins + git clone https://review.jami.net/ring-daemon daemon + git clone https://review.jami.net/jami-plugins plugins + cd plugins + pip3 install -r SDK/requirements.txt + +Step 2 - create HelloWorld with one functionality +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Use Jami Plugins SDK to create the plugin skeleton + +.. code:: python + + python3 SDK/pluginMainSDK.py + +.. + + (Jami Plugins SDK) plugin + + Tell us who you are? + +.. + + What’s your name? Aline Gondim Santos + + What’s your e-mail? aline.gondimsantos@savoirfairelinux.com + +.. + + Leave Empty or Press ‘q’ to quit this option. + + Now, you need to tell how you want yout plugin to be called. + +.. + + Choose a cool name for your plugin: Hello World + + Nice! Your HelloWorld will be awesome! + +.. + + Defining a manifest for “HelloWorld” plugin, we gonna need more + information.. + + Press ‘q’ to quit this option. + +.. + + Tell us a description: HelloWorld draws a circle in the center of a + call’s video + + Version must be of the form X.Y.Z Set plugin version (default 0.0.0): + 1.0.0 + +.. + + Chose a functionality name: CenterCircle + + Choose a API for functionality “CenterCircle”. + +.. + + Available APIs: (1) video during a call (Media Handler API) (2) audio + during a call (Media Handler API) (3) chat messages (Chat Handler + API) For more information about the API, call help preferences. + + Enter a data type number: 1 + +.. + + Add another functionaliy? [y/N] + + Would you like to add a preference? [y/n] y + +.. + + Your preferences options available are: (0) List; (1) Path; (2) + EditText; + + Which preference type do you choose: 0 Type a value for category: + stream Type a value for key: videostream Type a value for title: + Video stream Type a value for summary: select a video direction Type + a value for defaultValue: 0 + +.. + + Would you like to add a scope? [y/n] n + + Do you want to add a new entry Value? [y/n] y Type one new entry: 0 + +.. + + Do you want to add a new entry Value? [y/n] y Type one new entry: 1 + + Do you want to add a new entry Value? [y/n] n Type an entry name for + ‘0’: sent Type an entry name for ‘1’: received + +.. + + Would you like to add a preference? [y/n] y + + Your preferences options available are: (0) List; (1) Path; (3) + EditText; + +.. + + Which preference type do you choose: 0 Type a value for category: + color Type a value for key: color Type a value for title: Circle + color Type a value for summary: select a color Type a value for + defaultValue: ##00FF00 + + Would you like to add a scope? [y/n] y + +.. + + Possible values for scope: (0) centerCircle; + + Which scope do you choose: 0 + +.. + + Do you want to add a new entry Value? [y/n] y Type one new entry: + #0000FF + + Do you want to add a new entry Value? [y/n] y Type one new entry: + #00FF00 + +.. + + Do you want to add a new entry Value? [y/n] y Type one new entry: + #FF0000 + + Do you want to add a new entry Value? [y/n] n Type an entry name for + ‘#0000FF’: blue Type an entry name for ‘#00FF00’: green Type an entry + name for ‘#FF0000’: red + +.. + + Would you like to add a preference? [y/n] n + + The preference Circle color will be changeable during running time + for centerCircle functionality? [y/n] y + +.. + + Package ok. + + CMakeLists.txt and build.sh ok. + +- modify CenterCircleMediaHandler.cpp, CenterCircleVideoSubscriver.h, + CenterCircleVideoSubscriber.cpp; +- You will need to modify package.json, CMakeLists.txt and build.sh to + add OpenCV dependencies. + +All final files can be found +`here <https://git.jami.net/savoirfairelinux/jami-plugins>`__ + +Step 3 - build +~~~~~~~~~~~~~~ + +Before building the HelloWorld, you should compile ffmpeg and OpenCV +dependencies. This can be achieved by following the build instructions +for OpenCV `here <plugins>`__. Ffmpeg will be automatically build if you +follow those instructions. To build you plugin, you can either: \* Call +the build from Jami Plugins SDK (works for GNU/Linux and Windows): + +.. code:: python + + python3 SDK/pluginMainSDK.py + +.. + + (Jami Plugins SDK) build + + Leave Empty or Press ‘q’ to quit this option. + +.. + + Plugin to pass build related step: HelloWorld + + DAEMON not provided, building with ./../../daemon + +- Call plugin-build.py script (works for GNU/Linux, Windows and + Android): + +- GNU/Linux or Windows: > python3 build-plugin.py –projects=HelloWorld + +- Android: > python3 build-plugin.py –projects=HelloWorld + –distribution=android + +OBS: For Android, you can set ``ANDROID_ABI`` environment variable to +the ABI you want to build. Currently Jami supports ``x86_64``, +``armeabi-v7a``, and ``arm64-v8a``. Plugins will be build for the three +options by default. + +Step 4 - create another functionality for HelloWorld and rebuild +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that you tested and your HelloWorld is working, you can try to do +add another functionality to it. + +.. code:: python + + python3 SDK/pluginMainSDK.py + +.. + + (Jami Plugins SDK) functionality + + Tell us who you are? + +.. + + What’s your name? Aline Gondim Santos + + What’s your e-mail? aline.gondimsantos@savoirfairelinux.com + +.. + + Leave Empty or Press ‘q’ to quit this option. + + Plugin to be modified or created: HelloWorld + +.. + + Chose a functionality name: CoinCircle + + Choose a API for functionality “CoinCircle”. + +.. + + Available APIs: (1) video during a call (Media Handler API) (2) audio + during a call (Media Handler API) (3) chat messages (Chat Handler + API) For more information about the API, call help preferences. + + Enter a data type number: 1 + +.. + + Add another functionaliy? [y/N] n + + Would you like to add a preference? [y/n] n + +.. + + CMakeLists.txt and build.sh ok. + +Again, all code modifications are available +`here <https://git.jami.net/savoirfairelinux/jami-plugins>`__ + +Optionally, you can change your plugin version and description: + +.. code:: python + + python3 SDK/pluginMainSDK.py + +.. + + (Jami Plugins SDK) manifest Leave Empty or Press ‘q’ to quit this + option. + + Plugin to be modified or created: HelloWorld New description for your + plugin (ignore to keep previous description): HelloWorld can draw a + circle at the center or at the top-left of a call’s video New plugin + version (ignore to keep previous version): 2.0 + +Finally, you can rebuild the plugin using the same steps as before! + +Now you can start your own creations! Do not forget to tag Jami or +Savoir-Faire Linux in your repository, this way we can get to know how +the community is developping their own plugins! diff --git a/technical/basic-features/DataTransfer.png b/technical/basic-features/DataTransfer.png Binary files differ. diff --git a/technical/basic-features/Main.png b/technical/basic-features/Main.png Binary files differ. diff --git a/technical/basic-features/TLSsocketEndpoint.png b/technical/basic-features/TLSsocketEndpoint.png Binary files differ. diff --git a/technical/basic-features/swarm-chat.jpg b/technical/basic-features/swarm-chat.jpg Binary files differ. diff --git a/technical/choosing-crf-value-for-encoder.md b/technical/choosing-crf-value-for-encoder.md @@ -0,0 +1,105 @@ +# Choosing CRF value for encoder + +## Context +Bandwidth usage by the Jami application is not optimal for all types of connections. Indeed, in some cases, the user experience is not good (satellite connection, ...) despite the bandwidth management algorithm. + +## Observation +It is not necessary to aim for an optimal quality (CRF < 20) because beyond that, the visual perception is almost similar while the data flow (bitrate) required is much higher. + +## Objective +The purpose of this document is to verify the impact of a change in video quality with the CRF parameter of the encoder. + +## Test +These tests were performed by comparing : +- The first one encoded with Jami's current parameters +- The second encoded with a lower quality + +Each of these tests were performed for the following resolutions: 1080p, 720p and 436p. + +For each of these resolutions several bitrates have been used: +- 300 Kbit/s (Jami low value) +- 1.5 Mbit/s (Intermediate value) +- 6 Mbit/s (High value) + +The graphs show the evolution of the bitrate with the file being tested (resolution and specific set bitrate). + +A visual comparison (side by side) was made for each test. + +Thanks to this test we can estimate the bitrate that will be emitted in Jami according to the chosen parameters. We also have an overview of the visual quality. + +* * * + +1080p / 300 kbit/s / CRF28 +![image](encoder01.png) +1080p / 300 kbit/s / CRF38 +![image](encoder02.png) + +Visual comparison (CRF28 a gauche / CRF38 a droite) +https://nextcloud.savoirfairelinux.com/index.php/s/twzPmT3MRPjQ3b7 + +1080p / 1.5 Mbps / CRF22 +![image](encoder03.png) +1080p / 1.5 Mbit/s / CRF30 +![image](encoder04.png) + +Visual comparison (CRF22 left / CRF30 right) +https://nextcloud.savoirfairelinux.com/index.php/s/XK6Ef3rwBFriRXT + + 1080p / 6 Mbps / CRF17 +![image](encoder05.png) + 1080p / 6 Mbit/s / CRF23 +![image](encoder06.png) + +Visual comparison (CRF17 on the left / CRF23 on the right) +https://nextcloud.savoirfairelinux.com/index.php/s/RG3TksjQKtMorW5 + +* * * + +720p / 300 kbps / CRF28 +![image](encoder07.png) +720p / 300 kbit/s / CRF38 +![image](encoder08.png) +Visual comparison (CRF28 left / CRF38 right) +https://nextcloud.savoirfairelinux.com/index.php/s/Z4T6EzGqyyWTJ9f + +720p / 1.5 Mbps / CRF22 +![image](encoder09.png) +720p / 1.5 Mbit/s / CRF30 (Test with reduced CRF) +![image](encoder10.png) + +Visual comparison (CRF22 left / CRF30 right) +https://nextcloud.savoirfairelinux.com/index.php/s/H2Z5NQT3zJ9wzod + +720p / 6 Mbps / CRF17 +![image](encoder11.png) +720p / 6 Mbit/s / CRF23 +![image](encoder12.png) + +Visual comparison (CRF17 left / CRF23 right) +https://nextcloud.savoirfairelinux.com/index.php/s/gACSARfHjAKqgRR + +* * * + +436p / 300 kbps / CRF28 +![image](encoder13.png) +436p / 300 kbit/s / CRF38 +![image](encoder14.png) + +Visual comparison (CRF28 left / CRF38 right) +https://nextcloud.savoirfairelinux.com/index.php/s/gj9CpQox5fiaWMT + +436p / 1.5 Mbps / CRF22 +![image](encoder15.png) +436p / 1.5 Mbit/s / CRF30 +![image](encoder16.png) + +Visual comparison (CRF22 left / CRF30 right) +https://nextcloud.savoirfairelinux.com/index.php/s/BeCaqs2rMRpNQwS + +436p / 6 Mbps / CRF17 +![image](encoder17.png) +436p / 6 Mbit/s / CRF23 +![image](encoder18.png) + +Visual comparison (CRF17 left / CRF23 right) +https://nextcloud.savoirfairelinux.com/index.php/s/KLeXq9NeLKTfyqs diff --git a/technical/color_reference.png b/technical/color_reference.png Binary files differ. diff --git a/technical/encoder01.png b/technical/encoder01.png Binary files differ. diff --git a/technical/encoder02.png b/technical/encoder02.png Binary files differ. diff --git a/technical/encoder03.png b/technical/encoder03.png Binary files differ. diff --git a/technical/encoder04.png b/technical/encoder04.png Binary files differ. diff --git a/technical/encoder05.png b/technical/encoder05.png Binary files differ. diff --git a/technical/encoder06.png b/technical/encoder06.png Binary files differ. diff --git a/technical/encoder07.png b/technical/encoder07.png Binary files differ. diff --git a/technical/encoder08.png b/technical/encoder08.png Binary files differ. diff --git a/technical/encoder09.png b/technical/encoder09.png Binary files differ. diff --git a/technical/encoder10.png b/technical/encoder10.png Binary files differ. diff --git a/technical/encoder11.png b/technical/encoder11.png Binary files differ. diff --git a/technical/encoder12.png b/technical/encoder12.png Binary files differ. diff --git a/technical/encoder13.png b/technical/encoder13.png Binary files differ. diff --git a/technical/encoder14.png b/technical/encoder14.png Binary files differ. diff --git a/technical/encoder15.png b/technical/encoder15.png Binary files differ. diff --git a/technical/encoder16.png b/technical/encoder16.png Binary files differ. diff --git a/technical/encoder17.png b/technical/encoder17.png Binary files differ. diff --git a/technical/encoder18.png b/technical/encoder18.png Binary files differ.