diff --git a/ring-android/app/src/main/java/cx/ring/adapters/ConfParticipantAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/ConfParticipantAdapter.java
index 0307b89ae11848c92b322664bb6b67d118fcd3ba..050fb051189d1d4dfc784862e938be552749dd09 100644
--- a/ring-android/app/src/main/java/cx/ring/adapters/ConfParticipantAdapter.java
+++ b/ring-android/app/src/main/java/cx/ring/adapters/ConfParticipantAdapter.java
@@ -1,3 +1,22 @@
+/*
+ *  Copyright (C) 2004-2021 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 package cx.ring.adapters;
 
 import android.content.Context;
@@ -11,16 +30,18 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import java.util.List;
 
+import cx.ring.fragments.CallFragment;
 import cx.ring.views.AvatarFactory;
 import cx.ring.databinding.ItemConferenceParticipantBinding;
-import cx.ring.fragments.CallFragment;
+
+import net.jami.model.Conference;
 import net.jami.model.Contact;
 import net.jami.model.Call;
 import cx.ring.views.ParticipantView;
 
 public class ConfParticipantAdapter extends RecyclerView.Adapter<ParticipantView> {
     protected final ConfParticipantAdapter.ConfParticipantSelected onSelectedCallback;
-    private List<Call> calls = null;
+    private List<Conference.ParticipantInfo> calls = null;
 
     public ConfParticipantAdapter(@NonNull ConfParticipantSelected cb) {
         onSelectedCallback = cb;
@@ -34,22 +55,23 @@ public class ConfParticipantAdapter extends RecyclerView.Adapter<ParticipantView
 
     @Override
     public void onBindViewHolder(@NonNull ParticipantView holder, int position) {
-        final Call call = calls.get(position);
-        final Contact contact = call.getContact();
+        final Conference.ParticipantInfo info = calls.get(position);
+        final Contact contact = info.contact;
+
         final Context context = holder.itemView.getContext();
-        Call.CallStatus status = call.getCallStatus();
-        if (status == Call.CallStatus.CURRENT)  {
+        if (info.call != null && info.call.getCallStatus() != Call.CallStatus.CURRENT)  {
+            holder.binding.displayName.setText(String.format("%s\n%s", contact.getDisplayName(), context.getText(CallFragment.callStateToHumanState(info.call.getCallStatus()))));
+            holder.binding.photo.setAlpha(.5f);
+        } else {
             holder.binding.displayName.setText(contact.getDisplayName());
             holder.binding.photo.setAlpha(1f);
-        } else {
-            holder.binding.displayName.setText(String.format("%s\n%s", contact.getDisplayName(), context.getText(CallFragment.callStateToHumanState(status))));
-            holder.binding.photo.setAlpha(.5f);
         }
+
         if (holder.disposable != null)
             holder.disposable.dispose();
         holder.disposable = AvatarFactory.getAvatar(context, contact)
                 .subscribe(holder.binding.photo::setImageDrawable);
-        holder.itemView.setOnClickListener(view -> onSelectedCallback.onParticipantSelected(view, call));
+        holder.itemView.setOnClickListener(view -> onSelectedCallback.onParticipantSelected(view, info));
     }
 
     @Override
@@ -57,8 +79,8 @@ public class ConfParticipantAdapter extends RecyclerView.Adapter<ParticipantView
         return calls == null ? 0 : calls.size();
     }
 
-    public void updateFromCalls(@NonNull final List<Call> contacts) {
-        final List<Call> oldCalls = calls;
+    public void updateFromCalls(@NonNull final List<Conference.ParticipantInfo> contacts) {
+        final List<Conference.ParticipantInfo> oldCalls = calls;
         calls = contacts;
         if (oldCalls != null) {
             DiffUtil.calculateDiff(new DiffUtil.Callback() {
@@ -88,6 +110,6 @@ public class ConfParticipantAdapter extends RecyclerView.Adapter<ParticipantView
     }
 
     public interface ConfParticipantSelected {
-        void onParticipantSelected(View view, Call contact);
+        void onParticipantSelected(View view, Conference.ParticipantInfo contact);
     }
 }
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 687e76f29aa4f90b6810a1d9017e681bac39af85..05774ee7abe17c7383612ec6bd677d44fcd62105 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
@@ -96,7 +96,6 @@ import net.jami.model.Uri;
 import net.jami.services.DeviceRuntimeService;
 import net.jami.services.HardwareService;
 import net.jami.services.NotificationService;
-import net.jami.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -138,7 +137,6 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     public static final String ACTION_GET_CALL = "GET_CALL";
 
     public static final String KEY_ACTION = "action";
-    public static final String KEY_ACCOUNT_ID = "accountId";
     public static final String KEY_CONF_ID = "confId";
     public static final String KEY_AUDIO_ONLY = "AUDIO_ONLY";
 
@@ -344,7 +342,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
         return binding.getRoot();
     }
 
-    private TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
+    private final TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
         @Override
         public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
             mPreviewSurfaceWidth = width;
@@ -380,7 +378,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
         binding.pluginPreviewHandle.setAlpha(hiddenState);
     }
 
-    @SuppressLint("ClickableViewAccessibility")
+    @SuppressLint({"ClickableViewAccessibility", "RtlHardcoded", "WakelockTimeout"})
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         setHasOptionsMenu(true);
@@ -741,6 +739,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
      *
      * @param isAudioOnly true if it is an audio call
      */
+    @SuppressLint("WakelockTimeout")
     @Override
     public void handleCallWakelock(boolean isAudioOnly) {
         if (isAudioOnly) {
@@ -841,15 +840,13 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
         super.onOptionsItemSelected(item);
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                presenter.chatClick();
-                break;
-            case R.id.menuitem_dialpad:
-                presenter.dialpadClick();
-                break;
-            case R.id.menuitem_video_plugins:
-                displayVideoPluginsCarousel();
+        int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {
+            presenter.chatClick();
+        } else if (itemId == R.id.menuitem_dialpad) {
+            presenter.dialpadClick();
+        } else if (itemId == R.id.menuitem_video_plugins) {
+            displayVideoPluginsCarousel();
         }
         return true;
     }
@@ -949,9 +946,8 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     public void updateContactBubble(@NonNull final List<Call> contacts) {
         Log.w(TAG, "updateContactBubble " + contacts.size());
 
-        mConferenceMode = contacts.size() > 1;
-        String username = mConferenceMode ? "Conference with " + contacts.size() + " people" : contacts.get(0).getContact().getRingUsername();
-        String displayName = mConferenceMode ? null : contacts.get(0).getContact().getDisplayName();
+        String username = contacts.size() > 1 ? "Conference with " + contacts.size() + " people" : contacts.get(0).getContact().getDisplayName();
+        String displayName = contacts.size() > 1 ? null : contacts.get(0).getContact().getDisplayName();
 
         boolean hasProfileName = displayName != null && !displayName.contentEquals(username);
 
@@ -987,15 +983,42 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
                         .build(getActivity())
         );
 
-        if (!mConferenceMode) {
+    }
+
+    @Override
+    public void updateConfInfo(List<Conference.ParticipantInfo> participantInfo) {
+        Log.w(TAG, "updateConfInfo " + participantInfo);
+
+        mConferenceMode = participantInfo.size() > 1;
+
+        binding.participantLabelContainer.removeAllViews();
+        if (!participantInfo.isEmpty()) {
+            LayoutInflater inflater = LayoutInflater.from(binding.participantLabelContainer.getContext());
+            for (Conference.ParticipantInfo i : participantInfo) {
+                String displayName = i.contact.getDisplayName();
+                if (!TextUtils.isEmpty(displayName)) {
+                    ItemParticipantLabelBinding label = ItemParticipantLabelBinding.inflate(inflater);
+                    PercentFrameLayout.LayoutParams params = new PercentFrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+                    params.getPercentLayoutInfo().leftMarginPercent = i.x / (float) mVideoWidth;
+                    params.getPercentLayoutInfo().topMarginPercent = i.y / (float) mVideoHeight;
+                    label.participantName.setText(displayName);
+                    label.moderator.setVisibility(i.isModerator ? View.VISIBLE : View.GONE);
+                    label.mute.setVisibility(i.audioMuted ? View.VISIBLE : View.GONE);
+                    binding.participantLabelContainer.addView(label.getRoot(), params);
+                }
+            }
+        }
+        binding.participantLabelContainer.setVisibility(participantInfo.isEmpty() ? View.GONE : View.VISIBLE);
+
+        if (participantInfo.isEmpty() || participantInfo.size() < 2) {
             binding.confControlGroup.setVisibility(View.GONE);
         } else {
             binding.confControlGroup.setVisibility(View.VISIBLE);
             if (confAdapter == null) {
-                confAdapter = new ConfParticipantAdapter((view, call) -> {
+                confAdapter = new ConfParticipantAdapter((view, info) -> {
                     if (presenter == null)
                         return;
-                    boolean maximized = presenter.isMaximized(call);
+                    boolean maximized = presenter.isMaximized(info);
                     PopupMenu popup = new PopupMenu(view.getContext(), view);
                     popup.inflate(R.menu.conference_participant_actions);
                     MenuBuilder menu = (MenuBuilder) popup.getMenu();
@@ -1008,7 +1031,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
                         maxItem.setTitle(R.string.action_call_maximize);
                         maxItem.setIcon(R.drawable.baseline_open_in_full_24);
                     }
-                    if (!call.isAudioMuted()) {
+                    if (!info.audioMuted) {
                         muteItem.setTitle(R.string.action_call_mute);
                         muteItem.setIcon(R.drawable.baseline_mic_off_24);
                     } else {
@@ -1018,27 +1041,18 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
                     popup.setOnMenuItemClickListener(item -> {
                         if (presenter == null)
                             return false;
-                        switch (item.getItemId()) {
-                            case R.id.conv_contact_details:
-                                presenter.openParticipantContact(call);
-                                break;
-                            case R.id.conv_contact_hangup:
-                                presenter.hangupParticipant(call);
-                                break;
-                            case R.id.conv_mute:
-                                if (!call.isAudioMuted()) {
-                                    call.muteAudio(true);
-                                    presenter.muteParticipant(call, true);
-                                } else {
-                                    call.muteAudio(false);
-                                    presenter.muteParticipant(call, false);
-                                }
-                                break;
-                            case R.id.conv_contact_maximize:
-                                presenter.maximizeParticipant(call);
-                                break;
-                            default:
-                                return false;
+                        int itemId = item.getItemId();
+                        if (itemId == R.id.conv_contact_details) {
+                            presenter.openParticipantContact(info);
+                        } else if (itemId == R.id.conv_contact_hangup) {
+                            presenter.hangupParticipant(info);
+                        } else if (itemId == R.id.conv_mute) {
+                            //call.muteAudio(!info.audioMuted);
+                            presenter.muteParticipant(info, !info.audioMuted);
+                        } else if (itemId == R.id.conv_contact_maximize) {
+                            presenter.maximizeParticipant(info);
+                        } else {
+                            return false;
                         }
                         return true;
                     });
@@ -1047,34 +1061,12 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
                     menuHelper.show();
                 });
             }
-            confAdapter.updateFromCalls(contacts);
+            confAdapter.updateFromCalls(participantInfo);
             if (binding.confControlGroup.getAdapter() == null)
                 binding.confControlGroup.setAdapter(confAdapter);
         }
     }
 
-    @Override
-    public void updateConfInfo(List<Conference.ParticipantInfo> info) {
-        binding.participantLabelContainer.removeAllViews();
-        if (!info.isEmpty()) {
-            LayoutInflater inflater = LayoutInflater.from(binding.participantLabelContainer.getContext());
-            for (Conference.ParticipantInfo i : info) {
-                String displayName = i.contact.getDisplayName();
-                if (!TextUtils.isEmpty(displayName)) {
-                    ItemParticipantLabelBinding label = ItemParticipantLabelBinding.inflate(inflater);
-                    PercentFrameLayout.LayoutParams params = new PercentFrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-                    params.getPercentLayoutInfo().leftMarginPercent = i.x / (float) mVideoWidth;
-                    params.getPercentLayoutInfo().topMarginPercent = i.y / (float) mVideoHeight;
-                    label.participantName.setText(displayName);
-                    label.moderator.setVisibility(i.isModerator ? View.VISIBLE : View.GONE);
-                    label.mute.setVisibility(i.audioMuted ? View.VISIBLE : View.GONE);
-                    binding.participantLabelContainer.addView(label.getRoot(), params);
-                }
-            }
-        }
-        binding.participantLabelContainer.setVisibility(info.isEmpty() ? View.GONE : View.VISIBLE);
-    }
-
     @Override
     public void updateParticipantRecording(Set<Contact> contacts) {
         if (contacts.size() == 0) {
@@ -1131,7 +1123,9 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
 
         requireActivity().invalidateOptionsMenu();
         CallActivity callActivity = (CallActivity) getActivity();
-        callActivity.showSystemUI();
+        if (callActivity != null) {
+            callActivity.showSystemUI();
+        }
     }
 
     @Override
@@ -1471,6 +1465,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
     /**
      * Function that is called to show/hide the plugins recycler viewer and update UI
      */
+    @SuppressLint("UseCompatLoadingForDrawables")
     public void displayVideoPluginsCarousel() {
         choosePluginMode = !choosePluginMode;
 
@@ -1488,7 +1483,7 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
             for (String callMediaHandler : callMediaHandlers) {
                 Map<String, String> details = getCallMediaHandlerDetails(callMediaHandler);
                 String drawablePath = details.get("iconPath");
-                if (drawablePath.endsWith("svg"))
+                if (drawablePath != null && drawablePath.endsWith("svg"))
                     drawablePath = drawablePath.replace(".svg", ".png");
                 Drawable handlerIcon = Drawable.createFromPath(drawablePath);
                 if (handlerIcon == null) {
@@ -1513,17 +1508,15 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
             if(callMediaHandlers.size() > 0) {
                 // If no previous plugin was active, take the first, else previous
                 int position;
-                if(previousPluginPosition < 1) {
+                if (previousPluginPosition < 1) {
                     rp.scrollToPosition(1);
                     position = 1;
                     previousPluginPosition = 1;
                 } else {
                     position = previousPluginPosition;
                 }
-                if (position > 0) {
-                    String callMediaId = callMediaHandlers.get(position-1);
-                    presenter.startPlugin(callMediaId);
-                }
+                String callMediaId = callMediaHandlers.get(position-1);
+                presenter.startPlugin(callMediaId);
             }
 
         } else {
@@ -1546,12 +1539,11 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
 
     /**
      * Called whenever a plugin drawable in the recycler picker is clicked or scrolled to
-     * @param position
      */
     @Override
     public void onItemSelected(int position) {
         Log.i(TAG, "selected position: " + position);
-        /** If there was a different plugin before, unload it
+        /* If there was a different plugin before, unload it
          * If previousPluginPosition = -1 or 0, there was no plugin
          */
         if (previousPluginPosition > 0) {
@@ -1569,13 +1561,12 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
 
     /**
      * 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 there was a different plugin before, unload it
              * If previousPluginPosition = -1 or 0, there was no plugin
              */
             if (previousPluginPosition > 0) {
@@ -1585,7 +1576,9 @@ public class CallFragment extends BaseSupportFragment<CallPresenter> implements
             }
 
             CallActivity callActivity = (CallActivity) getActivity();
-            callActivity.showSystemUI();
+            if (callActivity != null) {
+                callActivity.showSystemUI();
+            }
 
             toggleVideoPluginsCarousel(false);
             displayVideoPluginsCarousel();
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 0d140715d382ab533a000aee041a5a8bedc78410..6c411718f0f7b8eb6f8b99af0839201451c663fd 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
@@ -436,7 +436,7 @@ public class TVCallFragment extends BaseSupportFragment<CallPresenter> implement
                         .build(getActivity())
         );
 
-        if (!mConferenceMode) {
+        /*if (!mConferenceMode) {
             binding.confControlGroup.setVisibility(View.GONE);
         } else {
             binding.confControlGroup.setVisibility(View.VISIBLE);
@@ -464,7 +464,7 @@ public class TVCallFragment extends BaseSupportFragment<CallPresenter> implement
             confAdapter.updateFromCalls(calls);
             if (binding.confControlGroup.getAdapter() == null)
                 binding.confControlGroup.setAdapter(confAdapter);
-        }
+        }*/
     }
 
     @Override
@@ -686,6 +686,36 @@ public class TVCallFragment extends BaseSupportFragment<CallPresenter> implement
             }
         }
         binding.participantLabelContainer.setVisibility(info.isEmpty() ? View.GONE : View.VISIBLE);
+
+        if (!mConferenceMode) {
+            binding.confControlGroup.setVisibility(View.GONE);
+        } else {
+            binding.confControlGroup.setVisibility(View.VISIBLE);
+            if (confAdapter  == null) {
+                confAdapter = new ConfParticipantAdapter((view, call) -> {
+                    Context context = requireContext();
+                    PopupMenu popup = new PopupMenu(context, view);
+                    popup.inflate(R.menu.conference_participant_actions);
+                    popup.setOnMenuItemClickListener(item -> {
+                        int itemId = item.getItemId();
+                        if (itemId == R.id.conv_contact_details) {
+                            presenter.openParticipantContact(call);
+                        } else if (itemId == R.id.conv_contact_hangup) {
+                            presenter.hangupParticipant(call);
+                        } else {
+                            return false;
+                        }
+                        return true;
+                    });
+                    MenuPopupHelper menuHelper = new MenuPopupHelper(context, (MenuBuilder) popup.getMenu(), view);
+                    menuHelper.setForceShowIcon(true);
+                    menuHelper.show();
+                });
+            }
+            confAdapter.updateFromCalls(info);
+            if (binding.confControlGroup.getAdapter() == null)
+                binding.confControlGroup.setAdapter(confAdapter);
+        }
     }
 
     @Override
diff --git a/ring-android/app/src/main/res/drawable/baseline_moderateur.xml b/ring-android/app/src/main/res/drawable/baseline_moderateur.xml
index 1361cac0d75e7243c3faf464a7656f47cbe4a059..34126174fa73e00fe217781749e21a2ceef8af81 100644
--- a/ring-android/app/src/main/res/drawable/baseline_moderateur.xml
+++ b/ring-android/app/src/main/res/drawable/baseline_moderateur.xml
@@ -2,11 +2,11 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24"
-    android:viewportHeight="24">
-  <path
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+<path
       android:pathData="M12.0856,6.1741L15.2189,10.3993L21.4127,6.2318L21.4127,18.3908L2.7376,18.3908L2.7376,6.2318L8.9295,10.3981L12.0856,6.1741Z"
       android:strokeWidth="1.3"
-      android:fillColor="#00000000"
-      android:fillType="nonZero"
-      android:strokeColor="#000000"/>
+      android:fillColor="@android:color/white"
+      android:strokeColor="@android:color/white"/>
 </vector>
diff --git a/ring-android/app/src/main/res/layout/item_participant_label.xml b/ring-android/app/src/main/res/layout/item_participant_label.xml
index 41039d9a0005a7b8b918ef2df4f18c54fb0b5068..1b206b01d80df2e4b173724aaa62758e45675faf 100644
--- a/ring-android/app/src/main/res/layout/item_participant_label.xml
+++ b/ring-android/app/src/main/res/layout/item_participant_label.xml
@@ -1,41 +1,47 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    android:orientation="horizontal"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:background="@drawable/background_conference_label"
-    android:gravity="center_vertical"
-    android:padding="12dp">
+    android:layout_height="wrap_content">
 
-    <TextView
-        android:id="@+id/participant_name"
+    <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        tools:text="Georges Longnom de Chateaubrillant"
-        android:textColor="@color/white"
-        android:ellipsize="marquee"
-        android:singleLine="true" />
+        android:layout_margin="4dp"
+        android:background="@drawable/background_conference_label"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:padding="12dp">
 
-    <ImageView
-        android:id="@+id/moderator"
-        android:layout_width="16dp"
-        android:layout_height="16dp"
-        android:src="@drawable/baseline_moderateur"
-        android:tint="@color/white"
-        android:layout_marginLeft="4dp"
-        android:visibility="gone"
-        tools:visibility="visible"
-        />
+        <TextView
+            android:id="@+id/participant_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="8dp"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:textColor="@color/white"
+            tools:text="Georges Longname of Chateaubrillant" />
 
-    <ImageView
-        android:id="@+id/mute"
-        android:layout_width="16dp"
-        android:layout_height="16dp"
-        android:layout_marginLeft="4dp"
-        android:src="@drawable/baseline_mic_off_24"
-        android:visibility="gone"
-        tools:visibility="visible"
-        />
+        <ImageView
+            android:id="@+id/moderator"
+            android:layout_width="16dp"
+            android:layout_height="16dp"
+            android:layout_margin="4dp"
+            android:contentDescription="@string/call_moderator"
+            android:src="@drawable/baseline_moderateur"
+            android:visibility="gone"
+            tools:visibility="visible" />
 
-</LinearLayout>
\ No newline at end of file
+        <ImageView
+            android:id="@+id/mute"
+            android:layout_width="16dp"
+            android:layout_height="16dp"
+            android:layout_margin="4dp"
+            android:contentDescription="@string/call_muted"
+            android:src="@drawable/baseline_mic_off_24"
+            android:visibility="gone"
+            tools:visibility="visible" />
+
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/strings_call.xml b/ring-android/app/src/main/res/values/strings_call.xml
index e865eb38829e8b9b639b4aae88d637f7680c4231..1906f3b40d3a3b4d88362ac650c10da2b2227fb9 100644
--- a/ring-android/app/src/main/res/values/strings_call.xml
+++ b/ring-android/app/src/main/res/values/strings_call.xml
@@ -38,4 +38,6 @@ along with this program; if not, write to the Free Software
     <string name="call_human_state_over">Over</string>
     <string name="call_human_state_none" translatable="false" />
     <!-- Conferences -->
+    <string name="call_moderator">Moderator</string>
+    <string name="call_muted">Muted</string>
 </resources>
\ No newline at end of file
diff --git a/ring-android/libringclient/src/main/java/net/jami/call/CallPresenter.java b/ring-android/libringclient/src/main/java/net/jami/call/CallPresenter.java
index 6120ebd47804c9668b1ec240b6d665d071f3662b..a11fe3eac0074fb85be835ebf81ff2eb3581dbe8 100644
--- a/ring-android/libringclient/src/main/java/net/jami/call/CallPresenter.java
+++ b/ring-android/libringclient/src/main/java/net/jami/call/CallPresenter.java
@@ -24,6 +24,7 @@ import net.jami.daemon.JamiService;
 import net.jami.facades.ConversationFacade;
 import net.jami.model.Call;
 import net.jami.model.Conference;
+import net.jami.model.Contact;
 import net.jami.model.Conversation;
 import net.jami.model.ConversationHistory;
 import net.jami.model.Uri;
@@ -401,7 +402,8 @@ public class CallPresenter extends RootPresenter<CallView> {
 
 
     public void uiVisibilityChanged(boolean displayed) {
-        net.jami.call.CallView view = getView();
+        Log.w(TAG, "uiVisibilityChanged " + mOnGoingCall + " "  + displayed);
+        CallView view = getView();
         if (view != null)
             view.displayHangupButton(mOnGoingCall && displayed);
     }
@@ -469,7 +471,7 @@ public class CallPresenter extends RootPresenter<CallView> {
     }
 
     private void confUpdate(Conference call) {
-        Log.w(TAG, "confUpdate " + call.getId());
+        Log.w(TAG, "confUpdate " + call.getId() + " " + call.getState());
 
         Call.CallStatus status = call.getState();
         if (status == Call.CallStatus.HOLD) {
@@ -522,12 +524,13 @@ public class CallPresenter extends RootPresenter<CallView> {
         }
     }
 
-    public void maximizeParticipant(Call call) {
-        if (mConference.getMaximizedCall() == call)
-            call = null;
-        mConference.setMaximizedCall(call);
-        if (call != null) {
-            mCallService.setConfMaximizedParticipant(mConference.getConfId(), call.getDaemonIdString());
+    public void maximizeParticipant(Conference.ParticipantInfo info) {
+        Contact contact = info == null ? null : info.contact;
+        if (mConference.getMaximizedParticipant() == contact)
+            info = null;
+        mConference.setMaximizedParticipant(contact);
+        if (info != null) {
+            mCallService.setConfMaximizedParticipant(mConference.getConfId(), info.contact.getUri());
         } else {
             mCallService.setConfGridLayout(mConference.getConfId());
         }
@@ -648,6 +651,7 @@ public class CallPresenter extends RootPresenter<CallView> {
                     if (confs.isEmpty()) {
                         final Observer<Call> pendingObserver = new Observer<Call>() {
                             private Call call = null;
+
                             @Override
                             public void onSubscribe(@NonNull Disposable d) {}
 
@@ -712,16 +716,18 @@ public class CallPresenter extends RootPresenter<CallView> {
         getView().startAddParticipant(mConference.getId());
     }
 
-    public void hangupParticipant(Call call) {
-        mCallService.hangUp(call.getDaemonIdString());
+    public void hangupParticipant(Conference.ParticipantInfo info) {
+        //mCallService.
+        if (info.call != null)
+            mCallService.hangUp(info.call.getDaemonIdString());
     }
 
-    public void muteParticipant(Call call, boolean mute) {
-        mCallService.muteParticipant(call.getConfId(), call.getContact().getPrimaryNumber(), mute);
+    public void muteParticipant(Conference.ParticipantInfo info, boolean mute) {
+        mCallService.muteParticipant(mConference.getId(), info.contact.getPrimaryNumber(), mute);
     }
 
-    public void openParticipantContact(Call call) {
-        getView().goToContact(call.getAccount(), call.getContact());
+    public void openParticipantContact(Conference.ParticipantInfo info) {
+        getView().goToContact(mConference.getFirstCall().getAccount(), info.contact);
     }
 
     public void stopCapture() {
@@ -736,8 +742,8 @@ public class CallPresenter extends RootPresenter<CallView> {
         mHardwareService.stopScreenShare();
     }
 
-    public boolean isMaximized(Call call) {
-        return mConference.getMaximizedCall() == call;
+    public boolean isMaximized(Conference.ParticipantInfo info) {
+        return mConference.getMaximizedParticipant() == info.contact;
     }
 
     public void startPlugin(String mediaHandlerId) {
diff --git a/ring-android/libringclient/src/main/java/net/jami/facades/ConversationFacade.java b/ring-android/libringclient/src/main/java/net/jami/facades/ConversationFacade.java
index 99bea15d3c55de4778da7c94d3806995cf52d2a1..01aef0be3c8d08727c9f7db742f38feb069bc76f 100644
--- a/ring-android/libringclient/src/main/java/net/jami/facades/ConversationFacade.java
+++ b/ring-android/libringclient/src/main/java/net/jami/facades/ConversationFacade.java
@@ -614,7 +614,7 @@ public class ConversationFacade {
             return;
         Contact contact = call.getContact();
         String conversationId = call.getConversationId();
-        Log.w(TAG, "CallStateChange " + call.getId() + " conversationId:" + conversationId);
+        Log.w(TAG, "CallStateChange " + call.getDaemonIdString() + " conversationId:" + conversationId);
 
         Conversation conversation = conversationId == null
                 ? (contact == null ? null : account.getByUri(contact.getUri()))
diff --git a/ring-android/libringclient/src/main/java/net/jami/model/Conference.java b/ring-android/libringclient/src/main/java/net/jami/model/Conference.java
index dbebde11199601331ceba8c2b65e2ec4760eb37a..cab4c89649d924853598652dfe275a99852e76f1 100644
--- a/ring-android/libringclient/src/main/java/net/jami/model/Conference.java
+++ b/ring-android/libringclient/src/main/java/net/jami/model/Conference.java
@@ -35,11 +35,13 @@ import io.reactivex.subjects.Subject;
 public class Conference {
 
     public static class ParticipantInfo {
-        public Contact contact;
+        public final Call call;
+        public final Contact contact;
         public int x, y, w, h;
         public boolean videoMuted, audioMuted, isModerator;
 
-        public ParticipantInfo(Contact c, Map<String, String> i) {
+        public ParticipantInfo(Call call, Contact c, Map<String, String> i) {
+            this.call = call;
             contact = c;
             x = Integer.parseInt(i.get("x"));
             y = Integer.parseInt(i.get("y"));
@@ -49,6 +51,10 @@ public class Conference {
             audioMuted = Boolean.parseBoolean(i.get("audioMuted"));
             isModerator = Boolean.parseBoolean(i.get("isModerator"));
         }
+
+        public boolean isEmpty() {
+            return x == 0 && y == 0 && w == 0 && h == 0;
+        }
     }
     private final Subject<List<ParticipantInfo>> mParticipantInfo = BehaviorSubject.createDefault(Collections.emptyList());
 
@@ -59,7 +65,8 @@ public class Conference {
     private Call.CallStatus mConfState;
     private final ArrayList<Call> mParticipants;
     private boolean mRecording;
-    private Call mMaximizedCall;
+    private Contact mMaximizedParticipant;
+    private boolean isModerator;
 
     public Conference(Call call) {
         this(call.getDaemonIdString());
@@ -104,12 +111,12 @@ public class Conference {
         return mId;
     }
 
-    public void setMaximizedCall(Call call) {
-        mMaximizedCall = call;
+    public void setMaximizedParticipant(Contact contact) {
+        mMaximizedParticipant = contact;
     }
 
-    public Call getMaximizedCall() {
-        return mMaximizedCall;
+    public Contact getMaximizedParticipant() {
+        return mMaximizedParticipant;
     }
 
     public String getPluginId() {
@@ -120,6 +127,14 @@ public class Conference {
         return mId;
     }
 
+    public void setIsModerator(boolean isModerator) {
+        this.isModerator = isModerator;
+    }
+
+    public boolean getIsModerator() {
+        return isModerator;
+    }
+
     public Call.CallStatus getState() {
         if (isSimpleCall()) {
             return mParticipants.get(0).getCallStatus();
diff --git a/ring-android/libringclient/src/main/java/net/jami/services/CallService.java b/ring-android/libringclient/src/main/java/net/jami/services/CallService.java
index 7a6d4e64cc735904e9896dc165a794f76c16a4a1..d5904ea3b7b002b051a7929b8db964bf10a796d3 100644
--- a/ring-android/libringclient/src/main/java/net/jami/services/CallService.java
+++ b/ring-android/libringclient/src/main/java/net/jami/services/CallService.java
@@ -124,30 +124,53 @@ public class CallService {
     }
 
     public void onConferenceInfoUpdated(String confId, List<Map<String, String>> info) {
+        Log.w(TAG, "onConferenceInfoUpdated " + confId + " " + info);
         Conference conference = getConference(confId);
+        boolean isModerator = false;
         if (conference != null) {
             List<Conference.ParticipantInfo> newInfo = new ArrayList<>(info.size());
             if (conference.isConference()) {
                 for (Map<String, String> i : info) {
                     Call call = conference.findCallByContact(Uri.fromString(i.get("uri")));
                     if (call != null) {
-                        newInfo.add(new Conference.ParticipantInfo(call.getContact(), i));
+                        Conference.ParticipantInfo confInfo = new Conference.ParticipantInfo(call, call.getContact(), i);
+                        if (confInfo.isEmpty()) {
+                            Log.w(TAG, "onConferenceInfoUpdated: ignoring empty entry " + i);
+                            continue;
+                        }
+                        if (confInfo.contact.isUser() && confInfo.isModerator) {
+                            isModerator = true;
+                        }
+                        newInfo.add(confInfo);
                     } else {
+                        Log.w(TAG, "onConferenceInfoUpdated " + confId + " can't find call for " + i);
                         // TODO
                     }
                 }
             } else {
                 Account account = mAccountService.getAccount(conference.getCall().getAccount());
-                for (Map<String, String> i : info)
-                    newInfo.add(new Conference.ParticipantInfo(account.getContactFromCache(Uri.fromString(i.get("uri"))), i));
+                for (Map<String, String> i : info) {
+                    Conference.ParticipantInfo confInfo = new Conference.ParticipantInfo(null, account.getContactFromCache(Uri.fromString(i.get("uri"))), i);
+                    if (confInfo.isEmpty()) {
+                        Log.w(TAG, "onConferenceInfoUpdated: ignoring empty entry " + i);
+                        continue;
+                    }
+                    if (confInfo.contact.isUser() && confInfo.isModerator) {
+                        isModerator = true;
+                    }
+                    newInfo.add(confInfo);
+                }
             }
+            conference.setIsModerator(isModerator);
             conference.setInfo(newInfo);
+        } else {
+            Log.w(TAG, "onConferenceInfoUpdated can't find conference" + confId);
         }
     }
 
-    public void setConfMaximizedParticipant(String confId, String callId) {
+    public void setConfMaximizedParticipant(String confId, Uri uri) {
         mExecutor.execute(() -> {
-            JamiService.setActiveParticipant(confId, callId);
+            JamiService.setActiveParticipant(confId, uri == null ? "" : uri.getRawRingId());
             JamiService.setConferenceLayout(confId, 1);
         });
     }
@@ -246,7 +269,7 @@ public class CallService {
                 JamiService.muteLocalMedia(callId, "MEDIA_TYPE_VIDEO", true);
             }
             Call call = addCall(account, callId, number, Call.Direction.OUTGOING);
-            if (conversationUri.isSwarm())
+            if (conversationUri != null && conversationUri.isSwarm())
                 call.setSwarmInfo(conversationUri.getRawRingId());
             call.muteVideo(audioOnly);
             updateConnectionCount();
@@ -446,14 +469,14 @@ public class CallService {
         return currentCalls.get(callId);
     }
 
-    public Call getCurrentCallForContactId(String contactId) {
+    /*public Call getCurrentCallForContactId(String contactId) {
         for (Call call : currentCalls.values()) {
             if (contactId.contains(call.getContact().getPrimaryNumber())) {
                 return call;
             }
         }
         return null;
-    }
+    }*/
 
     public void removeCallForId(String callId) {
         synchronized (currentCalls) {