diff --git a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
index 009f9301f6a0473b1107fa1544a459acb500c41e..df1273ea45365632fdd3d1f46a4d1697afba98db 100644
--- a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
@@ -157,13 +157,13 @@ public class CallActivity extends AppCompatActivity {
                             | View.SYSTEM_UI_FLAG_IMMERSIVE);
 
             CallFragment callFragment = getCallFragment();
-            if(callFragment != null) {
+            if(callFragment != null && !callFragment.isPluginsMode()) {
                 callFragment.toggleVideoPluginsCarousel(false);
             }
         }
     }
 
-    private void showSystemUI() {
+    public void showSystemUI() {
         if (mMainView != null) {
             mMainView.setSystemUiVisibility(
                     View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LOW_PROFILE
@@ -192,6 +192,8 @@ public class CallActivity extends AppCompatActivity {
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         CallFragment callFragment = getCallFragment();
         if (callFragment != null) {
+            callFragment.toggleVideoPluginsCarousel(false);
+            callFragment.displayVideoPluginsCarousel();
             return MediaButtonsHelper.handleMediaKeyCode(keyCode, callFragment)
                     || super.onKeyDown(keyCode, event);
         }
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index 146c9b1b3fb95fb82f3628c3021b67de18c9c210..e67455e951d572e400a3c0d7ccc3886eab20351a 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -672,6 +672,7 @@ public class HomeActivity extends AppCompatActivity implements BottomNavigationV
         if (fContent instanceof PluginsListSettingsFragment) {
             return;
         }
+
         fContent = new PluginsListSettingsFragment();
         getSupportFragmentManager()
                 .beginTransaction()
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
index b3348f4eae91b8fd848872e5dae56a8e9cd486e3..6a28c1b1743e608e4932815c40a34a66b237b6c7 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
@@ -120,6 +120,7 @@ import cx.ring.utils.DeviceUtils;
 import cx.ring.utils.KeyboardVisibilityManager;
 import cx.ring.utils.Log;
 import cx.ring.utils.MediaButtonsHelper;
+import cx.ring.utils.StringUtils;
 import cx.ring.views.AvatarDrawable;
 import io.reactivex.disposables.CompositeDisposable;
 
@@ -169,6 +170,9 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     private boolean toggleVideoPluginsCarousel = true;
     private final ValueAnimator animation = new ValueAnimator();
 
+    public boolean isPluginsMode() {
+        return pluginsMode;
+    }
 
     private PointF previewDrag = null;
     private final ValueAnimator previewSnapAnimation = new ValueAnimator();
@@ -336,7 +340,6 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
             mPreviewSurfaceWidth = width;
             mPreviewSurfaceHeight = height;
             presenter.previewVideoSurfaceCreated(binding.previewSurface);
-//            presenter.pluginSurfaceCreated(binding.pluginPreviewSurface);
         }
 
         @Override
@@ -349,7 +352,6 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
         @Override
         public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
             presenter.previewVideoSurfaceDestroyed();
-//            presenter.pluginSurfaceDestroyed();
             return true;
         }
 
@@ -1385,20 +1387,19 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
         if (pluginsModeFirst) {
             // Init
             callMediaHandlers = Ringservice.listCallMediaHandlers();
-            List<Drawable> videoPluginsItems = new ArrayList<>();
+            List<Drawable> videoPluginsItems = new ArrayList<>(callMediaHandlers.size() + 1);
 
+            videoPluginsItems.add(context.getDrawable(R.drawable.baseline_cancel_24));
             // Search for plugin call media handlers icons
             // If a call media handler doesn't have an icon use a standard android icon
             for (String callMediaHandler : callMediaHandlers) {
                 Map<String, String> details = getCallMediaHandlerDetails(callMediaHandler);
-                Drawable d = context.getDrawable(R.drawable.ic_jami);
-                if(details.containsKey("icoPath")){
-                     Drawable cd = PluginUtils.getIcon(details.get("icoPath"));
-                    if(cd != null) {
-                        d = cd;
-                    }
+                String drawablePath = details.get("icoPath");
+                Drawable handlerIcon = StringUtils.isEmpty(drawablePath) ? null : Drawable.createFromPath(details.get("icoPath"));
+                if (handlerIcon == null) {
+                    handlerIcon = context.getDrawable(R.drawable.ic_jami);
                 }
-                videoPluginsItems.add(d);
+                videoPluginsItems.add(handlerIcon);
             }
 
             rp.updateData(videoPluginsItems);
@@ -1418,20 +1419,29 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
             // Start loading the first or previous plugin if one was active
             if(callMediaHandlers.size() > 0) {
                 // If no previous plugin was active, take the first, else previous
-                int position = (previousPluginPosition == -1)? 0 :previousPluginPosition;
-                String callMediaId = callMediaHandlers.get(position);
-                toggleCallMediaHandler(callMediaId, true);
-                previousPluginPosition = position;
+                int position;
+                if(previousPluginPosition < 1) {
+                    rp.scrollToPosition(1);
+                    position = 1;
+                    previousPluginPosition = 1;
+                } else {
+                    position = previousPluginPosition;
+                }
+                if (position > 0) {
+                    String callMediaId = callMediaHandlers.get(position-1);
+                    toggleCallMediaHandler(callMediaId, true);
+                }
             }
 
         } else {
             //change preview image
             displayVideoSurface(true,true);
-            if (previousPluginPosition != -1) {
+            if (previousPluginPosition > 0) {
                 String callMediaId = callMediaHandlers.
-                        get(previousPluginPosition);
+                        get(previousPluginPosition-1);
 
                 toggleCallMediaHandler(callMediaId, false);
+                rp.scrollToPosition(previousPluginPosition);
             }
             binding.recyclerPicker.setVisibility(View.GONE);
             movePreview(false);
@@ -1446,18 +1456,44 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     @Override
     public void onItemSelected(int position) {
         Log.i(TAG, "selected position: " + position);
-        if (previousPluginPosition != position) {
+        /** If there was a different plugin before, unload it
+         * If previousPluginPosition = -1 or 0, there was no plugin
+         */
+        if (previousPluginPosition > 0) {
+            String callMediaId = callMediaHandlers.get(previousPluginPosition-1);
+            toggleCallMediaHandler(callMediaId, false);
+        }
+
+        if (position > 0) {
+            previousPluginPosition = position;
+            String callMediaId = callMediaHandlers.get(position-1);
+            toggleCallMediaHandler(callMediaId, true);
+        }
+    }
+
+
+    /**
+     * Called whenever a plugin drawable in the recycler picker is clicked
+     * @param position
+     */
+    @Override
+    public void onItemClicked(int position) {
+        Log.i(TAG, "selected position: " + position);
+        if (position == 0) {
             /** If there was a different plugin before, unload it
-             * If previousPluginPosition = -1, there was no plugin
+             * If previousPluginPosition = -1 or 0, there was no plugin
              */
-            if (previousPluginPosition != -1) {
-                String callMediaId = callMediaHandlers.get(previousPluginPosition);
+            if (previousPluginPosition > 0) {
+                String callMediaId = callMediaHandlers.get(previousPluginPosition-1);
                 toggleCallMediaHandler(callMediaId, false);
+                rp.scrollToPosition(previousPluginPosition);
             }
 
-            previousPluginPosition = position;
-            String callMediaId = callMediaHandlers.get(position);
-            toggleCallMediaHandler(callMediaId, true);
+            CallActivity callActivity = (CallActivity) getActivity();
+            callActivity.showSystemUI();
+
+            toggleVideoPluginsCarousel(false);
+            displayVideoPluginsCarousel();
         }
     }
 }
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/plugins/PluginPreferences.java b/ring-android/app/src/main/java/cx/ring/plugins/PluginPreferences.java
new file mode 100644
index 0000000000000000000000000000000000000000..33a04daa3303f05be33612f89b44f4d969b159fe
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/plugins/PluginPreferences.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright (C) 2004-2019 Savoir-faire Linux Inc.
+ *
+ *  Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *           Romain Bertozzi <romain.bertozzi@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, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package cx.ring.plugins;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import cx.ring.R;
+import cx.ring.databinding.FragPluginSettingsBinding;
+import cx.ring.settings.pluginssettings.PluginDetails;
+
+public class PluginPreferences extends Preference {
+    private PluginDetails mPluginDetails;
+
+    private View.OnClickListener resetClickListener;
+    private View.OnClickListener installClickListener;
+
+    public void setResetClickListener(View.OnClickListener clickListener) {
+        resetClickListener = clickListener;
+    }
+
+    public void setInstallClickListener(View.OnClickListener clickListener) {
+        installClickListener = clickListener;
+    }
+
+    public PluginPreferences(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public PluginPreferences(Context context, PluginDetails pluginDetails) {
+        super(context);
+        mPluginDetails = pluginDetails;
+        setLayoutResource(R.layout.frag_plugin_settings);
+    }
+
+    public PluginPreferences(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public PluginPreferences(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        FragPluginSettingsBinding binding = FragPluginSettingsBinding.bind(holder.itemView);
+
+        if (mPluginDetails != null) {
+            binding.pluginSettingIcon.setImageDrawable(mPluginDetails.getIcon());
+            binding.pluginSettingTitle.setText(mPluginDetails.getName());
+        }
+
+        if (resetClickListener != null) {
+            binding.pluginSettingReset.setOnClickListener(resetClickListener);
+        }
+
+        if (installClickListener != null) {
+            binding.pluginSettingInstall.setOnClickListener(installClickListener);
+        }
+    }
+
+}
diff --git a/ring-android/app/src/main/java/cx/ring/plugins/PluginUtils.java b/ring-android/app/src/main/java/cx/ring/plugins/PluginUtils.java
index f68ddf31e6be0458d3bdd15d3ad5a6749ceb03d5..3c5da8ba37c03a1fb736a1481cdf73049c01c574 100644
--- a/ring-android/app/src/main/java/cx/ring/plugins/PluginUtils.java
+++ b/ring-android/app/src/main/java/cx/ring/plugins/PluginUtils.java
@@ -32,46 +32,25 @@ public class PluginUtils {
         tree(mContext.getFilesDir() + File.separator+ "plugins",0);
         tree(mContext.getCacheDir().getAbsolutePath(),0);
 
-        List<PluginDetails> pluginsList = new ArrayList<>();
-
         List<String> pluginsPaths = Ringservice.listAvailablePlugins();
 
-        for(String pluginPath : pluginsPaths) {
+        List<PluginDetails> pluginsList = new ArrayList<>(pluginsPaths.size());
+        for (String pluginPath : pluginsPaths) {
             File pluginFolder = new File(pluginPath);
-            if(pluginFolder.isDirectory()){
+            if(pluginFolder.isDirectory()) {
                 //We use the absolute path of a plugin as a preference name for uniqueness
-                SharedPreferences sp = mContext.getSharedPreferences(
-                        pluginFolder.getName(), MODE_PRIVATE);
-
+                //TODO remove and use enabled information from daemon
+                SharedPreferences sp = mContext.getSharedPreferences(pluginFolder.getName(), MODE_PRIVATE);
                 boolean enabled = sp.getBoolean(PLUGIN_ENABLED,false);
 
                 pluginsList.add(new PluginDetails(
                         pluginFolder.getName(),
-                        pluginFolder.getAbsolutePath(),enabled));
+                        pluginFolder.getAbsolutePath(), enabled));
             }
         }
         return pluginsList;
     }
 
-    public static String getABI(){
-        return Build.SUPPORTED_ABIS[0];
-    }
-
-    /**
-     * Checks if there is a file at the indicated path and converts if to a drawable if possible
-     * @param iconPath String representing the absolute icon path
-     * @return Drawable of the icon
-     */
-    public static Drawable getIcon(String iconPath) {
-        Drawable icon = null;
-        File file = new File(iconPath);
-        Log.i(TAG, "Icon path: " + iconPath);
-        if(file.exists()) {
-            icon = Drawable.createFromPath(iconPath);
-        }
-        return icon;
-    }
-
     /**
      * Loads the so file and instantiates the plugin init function (toggle on)
      * @param path root path of the plugin
diff --git a/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPicker.java b/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPicker.java
index f648d3c590c9990dffae918f6a18fa4ebaef5f36..fd1a83b1e72e544242b01c6f92548aa3af3a7dc7 100644
--- a/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPicker.java
+++ b/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPicker.java
@@ -57,8 +57,9 @@ public class RecyclerPicker implements RecyclerPickerAdapter.ItemClickListener{
         int currentPos = mLayoutManager.findFirstVisibleItemPosition();
         if(position != currentPos) {
             mRecyclerView.smoothScrollToPosition(position);
-        } else {
             mItemSelectedListener.onItemSelected(position);
+        } else {
+            mItemSelectedListener.onItemClicked(position);
         }
 
     }
diff --git a/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPickerLayoutManager.java b/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPickerLayoutManager.java
index 9fa779b81b31336c91ed65c42b873149846132bb..c93c1ffa8046de8dd041697ba1f067b9cfc4b838 100644
--- a/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPickerLayoutManager.java
+++ b/ring-android/app/src/main/java/cx/ring/plugins/RecyclerPicker/RecyclerPickerLayoutManager.java
@@ -99,5 +99,6 @@ public class RecyclerPickerLayoutManager extends LinearLayoutManager {
 
     public interface ItemSelectedListener {
         void onItemSelected(int position);
+        void onItemClicked(int position);
     }
 }
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 44696b1574df5ebf1a14519a3abf3f64bcb0dbfb..edb0ce785e46ec06eeb5c962315f240816759c55 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
@@ -134,8 +134,9 @@ public class SettingsFragment extends BaseSupportFragment<SettingsPresenter> imp
                 .show());
         binding.settingsPluginsLayout.setOnClickListener(v -> {
             HomeActivity activity = (HomeActivity) getActivity();
-            if (activity != null && presenter.getPluginsEnabled())
+            if (activity != null && presenter.getPluginsEnabled()){
                 activity.goToPluginsListSettings();
+            }
         });
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginSettingsFragment.java b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginSettingsFragment.java
index 408e505e649c9767ccffd763ade59ec1cf700986..f0a9147b68f18db25c6118d0ad66d10ad9072345 100644
--- a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginSettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginSettingsFragment.java
@@ -1 +1,387 @@
-package cx.ring.settings.pluginssettings;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.CheckBoxPreference;
import androidx.preference.DialogPreference;
import androidx.preference.DropDownPreference;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SeekBarPreference;
import androidx.preference.SwitchPreference;
import androidx.preference.TwoStatePreference;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cx.ring.R;
import cx.ring.client.HomeActivity;
import cx.ring.daemon.Ringservice;
import cx.ring.plugins.ButtonPreference.ButtonPreference;

import static cx.ring.plugins.PluginUtils.getOrElse;
import static cx.ring.plugins.PluginUtils.stringListToListString;

public class PluginSettingsFragment extends PreferenceFragmentCompat {
    public static final String TAG = PluginSettingsFragment.class.getSimpleName();
    private Context mContext;
    private List<Map<String, String>> mPreferencesAttributes;
    private PluginDetails pluginDetails;

    public static PluginSettingsFragment newInstance(PluginDetails pluginDetails) {
        Bundle args = new Bundle();
        args.putString("name", pluginDetails.getName());
        args.putString("rootPath", pluginDetails.getRootPath());
        args.putBoolean("enabled", pluginDetails.isEnabled());
        PluginSettingsFragment psf = new PluginSettingsFragment();
        psf.setArguments(args);
        return psf;
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = requireActivity();

        Bundle arguments = getArguments();

        if (arguments != null && arguments.getString("name") != null
                && arguments.getString("rootPath") != null) {
            pluginDetails = new PluginDetails(arguments.getString("name"),
                    arguments.getString("rootPath"), arguments.getBoolean("enabled"));

            mPreferencesAttributes = pluginDetails.getPluginPreferences();

            PreferenceManager preferenceManager = getPreferenceManager();
            PluginPreferencesDataStore ppds = new PluginPreferencesDataStore(pluginDetails);
            preferenceManager.setPreferenceDataStore(ppds);
            setHasOptionsMenu(true);
        }
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View root = super.onCreateView(inflater, container, savedInstanceState);
        PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(mContext);
        screen.addPreference(createResetPreference());
        for (Preference preference : createPreferences(mPreferencesAttributes)) {
            screen.addPreference(preference);
        }

        setPreferenceScreen(screen);
        return root;
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        inflater.inflate(R.menu.plugin_edition, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch (item.getItemId()) {
            case R.id.menuitem_delete:
                AlertDialog alertDialog = new MaterialAlertDialogBuilder(mContext)
                        .setMessage(R.string.account_delete_dialog_message)
                        .setTitle(R.string.plugin_uninstall_title)
                        .setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
                            Ringservice.uninstallPlugin(pluginDetails.getRootPath());
                            ((HomeActivity) requireActivity()).popFragmentImmediate();
                        })
                        .setNegativeButton(android.R.string.cancel, null)
                        .create();
                alertDialog.show();
                break;
            default:
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * Takes a list of preferences attributes map
     * Creates a preference View for each map of attributes in the preference
     *
     * @param preferencesAttributes A list of preferences attributes
     * @return list of preferences
     */
    private List<Preference> createPreferences(List<Map<String, String>> preferencesAttributes) {
        List<Preference> preferencesViews = new ArrayList<>();
        if (preferencesAttributes != null) {
            for (Map<String, String> preferenceAttributes : preferencesAttributes) {
                String type = preferenceAttributes.get("type");
                // Call for each type the appropriate function member
                if (type != null) {
                    switch (type) {
                        case "CheckBox":
                            preferencesViews.add(createCheckBoxPreference(preferenceAttributes));
                            break;
                        case "DropDown":
                            preferencesViews.add(createDropDownPreference(preferenceAttributes));
                            break;
                        case "EditText":
                            preferencesViews.add(createEditTextPreference(preferenceAttributes));
                            break;
                        case "List":
                            preferencesViews.add(createListPreference(preferenceAttributes));
                            break;
                        case "MultiSelectList":
                            preferencesViews.
                                    add(createMultiSelectListPreference(preferenceAttributes));
                            break;
                        case "SeekBar":
                            preferencesViews.add(createSeekBarPreference(preferenceAttributes));
                            break;
                        case "Switch":
                            preferencesViews.add(createSwitchPreference(preferenceAttributes));
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        return preferencesViews;
    }

    private Preference createResetPreference() {
        ButtonPreference preference = new ButtonPreference(mContext);
        preference.setTitle(R.string.plugin_reset_preferences);
        preference.setSummary(R.string.plugin_reset_preferences_summary);
        preference.setIcon(R.drawable.baseline_cancel_24);
        preference.setPersistent(false);
        preference.setKey("uninstall");
        preference.setText("Reset");
        preference.setClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new MaterialAlertDialogBuilder(mContext)
                        .setTitle(preference.getTitle())
                        .setMessage(R.string.plugin_reset_preferences_ask)
                        .setPositiveButton(android.R.string.ok, (dialog, id) -> {
                            Ringservice.resetPluginPreferencesValues(pluginDetails.getRootPath());
                            ((HomeActivity) requireActivity()).popFragmentImmediate();
                        })
                        .setNegativeButton(android.R.string.cancel, (dialog, whichButton) -> {
                            /* Terminate with no action */
                        })
                        .show();
            }
        });
        return preference;
    }

    private CheckBoxPreference createCheckBoxPreference(Map<String, String> preferenceModel) {
        CheckBoxPreference preference = new CheckBoxPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setTwoStatePreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    private DropDownPreference createDropDownPreference(Map<String, String> preferenceModel) {
        DropDownPreference preference = new DropDownPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setListPreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    private EditTextPreference createEditTextPreference(Map<String, String> preferenceModel) {
        EditTextPreference preference = new EditTextPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setDialogPreferenceAttributes(preference, preferenceModel);
        setEditTextAttributes(preference, preferenceModel);
        return preference;
    }

    private ListPreference createListPreference(Map<String, String> preferenceModel) {
        ListPreference preference = new ListPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setListPreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    private MultiSelectListPreference createMultiSelectListPreference(
            Map<String, String> preferenceModel) {
        MultiSelectListPreference preference = new MultiSelectListPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setMultiSelectListPreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    private SwitchPreference createSwitchPreference(Map<String, String> preferenceModel) {
        SwitchPreference preference = new SwitchPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setTwoStatePreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    private SeekBarPreference createSeekBarPreference(Map<String, String> preferenceModel) {
        SeekBarPreference preference = new SeekBarPreference(mContext);
        setPreferenceAttributes(preference, preferenceModel);
        setSeekBarPreferenceAttributes(preference, preferenceModel);
        return preference;
    }

    /**
     * Sets attributes that are common in the Preference base class
     *
     * @param preference      the preference
     * @param preferenceModel the map of attributes
     */
    private void setPreferenceAttributes(Preference preference,
                                         Map<String, String> preferenceModel) {
        String key = preferenceModel.get("key");
        preference.setKey(key);
        preference.setTitle(getOrElse(preferenceModel.get("title"), ""));
        preference.setSummary(getOrElse(preferenceModel.get("summary"), ""));
    }

    //TODO : add drawable icon
    private void setDialogPreferenceAttributes(DialogPreference preference,
                                               Map<String, String> preferenceModel) {
        String dialogTitle = getOrElse(preferenceModel.get("dialogTitle"), "");
        String dialogMessage = getOrElse(preferenceModel.get("dialogMessage"), "");
        String positiveButtonText = getOrElse(preferenceModel.get("positiveButtonText"), "");
        String negativeButtonText = getOrElse(preferenceModel.get("negativeButtonText"), "");

        if (!dialogTitle.isEmpty()) {
            preference.setDialogTitle(dialogTitle);
        }

        if (!dialogMessage.isEmpty()) {
            preference.setDialogTitle(dialogMessage);
        }

        if (!positiveButtonText.isEmpty()) {
            preference.setPositiveButtonText(positiveButtonText);
        }

        if (!negativeButtonText.isEmpty()) {
            preference.setNegativeButtonText(negativeButtonText);
        }
    }

    /**
     * Sets attributes specific to EditTextPreference
     * Here we set the default value
     *
     * @param preference      EditTextPreference
     * @param preferenceModel the map of attributes
     */
    private void setEditTextAttributes(EditTextPreference preference,
                                       Map<String, String> preferenceModel) {
        preference.setDefaultValue(preferenceModel.get("defaultValue"));
    }

    /**
     * Sets specific attributes for Preference that have for a base class ListPreference
     * Sets the entries, entryValues and defaultValue
     *
     * @param preference      the list preference
     * @param preferenceModel the map of attributes
     */
    private void setListPreferenceAttributes(ListPreference preference,
                                             Map<String, String> preferenceModel) {
        setDialogPreferenceAttributes(preference, preferenceModel);
        String entries = getOrElse(preferenceModel.get("entries"), "[]");
        preference.setEntries(stringListToListString(entries).
                toArray(new CharSequence[ 0 ]));
        String entryValues = getOrElse(preferenceModel.get("entryValues"), "[]");
        preference.setEntryValues(stringListToListString(entryValues).
                toArray(new CharSequence[ 0 ]));
        preference.setDefaultValue(preferenceModel.get("defaultValue"));
    }

    /**
     * Sets specific attributes for Preference that have for a base class MultiSelectListPreference
     * Sets the entries, entryValues and defaultValues
     *
     * @param preference      the multi select list preference
     * @param preferenceModel the map of attributes
     */
    private void setMultiSelectListPreferenceAttributes(MultiSelectListPreference preference,
                                                        Map<String, String> preferenceModel) {
        setDialogPreferenceAttributes(preference, preferenceModel);
        String entries = getOrElse(preferenceModel.get("entries"), "[]");
        preference.setEntries(stringListToListString(entries).
                toArray(new CharSequence[ 0 ]));
        String entryValues = getOrElse(preferenceModel.get("entryValues"), "[]");
        preference.setEntryValues(stringListToListString(entryValues).
                toArray(new CharSequence[ 0 ]));
        String defaultValues = getOrElse(preferenceModel.get("defaultValue"), "[]");
        preference.setEntryValues(stringListToListString(entryValues).
                toArray(new CharSequence[ 0 ]));
        Set<CharSequence> set = new HashSet<>(stringListToListString(defaultValues));
        preference.setDefaultValue(set);
    }

    /**
     * Sets specific attributes for setSeekBarPreference
     *
     * @param preference      the seek bar preference
     * @param preferenceModel the map of attributes
     */
    private void setSeekBarPreferenceAttributes(SeekBarPreference preference,
                                                Map<String, String> preferenceModel) {
        int min = 0, max = 1, increment = 1;
        int defaultValue = 0;
        try {
            min = Integer.parseInt(getOrElse(preferenceModel.get("min"), "0"));
            max = Integer.parseInt(getOrElse(preferenceModel.get("max"), "1"));
            increment = Integer.parseInt(getOrElse(preferenceModel.get("increment"), "1"));
            defaultValue = Integer.parseInt(getOrElse(preferenceModel.get("defaultValue"), "[0"));
        } catch (NumberFormatException e) {
            Log.e(TAG, e.toString());
        }
        preference.setMin(min);
        preference.setMax(max);
        preference.setSeekBarIncrement(increment);
        preference.setAdjustable(Boolean.valueOf(getOrElse(preferenceModel.get("adjustable"),
                "true")));
        preference.setDefaultValue(defaultValue);
        preference.setShowSeekBarValue(true);
        preference.setUpdatesContinuously(true);
    }

    /**
     * Sets specific attributes for twoStatePreference like Switch and CheckBox
     *
     * @param preference      the two state preference
     * @param preferenceModel the map of attributes
     */
    private void setTwoStatePreferenceAttributes(TwoStatePreference preference,
                                                 Map<String, String> preferenceModel) {
        preference.setDefaultValue(Boolean.valueOf(preferenceModel.get("defaultValue")));
    }
}
\ No newline at end of file
+package cx.ring.settings.pluginssettings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.preference.CheckBoxPreference;
+import androidx.preference.DialogPreference;
+import androidx.preference.DropDownPreference;
+import androidx.preference.EditTextPreference;
+import androidx.preference.ListPreference;
+import androidx.preference.MultiSelectListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SeekBarPreference;
+import androidx.preference.SwitchPreference;
+import androidx.preference.TwoStatePreference;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.prefs.Preferences;
+
+import cx.ring.R;
+import cx.ring.client.HomeActivity;
+import cx.ring.daemon.Ringservice;
+import cx.ring.plugins.ButtonPreference.ButtonPreference;
+import cx.ring.plugins.PluginPreferences;
+
+import static android.content.Context.MODE_PRIVATE;
+import static cx.ring.plugins.PluginUtils.PLUGIN_ENABLED;
+import static cx.ring.plugins.PluginUtils.getOrElse;
+import static cx.ring.plugins.PluginUtils.stringListToListString;
+
+public class PluginSettingsFragment extends PreferenceFragmentCompat {
+    public static final String TAG = PluginSettingsFragment.class.getSimpleName();
+    private Context mContext;
+    private List<Map<String, String>> mPreferencesAttributes;
+    private PluginDetails pluginDetails;
+
+    public static PluginSettingsFragment newInstance(PluginDetails pluginDetails) {
+        Bundle args = new Bundle();
+        args.putString("name", pluginDetails.getName());
+        args.putString("rootPath", pluginDetails.getRootPath());
+        args.putBoolean("enabled", pluginDetails.isEnabled());
+        PluginSettingsFragment psf = new PluginSettingsFragment();
+        psf.setArguments(args);
+        return psf;
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mContext = requireActivity();
+
+        Bundle arguments = getArguments();
+
+        if (arguments != null && arguments.getString("name") != null
+                && arguments.getString("rootPath") != null) {
+            pluginDetails = new PluginDetails(arguments.getString("name"),
+                    arguments.getString("rootPath"), arguments.getBoolean("enabled"));
+
+            mPreferencesAttributes = pluginDetails.getPluginPreferences();
+
+            PreferenceManager preferenceManager = getPreferenceManager();
+            PluginPreferencesDataStore ppds = new PluginPreferencesDataStore(pluginDetails);
+            preferenceManager.setPreferenceDataStore(ppds);
+            setHasOptionsMenu(true);
+        }
+    }
+
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+                             @Nullable Bundle savedInstanceState) {
+        View root = super.onCreateView(inflater, container, savedInstanceState);
+
+        PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(mContext);
+        screen.addPreference(createHeadPreference());
+        for (Preference preference : createPreferences(mPreferencesAttributes)) {
+            screen.addPreference(preference);
+        }
+        setPreferenceScreen(screen);
+        return root;
+    }
+
+    @Override
+    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+        inflater.inflate(R.menu.plugin_edition, menu);
+        MenuItem item = menu.findItem(R.id.menuitem_delete);
+        item.setVisible(false);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    /**
+     * Takes a list of preferences attributes map
+     * Creates a preference View for each map of attributes in the preference
+     *
+     * @param preferencesAttributes A list of preferences attributes
+     * @return list of preferences
+     */
+    private List<Preference> createPreferences(List<Map<String, String>> preferencesAttributes) {
+        List<Preference> preferencesViews = new ArrayList<>();
+        if (preferencesAttributes != null) {
+            for (Map<String, String> preferenceAttributes : preferencesAttributes) {
+                String type = preferenceAttributes.get("type");
+                // Call for each type the appropriate function member
+                if (type != null) {
+                    switch (type) {
+                        case "CheckBox":
+                            preferencesViews.add(createCheckBoxPreference(preferenceAttributes));
+                            break;
+                        case "DropDown":
+                            preferencesViews.add(createDropDownPreference(preferenceAttributes));
+                            break;
+                        case "EditText":
+                            preferencesViews.add(createEditTextPreference(preferenceAttributes));
+                            break;
+                        case "List":
+                            preferencesViews.add(createListPreference(preferenceAttributes));
+                            break;
+                        case "MultiSelectList":
+                            preferencesViews.
+                                    add(createMultiSelectListPreference(preferenceAttributes));
+                            break;
+                        case "SeekBar":
+                            preferencesViews.add(createSeekBarPreference(preferenceAttributes));
+                            break;
+                        case "Switch":
+                            preferencesViews.add(createSwitchPreference(preferenceAttributes));
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+
+        return preferencesViews;
+    }
+
+    private Preference createHeadPreference()
+    {
+        PluginPreferences preference = new PluginPreferences(mContext, pluginDetails);
+        preference.setResetClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new MaterialAlertDialogBuilder(mContext)
+                        .setTitle(preference.getTitle())
+                        .setMessage(R.string.plugin_reset_preferences_ask)
+                        .setPositiveButton(android.R.string.ok, (dialog, id) -> {
+                            Ringservice.resetPluginPreferencesValues(pluginDetails.getRootPath());
+                            ((HomeActivity) requireActivity()).popFragmentImmediate();
+                        })
+                        .setNegativeButton(android.R.string.cancel, (dialog, whichButton) -> {
+                            /* Terminate with no action */
+                        })
+                        .show();
+            }
+        });
+        preference.setInstallClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new MaterialAlertDialogBuilder(mContext)
+                        .setMessage(R.string.account_delete_dialog_message)
+                        .setTitle(R.string.plugin_uninstall_title)
+                        .setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
+                            SharedPreferences sp = mContext.getSharedPreferences(
+                                    pluginDetails.getName(), MODE_PRIVATE);
+
+                            SharedPreferences.Editor preferencesEditor = sp.edit();
+                            pluginDetails.setEnabled(false);
+                            preferencesEditor.putBoolean(PLUGIN_ENABLED, pluginDetails.isEnabled());
+                            preferencesEditor.apply();
+                            Ringservice.uninstallPlugin(pluginDetails.getRootPath());
+                            ((HomeActivity) requireActivity()).popFragmentImmediate();
+                        })
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .show();
+            }
+        });
+        return preference;
+    }
+
+    private CheckBoxPreference createCheckBoxPreference(Map<String, String> preferenceModel) {
+        CheckBoxPreference preference = new CheckBoxPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setTwoStatePreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private DropDownPreference createDropDownPreference(Map<String, String> preferenceModel) {
+        DropDownPreference preference = new DropDownPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setListPreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private EditTextPreference createEditTextPreference(Map<String, String> preferenceModel) {
+        EditTextPreference preference = new EditTextPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setDialogPreferenceAttributes(preference, preferenceModel);
+        setEditTextAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private ListPreference createListPreference(Map<String, String> preferenceModel) {
+        ListPreference preference = new ListPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setListPreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private MultiSelectListPreference createMultiSelectListPreference(
+            Map<String, String> preferenceModel) {
+        MultiSelectListPreference preference = new MultiSelectListPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setMultiSelectListPreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private SwitchPreference createSwitchPreference(Map<String, String> preferenceModel) {
+        SwitchPreference preference = new SwitchPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setTwoStatePreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    private SeekBarPreference createSeekBarPreference(Map<String, String> preferenceModel) {
+        SeekBarPreference preference = new SeekBarPreference(mContext);
+        setPreferenceAttributes(preference, preferenceModel);
+        setSeekBarPreferenceAttributes(preference, preferenceModel);
+        return preference;
+    }
+
+    /**
+     * Sets attributes that are common in the Preference base class
+     *
+     * @param preference      the preference
+     * @param preferenceModel the map of attributes
+     */
+    private void setPreferenceAttributes(Preference preference,
+                                         Map<String, String> preferenceModel) {
+        String key = preferenceModel.get("key");
+        preference.setKey(key);
+        preference.setTitle(getOrElse(preferenceModel.get("title"), ""));
+        preference.setSummary(getOrElse(preferenceModel.get("summary"), ""));
+    }
+
+    //TODO : add drawable icon
+    private void setDialogPreferenceAttributes(DialogPreference preference,
+                                               Map<String, String> preferenceModel) {
+        String dialogTitle = getOrElse(preferenceModel.get("dialogTitle"), "");
+        String dialogMessage = getOrElse(preferenceModel.get("dialogMessage"), "");
+        String positiveButtonText = getOrElse(preferenceModel.get("positiveButtonText"), "");
+        String negativeButtonText = getOrElse(preferenceModel.get("negativeButtonText"), "");
+
+        if (!dialogTitle.isEmpty()) {
+            preference.setDialogTitle(dialogTitle);
+        }
+
+        if (!dialogMessage.isEmpty()) {
+            preference.setDialogTitle(dialogMessage);
+        }
+
+        if (!positiveButtonText.isEmpty()) {
+            preference.setPositiveButtonText(positiveButtonText);
+        }
+
+        if (!negativeButtonText.isEmpty()) {
+            preference.setNegativeButtonText(negativeButtonText);
+        }
+    }
+
+    /**
+     * Sets attributes specific to EditTextPreference
+     * Here we set the default value
+     *
+     * @param preference      EditTextPreference
+     * @param preferenceModel the map of attributes
+     */
+    private void setEditTextAttributes(EditTextPreference preference,
+                                       Map<String, String> preferenceModel) {
+        preference.setDefaultValue(preferenceModel.get("defaultValue"));
+    }
+
+    /**
+     * Sets specific attributes for Preference that have for a base class ListPreference
+     * Sets the entries, entryValues and defaultValue
+     *
+     * @param preference      the list preference
+     * @param preferenceModel the map of attributes
+     */
+    private void setListPreferenceAttributes(ListPreference preference,
+                                             Map<String, String> preferenceModel) {
+        setDialogPreferenceAttributes(preference, preferenceModel);
+        String entries = getOrElse(preferenceModel.get("entries"), "[]");
+        preference.setEntries(stringListToListString(entries).
+                toArray(new CharSequence[ 0 ]));
+        String entryValues = getOrElse(preferenceModel.get("entryValues"), "[]");
+        preference.setEntryValues(stringListToListString(entryValues).
+                toArray(new CharSequence[ 0 ]));
+        preference.setDefaultValue(preferenceModel.get("defaultValue"));
+    }
+
+    /**
+     * Sets specific attributes for Preference that have for a base class MultiSelectListPreference
+     * Sets the entries, entryValues and defaultValues
+     *
+     * @param preference      the multi select list preference
+     * @param preferenceModel the map of attributes
+     */
+    private void setMultiSelectListPreferenceAttributes(MultiSelectListPreference preference,
+                                                        Map<String, String> preferenceModel) {
+        setDialogPreferenceAttributes(preference, preferenceModel);
+        String entries = getOrElse(preferenceModel.get("entries"), "[]");
+        preference.setEntries(stringListToListString(entries).
+                toArray(new CharSequence[ 0 ]));
+        String entryValues = getOrElse(preferenceModel.get("entryValues"), "[]");
+        preference.setEntryValues(stringListToListString(entryValues).
+                toArray(new CharSequence[ 0 ]));
+        String defaultValues = getOrElse(preferenceModel.get("defaultValue"), "[]");
+        preference.setEntryValues(stringListToListString(entryValues).
+                toArray(new CharSequence[ 0 ]));
+        Set<CharSequence> set = new HashSet<>(stringListToListString(defaultValues));
+        preference.setDefaultValue(set);
+    }
+
+    /**
+     * Sets specific attributes for setSeekBarPreference
+     *
+     * @param preference      the seek bar preference
+     * @param preferenceModel the map of attributes
+     */
+    private void setSeekBarPreferenceAttributes(SeekBarPreference preference,
+                                                Map<String, String> preferenceModel) {
+        int min = 0, max = 1, increment = 1;
+        int defaultValue = 0;
+        try {
+            min = Integer.parseInt(getOrElse(preferenceModel.get("min"), "0"));
+            max = Integer.parseInt(getOrElse(preferenceModel.get("max"), "1"));
+            increment = Integer.parseInt(getOrElse(preferenceModel.get("increment"), "1"));
+            defaultValue = Integer.parseInt(getOrElse(preferenceModel.get("defaultValue"), "[0"));
+        } catch (NumberFormatException e) {
+            Log.e(TAG, e.toString());
+        }
+        preference.setMin(min);
+        preference.setMax(max);
+        preference.setSeekBarIncrement(increment);
+        preference.setAdjustable(Boolean.valueOf(getOrElse(preferenceModel.get("adjustable"),
+                "true")));
+        preference.setDefaultValue(defaultValue);
+        preference.setShowSeekBarValue(true);
+        preference.setUpdatesContinuously(true);
+    }
+
+    /**
+     * Sets specific attributes for twoStatePreference like Switch and CheckBox
+     *
+     * @param preference      the two state preference
+     * @param preferenceModel the map of attributes
+     */
+    private void setTwoStatePreferenceAttributes(TwoStatePreference preference,
+                                                 Map<String, String> preferenceModel) {
+        preference.setDefaultValue(Boolean.valueOf(preferenceModel.get("defaultValue")));
+    }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListAdapter.java b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListAdapter.java
index 61c3f51a7c8596581e49bd181f9fdab91a847ee1..8e0a1734356b7451bf35cf2d3aaaa1bfeb3664ec 100644
--- a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListAdapter.java
+++ b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListAdapter.java
@@ -49,6 +49,7 @@ public class PluginsListAdapter extends RecyclerView.Adapter<PluginsListAdapter.
 
     public void updatePluginsList(List<PluginDetails> listPlugins) {
         mList = listPlugins;
+
         notifyDataSetChanged();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListSettingsFragment.java b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListSettingsFragment.java
index c9319d9a159f7ddbdcafdaa4a35e477b72084b06..4b6b73a44298e35f0fe944e2fe116fff80966ed9 100644
--- a/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListSettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/settings/pluginssettings/PluginsListSettingsFragment.java
@@ -24,6 +24,7 @@ import com.google.android.material.snackbar.Snackbar;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.List;
 
 import cx.ring.R;
 import cx.ring.client.HomeActivity;
@@ -85,13 +86,16 @@ public class PluginsListSettingsFragment extends Fragment implements PluginsList
             startActivityForResult(intent, ARCHIVE_REQUEST_CODE);
         });
 
+        ((HomeActivity) requireActivity()).
+                setToolbarState(R.string.menu_item_plugin_list);
+
         return pluginsSettingsList;
     }
 
     @Override
     public void onResume() {
         ((HomeActivity) requireActivity()).
-                setToolbarState(R.string.menu_item_settings);
+                setToolbarState(R.string.menu_item_plugin_list);
         super.onResume();
     }
 
@@ -146,6 +150,7 @@ public class PluginsListSettingsFragment extends Fragment implements PluginsList
 
     private String installPluginFile(File pluginFile, boolean force) throws IOException{
         int i = Ringservice.installPlugin(pluginFile.getAbsolutePath(), force);
+
         // Free the cache
         boolean cacheFileFreed = pluginFile.delete();
         if(!cacheFileFreed) {
@@ -181,6 +186,16 @@ public class PluginsListSettingsFragment extends Fragment implements PluginsList
 
                     @Override
                     public void onSuccess(String filename) {
+
+                        String[] plugin = filename.split(".jpl");
+                        List<PluginDetails> availablePlugins = listAvailablePlugins(mContext);
+                        for (PluginDetails availablePlugin : availablePlugins){
+                            if (availablePlugin.getName().equals(plugin[0]))
+                            {
+                                availablePlugin.setEnabled(true);
+                                onPluginEnabled(availablePlugin);
+                            }
+                        }
                         ((PluginsListAdapter) mAdapter)
                                 .updatePluginsList(listAvailablePlugins(mContext));
                         Toast.makeText(mContext, "Plugin: " + filename +
diff --git a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
index 972d48b95d5b7e8b969d55dc5e090c0084cb83d3..b8d700218de024e4e44dfa4d0db0b3bd10d850e8 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
@@ -504,12 +504,6 @@ public class TVCallFragment extends BaseSupportFragment<CallPresenter> implement
 
     @Override
     public void resetPluginPreviewVideoSize(int previewWidth, int previewHeight, int rot) {
-        if (previewWidth == -1 && previewHeight == -1)
-            return;
-        mPreviewWidth = previewWidth;
-        mPreviewHeight = previewHeight;
-        boolean flip = (rot % 180) != 0;
-        binding.pluginPreviewSurface.setAspectRatio(flip ? mPreviewHeight : mPreviewWidth, flip ? mPreviewWidth : mPreviewHeight);
     }
 
     @Override
diff --git a/ring-android/app/src/main/res/drawable/round_settings_backup_restore_24.xml b/ring-android/app/src/main/res/drawable/round_settings_backup_restore_24.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2bf908c7f8b40d53a46c45b09bf54371f6e27a32
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/round_settings_backup_restore_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="M14,12c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2 0.9,2 2,2 2,-0.9 2,-2zM12.26,3C7.17,2.86 3,6.95 3,12L1.21,12c-0.45,0 -0.67,0.54 -0.35,0.85l2.79,2.79c0.2,0.2 0.51,0.2 0.71,0l2.79,-2.79c0.31,-0.31 0.09,-0.85 -0.36,-0.85L5,12c0,-3.9 3.18,-7.05 7.1,-7 3.72,0.05 6.85,3.18 6.9,6.9 0.05,3.91 -3.1,7.1 -7,7.1 -1.25,0 -2.42,-0.34 -3.44,-0.91 -0.39,-0.22 -0.87,-0.14 -1.18,0.18 -0.46,0.46 -0.37,1.25 0.2,1.57C8.89,20.57 10.39,21 12,21c5.05,0 9.14,-4.17 9,-9.26 -0.13,-4.69 -4.05,-8.61 -8.74,-8.74z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/layout/frag_plugin_settings.xml b/ring-android/app/src/main/res/layout/frag_plugin_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a351b7a4ca32b4e10e04675a9935c35da1d77ed4
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/frag_plugin_settings.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.widget.RelativeLayout 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:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <ImageView
+        android:id="@+id/plugin_setting_icon"
+        android:layout_marginTop="32dp"
+        android:layout_width="80dp"
+        android:layout_height="80dp"
+        android:layout_centerHorizontal="true"
+        app:srcCompat="@drawable/baseline_group_24" />
+
+    <TextView
+        android:id="@+id/plugin_setting_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:layout_below="@+id/plugin_setting_icon"
+        android:singleLine="true"
+        android:text="@string/video_plugins"
+        android:textSize="20sp"
+        android:layout_centerHorizontal="true"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <View
+        android:id="@+id/plugin_setting_divider"
+        android:layout_below="@+id/plugin_setting_title"
+        android:layout_marginTop="16dp"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@android:color/darker_gray"/>
+
+    <LinearLayout
+        android:id="@+id/plugin_setting_buttons"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:layout_below="@+id/plugin_setting_divider"
+        android:layout_marginTop="16dp"
+        android:weightSum="2">
+
+<!--        <RelativeLayout-->
+<!--            android:id="@+id/plugin_setting_load"-->
+<!--            android:layout_width="wrap_content"-->
+<!--            android:layout_height="wrap_content"-->
+<!--            android:layout_weight="1"-->
+<!--            android:clickable="true">-->
+
+<!--            <ImageView-->
+<!--                android:id="@+id/plugin_setting_load_image"-->
+<!--                android:layout_width="32dp"-->
+<!--                android:layout_height="32dp"-->
+<!--                android:src="@drawable/baseline_delete_24"-->
+<!--                android:layout_centerHorizontal="true"/>-->
+
+<!--            <TextView-->
+<!--                android:layout_below="@+id/plugin_setting_load_image"-->
+<!--                android:layout_width="wrap_content"-->
+<!--                android:layout_height="wrap_content"-->
+<!--                android:text="Activate"-->
+<!--                android:layout_centerHorizontal="true"/>-->
+
+<!--        </RelativeLayout>-->
+        <RelativeLayout
+            android:id="@+id/plugin_setting_reset"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:clickable="true">
+
+            <ImageView
+                android:id="@+id/plugin_setting_reset_image"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:src="@drawable/round_settings_backup_restore_24"
+                android:layout_centerHorizontal="true"/>
+
+            <TextView
+                android:layout_below="@+id/plugin_setting_reset_image"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Reset"
+                android:layout_centerHorizontal="true"/>
+
+        </RelativeLayout>
+        <RelativeLayout
+            android:id="@+id/plugin_setting_install"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:clickable="true"
+            android:focusable="true">
+
+            <ImageView
+                android:id="@+id/plugin_setting_install_image"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:src="@drawable/baseline_delete_24"
+                android:layout_centerHorizontal="true"/>
+
+            <TextView
+                android:layout_below="@+id/plugin_setting_install_image"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Uninstall"
+                android:layout_centerHorizontal="true"/>
+
+        </RelativeLayout>
+
+    </LinearLayout>
+
+
+    <View
+        android:layout_below="@+id/plugin_setting_buttons"
+        android:layout_marginTop="16dp"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@android:color/darker_gray"/>
+
+</android.widget.RelativeLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/frag_plugins_list_item.xml b/ring-android/app/src/main/res/layout/frag_plugins_list_item.xml
index ed085facc1d8293ce5ac4d80ce86dd3009d51669..fb8aed7ac94c111a28817a83e018463487a36ec7 100644
--- a/ring-android/app/src/main/res/layout/frag_plugins_list_item.xml
+++ b/ring-android/app/src/main/res/layout/frag_plugins_list_item.xml
@@ -12,6 +12,7 @@
         android:layout_height="wrap_content"
         android:layout_marginStart="16dp"
         tools:text="My plugin"
+        android:textSize="16sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toEndOf="@+id/plugin_item_icon"
         app:layout_constraintTop_toTopOf="parent" />
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 5993c5d879e9d984f82864af380d94415e5a8185..32550a67e3c9841cf30c7634b50e598af77f085e 100644
--- a/ring-android/app/src/main/res/layout/frag_settings.xml
+++ b/ring-android/app/src/main/res/layout/frag_settings.xml
@@ -122,6 +122,62 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
             </RelativeLayout>
 
+            <RelativeLayout
+                android:id="@+id/settings_plugins_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="@dimen/padding_large">
+
+                <ImageView
+                    android:id="@+id/plugins_image"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentStart="true"
+                    android:layout_centerVertical="true"
+                    android:contentDescription="@string/pref_plugins_summary"
+                    app:srcCompat="@drawable/ic_plugin"
+                    android:layout_marginEnd="32dp"/>
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_centerVertical="true"
+                    android:layout_toStartOf="@+id/settings_plugins_switch"
+                    android:layout_toEndOf="@+id/plugins_image"
+                    android:orientation="vertical">
+                    <TextView
+                        android:id="@+id/plugins_title"
+                        style="@style/ListPrimary"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:maxLines="3"
+                        android:singleLine="false"
+                        android:text="@string/pref_plugins_title"
+                        android:layout_toEndOf="@id/plugins_image"
+                        android:layout_marginEnd="16dp" />
+
+                    <TextView
+                        style="@style/ListSecondary"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:text="@string/pref_plugins_summary"
+                        android:layout_toEndOf="@id/plugins_image"
+                        android:layout_marginEnd="16dp"
+                        android:layout_below="@id/plugins_title"/>
+
+                </LinearLayout>
+
+                <Switch
+                    android:id="@+id/settings_plugins_switch"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentEnd="true"
+                    android:checked="false"
+                    android:layout_marginStart="16dp"
+                    android:layout_centerVertical="true"/>
+
+            </RelativeLayout>
+
+
             <!-- Contacts settings -->
 
             <!--
@@ -440,62 +496,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
                     android:layout_below="@id/system_clear_history_title"/>
 
             </RelativeLayout>
-
-            <RelativeLayout
-                android:id="@+id/settings_plugins_layout"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="@dimen/padding_large">
-
-                <ImageView
-                    android:id="@+id/plugins_image"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_alignParentStart="true"
-                    android:layout_centerVertical="true"
-                    android:contentDescription="@string/pref_plugins_summary"
-                    app:srcCompat="@drawable/ic_plugin"
-                    android:layout_marginEnd="32dp"/>
-                <LinearLayout
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_centerVertical="true"
-                    android:layout_toStartOf="@+id/settings_plugins_switch"
-                    android:layout_toEndOf="@+id/plugins_image"
-                    android:orientation="vertical">
-                    <TextView
-                        android:id="@+id/plugins_title"
-                        style="@style/ListPrimary"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:maxLines="3"
-                        android:singleLine="false"
-                        android:text="@string/pref_plugins_title"
-                        android:layout_toEndOf="@id/plugins_image"
-                        android:layout_marginEnd="16dp" />
-
-                    <TextView
-                        style="@style/ListSecondary"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:text="@string/pref_plugins_summary"
-                        android:layout_toEndOf="@id/plugins_image"
-                        android:layout_marginEnd="16dp"
-                        android:layout_below="@id/plugins_title"/>
-
-                </LinearLayout>
-
-                <Switch
-                    android:id="@+id/settings_plugins_switch"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_alignParentEnd="true"
-                    android:checked="false"
-                    android:layout_marginStart="16dp"
-                    android:layout_centerVertical="true"/>
-
-            </RelativeLayout>
-
         </LinearLayout>
     </cx.ring.views.BoundedScrollView>
 </RelativeLayout>
diff --git a/ring-android/app/src/main/res/layout/single_button_preference.xml b/ring-android/app/src/main/res/layout/single_button_preference.xml
index 2525f630a7afb3baebbb1516e556579d2c257ad7..30d62e0c30788794cd48f1d9acaaf4764647c51e 100644
--- a/ring-android/app/src/main/res/layout/single_button_preference.xml
+++ b/ring-android/app/src/main/res/layout/single_button_preference.xml
@@ -19,14 +19,15 @@
         android:id="@+id/title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
+        android:layout_marginStart="76dp"
         android:layout_marginTop="16dp"
         android:ellipsize="marquee"
         android:fadingEdge="horizontal"
         android:singleLine="true"
         android:text="@string/video_plugins"
+        android:textSize="16sp"
         android:textAppearance="?android:attr/textAppearanceLarge"
-        app:layout_constraintStart_toEndOf="@+id/icon"
+        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
     <TextView
@@ -35,12 +36,13 @@
         android:layout_height="wrap_content"
         android:layout_below="@android:id/title"
         android:layout_alignStart="@android:id/title"
-        android:layout_marginStart="16dp"
+        android:layout_marginStart="76dp"
         android:maxLines="4"
         android:text="@string/video_plugins"
+        android:textSize="14sp"
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:textColor="?android:attr/textColorSecondary"
-        app:layout_constraintStart_toEndOf="@+id/icon"
+        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/title" />
 
     <Button
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index 5f7dbf9652267c0a126bd2264e2bebce6d2182f9..d265befe6b7addd3168677d0bbeb73f1367c452a 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -70,6 +70,7 @@ along with this program; if not, write to the Free Software
     <string name="menu_item_accounts">Manage accounts</string>
     <string name="menu_item_account">Manage account</string>
     <string name="menu_item_settings">Settings</string>
+    <string name="menu_item_plugin_list">Plugins Settings</string>
     <string name="menu_item_share">Share my contact</string>
     <string name="menu_item_about">About Jami</string>
 
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 f0e7d4a06aa89e91aaa18c79517b35dfd3bcec61..4897685d1d5118d89789ed2b8853a73454a75d9f 100644
--- a/ring-android/app/src/main/res/values/strings_preferences.xml
+++ b/ring-android/app/src/main/res/values/strings_preferences.xml
@@ -41,7 +41,7 @@
     <string name="pref_persistNotification_summary">Allow running in background to receive calls and messages.</string>
 
     <!-- Plugin -->
-    <string name="pref_plugins_title">Plugins (experimental)</string>
+    <string name="pref_plugins_title">Plugins</string>
     <string name="pref_plugins_summary">Enable plugins and set their parameters</string>
     <string name="fab_plugins_add">Add a new plugin</string>
     <string name="plugin_uninstall_title">Uninstall Plugin ?</string>
diff --git a/ring-android/libringclient/src/main/java/cx/ring/call/CallView.java b/ring-android/libringclient/src/main/java/cx/ring/call/CallView.java
index 757404d27cdf7442490c04109d29b2b2780feba7..79d8386ced9c0dbac5750ea0177e96d86f23cae7 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/call/CallView.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/call/CallView.java
@@ -32,7 +32,6 @@ public interface CallView {
     void displayContactBubble(boolean display);
 
     void displayVideoSurface(boolean displayVideoSurface, boolean displayPreviewContainer);
-//    void displayPluginSurface();
 
     void displayPreviewSurface(boolean display);
 
diff --git a/ring-android/libringclient/src/main/java/cx/ring/model/Conference.java b/ring-android/libringclient/src/main/java/cx/ring/model/Conference.java
index 484ff5d472b527cba2ca2f7c495e368f2ea7e775..36bd19e9bf2410d17b4e5f050dd01eb8b3176964 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/model/Conference.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/model/Conference.java
@@ -73,7 +73,7 @@ public class Conference {
     }
 
     public String getPluginId() {
-        return mId + "_plugin";
+        return "local";
     }
 
     public String getConfId() {