diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index 1e0a91bc1b2c79f0f212bc3b116f15f5a65316bb..aa73e5a8c930143215eef27d79cad20f4fcfea4e 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -100,12 +100,17 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         <meta-data
             android:name="google_analytics_adid_collection_enabled"
             android:value="false" />
+        <activity
+            android:name=".client.LogsActivity"
+            android:label="@string/pref_logs_title"
+            android:theme="@style/AppTheme.Navigation"
+            />
 
         <activity
             android:name=".client.HomeActivity"
             android:configChanges="screenSize|screenLayout|smallestScreenSize"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:launchMode="singleTask"
             android:theme="@style/AppTheme.Navigation"
             android:windowSoftInputMode="adjustResize">
@@ -139,14 +144,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
             <meta-data
                 android:name="android.app.searchable"
                 android:resource="@xml/searchable" />
-
-            <meta-data android:name="android.app.shortcuts"
-                android:resource="@xml/shortcuts"/>
+            <meta-data
+                android:name="android.app.shortcuts"
+                android:resource="@xml/shortcuts" />
         </activity>
         <activity
             android:name=".client.ShareActivity"
-            android:label="@string/title_share_with"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/title_share_with"
             android:parentActivityName=".client.HomeActivity"
             android:theme="@style/AppTheme">
             <intent-filter>
@@ -164,10 +169,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         <activity
             android:name=".account.AccountWizardActivity"
             android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
-            android:theme="@style/AppThemeBase.Light"
             android:icon="@mipmap/ic_launcher"
             android:resizeableActivity="true"
-            android:windowSoftInputMode="adjustResize"/>
+            android:theme="@style/AppThemeBase.Light"
+            android:windowSoftInputMode="adjustResize" />
         <activity
             android:name=".client.RingtoneActivity"
             android:configChanges="screenSize|screenLayout|smallestScreenSize"
@@ -186,7 +191,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
                 <action android:name="android.intent.action.QUICKBOOT_POWERON" />
-                <action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED"/>
+                <action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
             </intent-filter>
         </receiver>
 
@@ -207,8 +212,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
             android:foregroundServiceType="dataSync" />
         <service
             android:name=".services.LocationSharingService"
-            android:foregroundServiceType="location"
-            android:exported="false" />
+            android:exported="false"
+            android:foregroundServiceType="location" />
 
         <activity
             android:name=".client.CallActivity"
@@ -280,8 +285,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
             android:name=".client.ConversationActivity"
             android:allowEmbedded="true"
             android:configChanges="screenSize|screenLayout|smallestScreenSize"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:parentActivityName=".client.HomeActivity"
             android:resizeableActivity="true"
             android:theme="@style/AppTheme.Fullscreen"
@@ -293,34 +298,37 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
             <intent-filter>
                 <action android:name=".service.DRingService" />
             </intent-filter>
-        </service>
-
-        <!-- AndroidTV section -->
+        </service> <!-- AndroidTV section -->
         <activity
             android:name=".tv.main.HomeActivity"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:theme="@style/Theme.Jami.Leanback.Main">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+
                 <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
+
                 <category android:name="android.intent.category.BROWSABLE" />
                 <category android:name="android.intent.category.DEFAULT" />
+
                 <data
-                    android:scheme="jamitv"
                     android:host="cx.ring"
-                    android:path="/home" />
+                    android:path="/home"
+                    android:scheme="jamitv" />
             </intent-filter>
         </activity>
+
         <receiver
             android:name=".tv.main.ChannelActionHandler"
             android:enabled="true"
             android:exported="true">
             <intent-filter>
                 <category android:name="android.intent.category.DEFAULT" />
+
                 <action android:name="android.media.tv.ACTION_INITIALIZE_PROGRAMS" />
                 <action android:name="android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
                 <action android:name="android.media.tv.ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT" />
@@ -330,30 +338,30 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
         <activity
             android:name=".tv.account.TVAccountWizard"
-            android:label="@string/app_name"
-            android:icon="@mipmap/ic_launcher"
             android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
+            android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:theme="@style/AppTheme" />
         <activity
             android:name=".tv.search.SearchActivity"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:theme="@style/Theme.Leanback" />
         <activity
             android:name=".tv.about.AboutActivity"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:theme="@style/Theme.Leanback" />
         <activity
             android:name=".tv.account.TVShareActivity"
-            android:label="@string/app_name"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:theme="@style/Theme.Ring.Leanback" />
         <activity
             android:name=".tv.call.TVCallActivity"
-            android:label="@string/app_name"
-            android:icon="@mipmap/ic_launcher"
             android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
+            android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
             android:resizeableActivity="true"
             android:showOnLockScreen="true"
             android:supportsPictureInPicture="true"
@@ -366,9 +374,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         </activity>
         <activity
             android:name=".tv.camera.CustomCameraActivity"
-            android:theme="@style/AppTheme"
+            android:icon="@mipmap/ic_launcher"
             android:label="@string/app_name"
-            android:icon="@mipmap/ic_launcher">
+            android:theme="@style/AppTheme">
             <intent-filter>
                 <action android:name="cx.ring.action.CALL" />
 
@@ -377,20 +385,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         </activity>
         <activity
             android:name=".tv.contact.TVContactActivity"
-            android:theme="@style/Theme.Leanback.Details"
+            android:icon="@mipmap/ic_launcher"
             android:label="@string/app_name"
-            android:icon="@mipmap/ic_launcher">
+            android:theme="@style/Theme.Leanback.Details">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
+
                 <category android:name="android.intent.category.BROWSABLE" />
                 <category android:name="android.intent.category.DEFAULT" />
+
                 <data
-                    android:scheme="jamitv"
                     android:host="cx.ring"
-                    android:pathPrefix="/conversation/" />
+                    android:pathPrefix="/conversation/"
+                    android:scheme="jamitv" />
             </intent-filter>
         </activity>
-
         <activity
             android:name=".tv.account.TVSettingsActivity"
             android:theme="@style/LeanbackPreferences" />
@@ -408,8 +417,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         <activity
             android:name=".client.MediaViewerActivity"
             android:exported="false"
-            android:label="@string/title_media_viewer"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/title_media_viewer"
             android:theme="@style/AppThemeBase.Dark" />
 
         <service
@@ -419,16 +428,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
         <activity
             android:name=".client.ContactDetailsActivity"
             android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
-            android:label="@string/conversation_details"
             android:icon="@mipmap/ic_launcher"
+            android:label="@string/conversation_details"
             android:resizeableActivity="true"
             android:theme="@style/AppTheme.Fullscreen"
             android:windowSoftInputMode="adjustResize" />
         <activity
             android:name=".client.ConversationSelectionActivity"
             android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
-            android:label="Choose a contact or conversation"
             android:icon="@mipmap/ic_launcher"
+            android:label="Choose a contact or conversation"
             android:theme="@style/Theme.MaterialComponents.DayNight.Dialog.Alert"
             android:windowSoftInputMode="adjustResize" />
     </application>
diff --git a/ring-android/app/src/main/java/cx/ring/client/LogsActivity.java b/ring-android/app/src/main/java/cx/ring/client/LogsActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..07f7d2cd6b513e8ef11e378f4b0af56c307410cd
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/client/LogsActivity.java
@@ -0,0 +1,203 @@
+/*
+ *  Copyright (C) 2004-2021 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Beraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cx.ring.client;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.content.ContextCompat;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import net.jami.services.HardwareService;
+import net.jami.utils.StringUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import cx.ring.R;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.ActivityLogsBinding;
+import cx.ring.utils.AndroidFileUtils;
+import cx.ring.utils.ContentUriHandler;
+import io.reactivex.Maybe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+
+public class LogsActivity extends AppCompatActivity {
+    private static final String TAG = LogsActivity.class.getSimpleName();
+
+    private ActivityLogsBinding binding;
+
+    private final CompositeDisposable compositeDisposable = new CompositeDisposable();
+    private Disposable disposable;
+
+    private ActivityResultLauncher<String> fileSaver;
+    private File mCurrentFile = null;
+
+    @Inject
+    @Singleton
+    HardwareService mHardwareService;
+
+    public LogsActivity() {
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        JamiApplication.getInstance().startDaemon();
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
+        binding = ActivityLogsBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
+        setSupportActionBar(binding.toolbar);
+        ActionBar ab = getSupportActionBar();
+        if (ab != null)
+            ab.setDisplayHomeAsUpEnabled(true);
+
+        fileSaver = registerForActivityResult(new ActivityResultContracts.CreateDocument(), result -> compositeDisposable.add(
+                AndroidFileUtils.copyFileToUri(getContentResolver(), mCurrentFile, result).
+                        observeOn(AndroidSchedulers.mainThread()).
+                        subscribe(() -> {
+                            if (!mCurrentFile.delete())
+                                Log.w(TAG, "Can't delete temp file");
+                            mCurrentFile = null;
+                            Snackbar.make(binding.getRoot(), R.string.file_saved_successfully, Snackbar.LENGTH_SHORT).show();
+                        }, error -> Snackbar.make(binding.getRoot(), R.string.generic_error, Snackbar.LENGTH_SHORT).show())));
+
+        binding.fab.setOnClickListener(view -> {
+            if (disposable == null)
+                startLogging();
+            else
+                stopLogging();
+        });
+        if (mHardwareService.isLogging())
+            startLogging();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.logs_menu, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    private Maybe<String> getLog() {
+        if (mHardwareService.isLogging())
+            return mHardwareService.startLogs()
+                .firstElement();
+        CharSequence log = binding.logView.getText();
+        if (StringUtils.isEmpty(log))
+            return Maybe.empty();
+        return Maybe.just(log.toString());
+    }
+
+    private Maybe<File> getLogFile() {
+        return getLog()
+                .observeOn(Schedulers.io())
+                .map(log -> {
+                    File file = AndroidFileUtils.createLogFile(this);
+                    OutputStream os = new FileOutputStream(file);
+                    os.write(log.getBytes());
+                    return file;
+                });
+    }
+
+    private Maybe<Uri> getLogUri() {
+        return getLogFile().map(file -> ContentUriHandler.getUriForFile(this, ContentUriHandler.AUTHORITY_FILES, file));
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+        int id = item.getItemId();
+        if (id == android.R.id.home) {
+            finish();
+            return true;
+        } else if (id == R.id.menu_log_share) {
+            compositeDisposable.add(getLogUri()
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(uri -> {
+                        Log.w(TAG, "saved logs to " + uri);
+                        Intent sendIntent = new Intent(Intent.ACTION_SEND);
+                        sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                        String type = getContentResolver().getType(uri);
+                        sendIntent.setDataAndType(uri, type);
+                        sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
+                        startActivity(Intent.createChooser(sendIntent, null));
+                    }, e -> Snackbar.make(binding.getRoot(), "Error sharing logs: " + e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show()));
+            return true;
+        } else if (id == R.id.menu_log_save) {
+            compositeDisposable.add(getLogFile()
+                    .subscribe(file -> {
+                        mCurrentFile = file;
+                        fileSaver.launch(file.getName());
+                    }));
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    void startLogging() {
+        binding.logView.setText("");
+        disposable = mHardwareService.startLogs()
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(message -> {
+                    binding.logView.setText(message);
+                    binding.scroll.post(() -> binding.scroll.fullScroll(View.FOCUS_DOWN));
+                }, e -> Log.w(TAG, "Error in logger", e));
+        compositeDisposable.add(disposable);
+        setButtonState(true);
+    }
+
+    void stopLogging() {
+        disposable.dispose();
+        disposable = null;
+        mHardwareService.stopLogs();
+        setButtonState(false);
+    }
+
+    void setButtonState(boolean logging) {
+        binding.fab.setText(logging ? R.string.pref_logs_stop : R.string.pref_logs_start);
+        binding.fab.setBackgroundColor(ContextCompat.getColor(this, logging ? R.color.red_400 : R.color.colorSecondary));
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (disposable != null) {
+            disposable.dispose();
+            disposable = null;
+        }
+        compositeDisposable.clear();
+        super.onDestroy();
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/dependencyinjection/JamiInjectionComponent.java b/ring-android/app/src/main/java/cx/ring/dependencyinjection/JamiInjectionComponent.java
index 74375259aa0f83d33e22cb0ab44f9ee9c08f68f9..c600b3296fb2db6fcc89770c519a496543d97a2b 100755
--- a/ring-android/app/src/main/java/cx/ring/dependencyinjection/JamiInjectionComponent.java
+++ b/ring-android/app/src/main/java/cx/ring/dependencyinjection/JamiInjectionComponent.java
@@ -41,6 +41,7 @@ import cx.ring.application.JamiApplication;
 import cx.ring.client.ContactDetailsActivity;
 import cx.ring.client.ConversationSelectionActivity;
 import cx.ring.client.HomeActivity;
+import cx.ring.client.LogsActivity;
 import cx.ring.client.RingtoneActivity;
 import cx.ring.contactrequests.BlockListFragment;
 import cx.ring.contactrequests.ContactRequestsFragment;
@@ -232,4 +233,7 @@ public interface JamiInjectionComponent {
     void inject(LinkDeviceFragment linkDeviceFragment);
 
     void inject(ContactPickerFragment contactPickerFragment);
+
+    void inject(LogsActivity logsActivity);
+
 }
diff --git a/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java b/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
index 471451c79bdb5e2210420a578149f6430dd12525..df685ca7afc82928b999a9671f12eaf00751d575 100644
--- a/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
@@ -20,10 +20,9 @@
 package cx.ring.settings;
 
 import android.app.Activity;
-import android.content.DialogInterface;
+import android.content.Intent;
 import android.os.Bundle;
 
-import androidx.annotation.ArrayRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -43,6 +42,7 @@ import android.widget.Toast;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
 import cx.ring.client.HomeActivity;
+import cx.ring.client.LogsActivity;
 import cx.ring.databinding.FragSettingsBinding;
 
 import net.jami.daemon.JamiService;
@@ -142,18 +142,15 @@ public class SettingsFragment extends BaseSupportFragment<SettingsPresenter> imp
 
         binding.settingsNotification.setOnClickListener(v -> new MaterialAlertDialogBuilder(view.getContext())
                 .setTitle(getString(R.string.pref_notification_title))
-                .setSingleChoiceItems(singleItems, mNotificationVisibility, new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialogInterface, int i) {
-                        checkedItem[0] = i;
-                    }
-                })
+                .setSingleChoiceItems(singleItems, mNotificationVisibility, (dialogInterface, i) -> checkedItem[0] = i)
                 .setPositiveButton(android.R.string.ok, (dialog, id) -> {
                     mNotificationVisibility = checkedItem[0];
                     saveSettings();
                 })
                 .setNegativeButton(android.R.string.cancel, (dialog, id) -> {})
                 .show());
+
+        binding.settingsLogs.setOnClickListener(v -> startActivity(new Intent(v.getContext(), LogsActivity.class)));
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/utils/AndroidFileUtils.java b/ring-android/app/src/main/java/cx/ring/utils/AndroidFileUtils.java
index f57bf02cb87b4babbaf0475c0f08c2af8370fb76..73455d21b64d7395b1fdaf3eacbaee591ac78574 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/AndroidFileUtils.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/AndroidFileUtils.java
@@ -295,6 +295,14 @@ public class AndroidFileUtils {
         // Save a file: path for use with ACTION_VIEW intents
         return File.createTempFile(imageFileName, ".webm", getTempShareDir(context));
     }
+    public static File createLogFile(@NonNull Context context) throws IOException {
+        // Create an image file name
+        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
+        String imageFileName = "log_" + timeStamp + "_";
+
+        // Save a file: path for use with ACTION_VIEW intents
+        return File.createTempFile(imageFileName, ".log", getTempShareDir(context));
+    }
 
     /**
      * Copies a file from a uri whether locally on a remote location to the local cache
diff --git a/ring-android/app/src/main/res/drawable/baseline_article_24.xml b/ring-android/app/src/main/res/drawable/baseline_article_24.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2dce23f5599ba962e66e5da72a97820e795719e6
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/baseline_article_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/layout/activity_logs.xml b/ring-android/app/src/main/res/layout/activity_logs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..699066adc6553a93bdbc31c2715d303a4366a7d5
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/activity_logs.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".client.LogsActivity">
+
+    <com.google.android.material.appbar.AppBarLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:liftOnScroll="true">
+
+        <com.google.android.material.appbar.MaterialToolbar
+            android:id="@+id/toolbar"
+            style="@style/Widget.MaterialComponents.Toolbar.Surface"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"
+            android:background="@color/background"
+            tools:menu="@menu/logs_menu"
+            tools:title="Logs"/>
+
+    </com.google.android.material.appbar.AppBarLayout>
+
+    <androidx.core.widget.NestedScrollView
+        android:id="@+id/scroll"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+        <TextView
+            android:id="@+id/log_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:padding="@dimen/padding_medium"
+            android:textIsSelectable="true"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior"
+            tools:text="@tools:sample/lorem/random" />
+    </androidx.core.widget.NestedScrollView>
+
+    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+        android:id="@+id/fab"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|center_horizontal"
+        android:layout_margin="@dimen/fab_margin"
+        android:gravity="center"
+        android:text="@string/pref_logs_start"
+        app:icon="@drawable/baseline_article_24" />
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/frag_settings.xml b/ring-android/app/src/main/res/layout/frag_settings.xml
index 3d1fcde966023e656d6acf0a039b76d82bdad466..d65e18c4d2e0057826ef0482a828bda79b480062 100644
--- a/ring-android/app/src/main/res/layout/frag_settings.xml
+++ b/ring-android/app/src/main/res/layout/frag_settings.xml
@@ -71,7 +71,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
                     android:layout_toEndOf="@id/theme_image"
                     android:layout_below="@id/theme_title" />
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_dark_theme"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -165,7 +165,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_plugins_switch"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -285,7 +285,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_typing"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -336,7 +336,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_read"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -387,7 +387,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_block_record"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -525,7 +525,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_push_notifications"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -575,7 +575,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_place_call"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -625,7 +625,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_startup"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -675,7 +675,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
                 </LinearLayout>
 
-                <Switch
+                <com.google.android.material.switchmaterial.SwitchMaterial
                     android:id="@+id/settings_persistNotification"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
@@ -686,6 +686,56 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
             </RelativeLayout>
 
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:padding="8dp"
+                android:text="@string/pref_category_diagnostic"
+                android:textColor="@color/textColorAccent"
+                android:textSize="18sp"
+                android:layout_marginStart="64dp" />
+
+            <RelativeLayout
+                android:id="@+id/settings_logs"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:padding="@dimen/padding_large">
+
+                <ImageView
+                    android:id="@+id/system_diagnostics_image"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:contentDescription="@string/pref_persistNotification_summary"
+                    android:src="@drawable/baseline_article_24"
+                    android:layout_alignParentStart="true"
+                    android:layout_centerVertical="true"
+                    android:layout_marginEnd="32dp"/>
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerVertical="true"
+                    android:layout_toEndOf="@+id/system_diagnostics_image"
+                    android:orientation="vertical">
+
+                    <TextView
+                        style="@style/ListPrimary"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:lines="1"
+                        android:text="@string/pref_logs_title" />
+
+                    <TextView
+                        style="@style/ListSecondary"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:text="@string/pref_logs_summary" />
+
+                </LinearLayout>
+
+            </RelativeLayout>
+
         </LinearLayout>
     </cx.ring.views.BoundedScrollView>
 </RelativeLayout>
diff --git a/ring-android/app/src/main/res/menu/logs_menu.xml b/ring-android/app/src/main/res/menu/logs_menu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e698f3671203f3ab39ed8fba22b8ae2a98af0edd
--- /dev/null
+++ b/ring-android/app/src/main/res/menu/logs_menu.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".client.HomeActivity">
+
+    <item
+        android:id="@+id/menu_log_share"
+        android:icon="@drawable/baseline_share_24"
+        android:title="@string/share_label"
+        app:showAsAction="collapseActionView|always" />
+
+    <item
+        android:id="@+id/menu_log_save"
+        android:icon="@drawable/baseline_file_download_24"
+        android:title="@string/dial_number"
+        app:showAsAction="always" />
+
+</menu>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/menu/smartlist_menu.xml b/ring-android/app/src/main/res/menu/smartlist_menu.xml
index e59954d0259319421b71c9067b8af8509321e210..21fb4e1f888e0b1c1c8f0b8b5b3438a4edee8cd2 100644
--- a/ring-android/app/src/main/res/menu/smartlist_menu.xml
+++ b/ring-android/app/src/main/res/menu/smartlist_menu.xml
@@ -19,13 +19,6 @@
         android:visible="false"
         app:showAsAction="always" />
 
-    <!--
-    Created by Rohith M S from Noun Project
-    Licensed under Creative Commons :
-    http://creativecommons.org/licenses/by/3.0/us/legalcode
-    Used without any modification.
-    -->
-
     <item
         android:id="@+id/menu_overflow"
         android:orderInCategory="101"
diff --git a/ring-android/app/src/main/res/values/strings_preferences.xml b/ring-android/app/src/main/res/values/strings_preferences.xml
index dd797a66189ca691286182f22bace2f55167c66b..acf4b887dcecdf22c4907508e5e88bb4dad4963e 100644
--- a/ring-android/app/src/main/res/values/strings_preferences.xml
+++ b/ring-android/app/src/main/res/values/strings_preferences.xml
@@ -5,6 +5,7 @@
     <string name="pref_category_video">Video</string>
     <string name="pref_category_system">System</string>
     <string name="pref_category_privacy">Privacy</string>
+    <string name="pref_category_diagnostic">Diagnostics</string>
 
     <string name="pref_mobileData_title">Mobile data</string>
     <string name="pref_mobileData_summary">Allow Jami on 3G/LTE networks additionally to Wi-Fi</string>
@@ -53,6 +54,11 @@
     <string name="pref_persistNotification_title">Run in background</string>
     <string name="pref_persistNotification_summary">Allow running in background to receive calls and messages.</string>
 
+    <string name="pref_logs_title">Diagnostic logs</string>
+    <string name="pref_logs_summary">Open diagnostic log settings</string>
+    <string name="pref_logs_start">Start Logging</string>
+    <string name="pref_logs_stop">Stop logging</string>
+
     <string name="pref_typing_title">Enable typing indicators</string>
     <string name="pref_typing_summary">Send and receive typing indicators showing that a message is being typed.</string>
 
diff --git a/ring-android/libringclient/src/main/java/net/jami/services/DaemonService.java b/ring-android/libringclient/src/main/java/net/jami/services/DaemonService.java
index b50d6cb425e4af15225421667fd603e3b238a294..bbe45d2b925f26553577d9e0853871d13c12ee91 100644
--- a/ring-android/libringclient/src/main/java/net/jami/services/DaemonService.java
+++ b/ring-android/libringclient/src/main/java/net/jami/services/DaemonService.java
@@ -248,6 +248,11 @@ public class DaemonService {
         public void contactRemoved(String accountId, String uri, boolean banned) {
             mExecutor.submit(() -> mAccountService.contactRemoved(accountId, uri, banned));
         }
+
+        @Override
+        public void messageSend(String message) {
+            mHardwareService.logMessage(message);
+        }
     }
 
     class DaemonCallAndConferenceCallback extends Callback {
diff --git a/ring-android/libringclient/src/main/java/net/jami/services/HardwareService.java b/ring-android/libringclient/src/main/java/net/jami/services/HardwareService.java
index c39fd8b3328ec57d0594424e687fdb0a2e0830f1..037fb623536bb2f522b457cdbbb918440ed712f3 100644
--- a/ring-android/libringclient/src/main/java/net/jami/services/HardwareService.java
+++ b/ring-android/libringclient/src/main/java/net/jami/services/HardwareService.java
@@ -23,6 +23,7 @@ package net.jami.services;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -34,10 +35,14 @@ import net.jami.daemon.UintVect;
 import net.jami.model.Conference;
 import net.jami.model.Call;
 import net.jami.utils.Log;
+import net.jami.utils.StringUtils;
 import net.jami.utils.Tuple;
 import io.reactivex.Completable;
+import io.reactivex.Emitter;
 import io.reactivex.Observable;
+import io.reactivex.ObservableOnSubscribe;
 import io.reactivex.Scheduler;
+import io.reactivex.schedulers.Schedulers;
 import io.reactivex.subjects.BehaviorSubject;
 import io.reactivex.subjects.PublishSubject;
 import io.reactivex.subjects.Subject;
@@ -209,4 +214,52 @@ public abstract class HardwareService {
     public abstract void setDeviceOrientation(int rotation);
 
     protected abstract List<String> getVideoDevices();
+
+    private Observable<String> logs = null;
+    private Emitter<String> logEmitter = null;
+
+    synchronized public boolean isLogging() {
+        return logs != null;
+    }
+
+    synchronized public Observable<String> startLogs() {
+        if (logs == null) {
+            logs = Observable.create((ObservableOnSubscribe<String>) emitter -> {
+                Log.w(TAG, "ObservableOnSubscribe JamiService.monitor(true)");
+                logEmitter = emitter;
+                JamiService.monitor(true);
+                emitter.setCancellable(() -> {
+                    Log.w(TAG, "ObservableOnSubscribe CANCEL JamiService.monitor(false)");
+                    synchronized (HardwareService.this) {
+                        JamiService.monitor(false);
+                        logEmitter = null;
+                        logs = null;
+                    }
+                });
+            })
+                    .observeOn(Schedulers.io())
+                    .scan(new StringBuffer(1024), (sb, message) -> sb.append(message).append('\n'))
+                    .throttleLatest(500, TimeUnit.MILLISECONDS)
+                    .map(StringBuffer::toString)
+                    .replay(1)
+                    .autoConnect();
+        }
+        return logs;
+    }
+
+    synchronized public void stopLogs() {
+        if (logEmitter != null) {
+            Log.w(TAG, "stopLogs JamiService.monitor(false)");
+            JamiService.monitor(false);
+            logEmitter.onComplete();
+            logEmitter = null;
+            logs = null;
+        }
+    }
+
+    void logMessage(String message) {
+        if (logEmitter != null && !StringUtils.isEmpty(message)) {
+            logEmitter.onNext(message);
+        }
+    }
 }