package com.ez.ertc.meeting.presenter;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import androidx.core.content.ContextCompat;

import com.ez.basertc.OnApplyResultListener;
import com.ez.basertc.RTCConstant;
import com.ez.baselib.utils.LogUtil;
import com.ez.basertc.ConstantKeys;
import com.ez.ertc.meeting.ErtcEzmHelper;
import com.ez.ertc.meeting.EzmLifecycleCallback;
import com.ez.ertc.meeting.R;
import com.ez.ertc.meeting.base.YsBaseActivity;
import com.ez.ertc.meeting.contract.ErtcRoomContract;
import com.ez.ertc.meeting.constant.MtAction;
import com.ez.ertc.meeting.constant.MtSets;
import com.ez.ertc.meeting.constant.SharingType;
import com.ez.ertc.meeting.event.MtAccountNotifyEvent;
import com.ez.ertc.meeting.event.MtAudioModeEvent;
import com.ez.ertc.meeting.event.MtCallStateEvent;
import com.ez.ertc.meeting.event.MtExitRoomEvent;
import com.ez.ertc.meeting.event.MtLanActionEvent;
import com.ez.ertc.meeting.event.MtSwitchMemberToastEvent;
import com.ez.ertc.meeting.event.MtSwitchStimulationEvent;
import com.ez.ertc.meeting.event.MtSwitchWaterMarkEvent;
import com.ez.ertc.meeting.event.MtToTestEvent;
import com.ez.ertc.meeting.event.MtToggleSelfAudioEvent;
import com.ez.ertc.meeting.service.ErtcPictureInPictureService;
import com.ez.ertc.meeting.service.ErtcVideoMeetingService;
import com.ez.ertc.meeting.service.FloatingButtonService;
import com.ez.ertc.meeting.ui.AirActivity;
import com.ez.ertc.meeting.ui.BeautyConfigActivity;
import com.ez.ertc.meeting.ui.ErtcRoomActivity;
import com.ez.ertc.meeting.ui.MeetingSetsActivity;
import com.ez.ertc.meeting.ui.TestConfigActivity;
import com.ez.ertc.meeting.utils.AndroidUtil;
import com.ez.ertc.meeting.utils.ErtcGenerateTestUserSig;
import com.ez.ertc.meeting.utils.ViewUtil;
import com.ez.ertc.meeting.widget.EZDialog;
import com.ez.ertc.meeting.widget.ErtcMonitorDialog;
import com.ez.ertc.meeting.widget.ErtcTextureView;
import com.ez.ertcmeeting.bean.DeviceState;
import com.ez.ertcmeeting.bean.UserAccount;
import com.ez.ertcmeeting.utils.NetLevelUtil;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;


/**
 * @author xiezuoyuan
 * @time 2019/9/18 14:19
 */
public class ErtcRoomPresenter implements ErtcRoomContract.Presenter {
    public static final int REQUEST_MEDIA_PROJECTION = 1000;

    private static final int MONITOR_GAP_DEFAULT = 10;
    private static final int MONITOR_GAP_LOW = 1;//质量监测时1秒回调一次
    public ErtcRoomContract.View mView;
    ErtcRoomContract.GroupView mGroupView;
    RTCConstant.EnterParam mRoomData;
    private Disposable mFlowDisposable;
    private boolean mIsBackCamera = false;
    boolean mIsOnFront = true;
    private Handler mCoverHandler;
    private Runnable mCoverRunnable = new Runnable() {
        @Override
        public void run() {
            mView.animCoverHide();
        }
    };
    SharingType mSharingType = SharingType.ST_None;
    private EZDialog mStopShareDialog;
    //自己会控
    private boolean mSoundOn = true;
    boolean mWaterMarkOn = true;//水印，默认打开
    boolean mNeedCloseVideo = false;//用于标记是否需要恢复自己视频
    boolean mIsBeautyEnable = false;//美颜开关
    private boolean canBeauty = true;//能否使用美颜
    boolean mIsVoiceStimulation = MtSets.isVoiceStimulation();
    boolean mIsShowMemberToast = MtSets.isShowMemberToast();
    private boolean mPictureInPicture = true;
    private boolean mPictureInPictureSaved = true;
    boolean isErtcSharingScreen = false;//ertc正在共享屏幕的userid
    String mSharingAccountId = "";//正在共享的人的ID，为null则没有人共享
    String mSharingDesktopUserId = "";//正在共享屏幕的UserId
    int mSharingDesktopMask;//正在共享屏幕的Mask
    boolean isAudioMode = false;
    boolean mForceLowStream = false;
    public static final List<UserAccount> sAccountList = Collections.synchronizedList(new ArrayList<UserAccount>());//需要线程安全
    Map<String, String> mNamesMap = Collections.synchronizedMap(new HashMap<String, String>());//需要线程安全
    Map<String, Boolean> accountVideoStateMap = new HashMap<>();
    UserAccount mMyAccount;
    UserAccount mScreenAccount;
    private Intent mFloatIntent;
    boolean isAudioOn = false, isVideoOn = false;
    public boolean isErtcEngineNullLeave = false;

    public UserAccount getAccountByUserId(String userId) {
        UserAccount account = null;
        synchronized (ErtcRoomPresenter.sAccountList) {
            for (UserAccount item : ErtcRoomPresenter.sAccountList) {
                if (item.getUserId().equals(userId)) {
                    account = item;
                    break;
                }
            }
        }
        return account;
    }


    private FloatingButtonService.FloatingButtonBinder mFloatingButtonBinder;
    private ServiceConnection mFloatingButtonConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mFloatingButtonBinder = (FloatingButtonService.FloatingButtonBinder) service;
            mFloatingButtonBinder.setOnCloseListener(new FloatingButtonService.OnCloseListener(){

                @Override
                public void onClose() {
//                    stopRecording();
                    onErtcShareModeNone(true, false);
                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (mFloatingButtonBinder != null) {
                mFloatingButtonBinder.setOnCloseListener(null);
                mFloatingButtonBinder = null;
            }
        }
    };

    Intent mPInPIntent;
    ErtcPictureInPictureService.PInPBinder mDesktopPInPBinder;
    private ServiceConnection mDesktopPInPConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mDesktopPInPBinder = (ErtcPictureInPictureService.PInPBinder) service;
            mDesktopPInPBinder.setOnCloseListener(new ErtcPictureInPictureService.OnCloseListener(){

                @Override
                public void onClose() {
                    stopDesktopPInP();
                }
            });
            mDesktopPInPBinder.setAccount(mScreenAccount, mSharingType);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (mDesktopPInPBinder != null) {
                mDesktopPInPBinder.setOnCloseListener(null);
                mDesktopPInPBinder = null;
            }
        }
    };
    boolean isForceStopShare = false;//点击停止共享按钮，强制把状态置为停止共享
    ErtcMonitorDialog mMonitorDialog;
    int streamWidth, streamHeight;

    public ErtcRoomPresenter(ErtcRoomContract.View mView,
                             ErtcRoomContract.GroupView mGroupView) {
        this.mView = mView;
        this.mGroupView = mGroupView;
        mView.setPresenter(this);
        start();
    }

    @Override
    public void start() {
        mView.showDesktopPInPButton(true);
        mIsBeautyEnable = MtSets.isEnableBeauty();
        //todo 设置美颜
    }

    @SuppressLint("NewApi")
    @Override
    public void initApi(RTCConstant.EnterParam roomData, boolean isAudioOn,
                        boolean isVideoOn, boolean isSoundOn) {
        if (roomData == null) {
            return;
        }
        mRoomData = roomData;
        MtSets.setSavedRoomInfo(mRoomData.roomId, mRoomData.userId);
        mView.updateMemberCount(1);
        mView.setRoomId(roomData.roomId);
        
        //设置默认音视频扬声器状态(需要检查有没有权限)
        boolean hasAudioPermission = ContextCompat.checkSelfPermission(mView.getActivity(), Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
        this.isAudioOn = isAudioOn && hasAudioPermission;
        boolean hasVideoPermission = ContextCompat.checkSelfPermission(mView.getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        this.isVideoOn = isVideoOn && hasVideoPermission;
        
        mMyAccount = UserAccount.Companion.newIntent(roomData.userId);
        mMyAccount.setAudioStatus(isAudioOn ? DeviceState.DS_Active.getValue() : DeviceState.DS_Closed.getValue());
        mMyAccount.setVideoStatus(isVideoOn ? DeviceState.DS_Active.getValue() : DeviceState.DS_Closed.getValue());

        mView.setLeaveTxt(R.string.ys_mt_room_meeting_end);

        mScreenAccount = mMyAccount;
        updateScreenView();
        if (!isSoundOn) {
            toggleSound();
        }

        if (!isVideoOn) {
            toggleCamera(DeviceState.DS_Closed);
        }

        startFlow();
        initRecording();
        postHideCover();
        ErtcEzmHelper.setEzmLifecycleCallback(new EzmLifecycleCallback() {
            @Override
            public void onBackground(boolean background) {
                if (ErtcEzmHelper.ertcEngine == null) {
                    return;
                }
                if (!background){
                    //回到会议activity所在task
                    if (mPInPIntent == null){
                        /**
                         * android系统限制：
                         * 如果回到桌面，5秒钟之内又立即点击APP图标唤起APP，那么APP内的task切换不会立即生效
                         * APP还是在主task内（与5秒内点击悬浮窗不会立即回到app的情况一样）
                         * 如果此时主task存在activity切换，则task切换会立即生效
                         * ps：
                         * 华为mate30pro手机在这种情况下也不会立即生效，但是在“5秒内点击悬浮窗”的情况下能立即回到app
                         */
                        LogUtil.i("EZRTCImpl", "roomPresenter====moveTaskToFront");
                        AirActivity.start(mView.getActivity());
                    }
                }
            }
        });
        updateWaterMarkVisibility();
        if (ErtcEzmHelper.ertcEngine == null) {
            return;
        }
        ErtcEzmHelper.ertcEngine.setSensorMode(1);
        ErtcEzmHelper.ertcEngine.setRTCListener(new ErtcRoomEventListener(this));
        ErtcEzmHelper.ertcEngine.setRtcStatsListener(new ErtcStatsListener(this));

        RTCConstant.ERTCVideoEncParam videoEncParam = new RTCConstant.ERTCVideoEncParam();
        int width = MtSets.getResolutionWidth();
        int height = MtSets.getResolutionHeight();
        if (width == MtSets.RESOLUTION_1080P_WIDTH && height == MtSets.RESOLUTION_1080P_HEIGHT){
            videoEncParam.videoResolution = RTCConstant.ERTCVideoResolution.ERTCVideoResolution_1920_1080;
        } else if (width == MtSets.RESOLUTION_720P_WIDTH && height == MtSets.RESOLUTION_720P_HEIGHT){
            videoEncParam.videoResolution = RTCConstant.ERTCVideoResolution.ERTCVideoResolution_1280_720;
        } else if (width == MtSets.RESOLUTION_480P_WIDTH && height == MtSets.RESOLUTION_480P_HEIGHT){
            videoEncParam.videoResolution = RTCConstant.ERTCVideoResolution.ERTCVideoResolution_640_480;
        } else if (width == MtSets.RESOLUTION_180P_WIDTH && height == MtSets.RESOLUTION_180P_HEIGHT){
            videoEncParam.videoResolution = RTCConstant.ERTCVideoResolution.ERTCVideoResolution_320_180;
        } else {
            for(RTCConstant.ERTCVideoResolution item : RTCConstant.ERTCVideoResolution.values()) {
                if(width == item.getWidth() && height == item.getHeight()){
                    videoEncParam.videoResolution = item;
                    break;
                }
            }
        }
        ConstantKeys.resolutionBig = videoEncParam.videoResolution;
        videoEncParam.videoFps = ConstantKeys.videoFpsBig; //ertc 15
        //todo 码率
//        videoEncParam.videoBitrate = (MtSets.getResolutionWidth() <= MtSets.RESOLUTION_480P_WIDTH ? 512 : 900) * 1024;
        videoEncParam.videoBitrate = ConstantKeys.resolutionBig.getRecommendBitrate();
        LogUtil.d("EZRTCImpl", "big param fps:" + videoEncParam.videoFps + " Resolution:"+ videoEncParam.videoResolution.getWidth() + "x" + videoEncParam.videoResolution.getHeight());
        ErtcEzmHelper.ertcEngine.setVideoEncoderParam(videoEncParam, true);
        ErtcEzmHelper.ertcEngine.setSmallVideoEncodeParam(ConstantKeys.resolutionSmall, true);
        LogUtil.d("EZRTCImpl", "small param fps:" + ConstantKeys.resolutionSmall.videoFps + " Resolution:"+ ConstantKeys.resolutionSmall.videoResolution.getWidth() + "x" + ConstantKeys.resolutionSmall.videoResolution.getHeight());
        ErtcEzmHelper.ertcEngine.enableDualStreamMode(true);//开启双流模式
        ErtcEzmHelper.ertcEngine.setLogLevelDebug(RTCConstant.BavLogLevel.BAV_LOG_LEVEL_INFO); //默认false
        ErtcEzmHelper.ertcEngine.setHardDecodePriority(true);//默认硬解优先
        ErtcEzmHelper.ertcEngine.enableAudioVolumeEvaluation(500);
        ErtcEzmHelper.ertcEngine.setSpeakerPhoneOn(mSoundOn);
        enableLocalVideo(isVideoOn);
        ErtcEzmHelper.ertcEngine.setQualityInterval(MONITOR_GAP_DEFAULT);

        ErtcTextureView localTextureView = mGroupView.findTextureView(mMyAccount.getUserId());
        if (localTextureView != null) {
            localTextureView.getVideoCanvasView().setRenderType(RTCConstant.ERTC_VIDEO_RENDER_MODE_FIT);
            localTextureView.hideProgress();
//            LogUtil.d("EZRTCImpl", "initApi setLocalView mGroupView");
//            ErtcEzmHelper.ertcEngine.setLocalView(localTextureView.getVideoCanvasView());
//            localTextureView.hideProgress();
        }

        mView.getScreenTextureView().getVideoCanvasView().setRenderType(RTCConstant.ERTC_VIDEO_RENDER_MODE_FIT);
        if (mDesktopPInPBinder != null && mDesktopPInPBinder.getTextureView() != null) {
            mDesktopPInPBinder.getTextureView().getVideoCanvasView().setRenderType(RTCConstant.ERTC_VIDEO_RENDER_MODE_FIT);
        }
        if (mScreenAccount != null && mScreenAccount.getUserId().equals(mMyAccount.getUserId())) {
            LogUtil.d("EZRTCImpl", "self bindView getScreenTextureView initApi");
            ErtcTextureView self = mView.getScreenTextureView();
            self.isShowLoadingProgress = false;
            self.hideProgress();
            if(mScreenAccount.getVideoStatus() == DeviceState.DS_Active.getValue()) {
                LogUtil.d("EZRTCImpl", "initApi setLocalViewChanged getScreenTextureView");
                ErtcEzmHelper.ertcEngine.setLocalViewChanged(self.getVideoCanvasView());
            }
        }

        ertcInitEnterRoom();
    }

    private void ertcInitEnterRoom() {
        LogUtil.d("EZRTCImpl", "ertcInitEnterRoom ErtcEzmHelper.ertcEngine：" + (ErtcEzmHelper.ertcEngine != null));
        if(ErtcEzmHelper.ertcEngine != null) {
            RTCConstant.EnterParam mInfo = new RTCConstant.EnterParam();
            mInfo.userId = mRoomData.userId;
            mInfo.roomId = mRoomData.roomId;
            mInfo.token = mRoomData.token;
            ErtcEzmHelper.ertcEngine.enterRoom(mInfo, RTCConstant.Scene.VideoCall);
        }
    }

    private void enableLocalVideo(boolean isVideoOn) {
        ErtcEzmHelper.ertcEngine.enableLocalVideo(isVideoOn);
    }

    private void postHideCover() {
        mCoverHandler = new Handler();
        mCoverHandler.postDelayed(mCoverRunnable, 5000);
    }

    boolean accountOnScreen(UserAccount account) {
        return mScreenAccount.getUserId().equals(account.getUserId())
                || mGroupView.hasMember(account.getUserId());
    }

    @SuppressLint("NewApi")
    private void updateScreenView() {
        if (mScreenAccount != null) {
            //视频状态与是否正在共享有关：若正在共享屏幕，不显示关闭状态；若自己正在共享屏幕，按状态显示。
            if (mScreenAccount.getVideoStatus() != DeviceState.DS_Active.getValue()
                    && (!mSharingDesktopUserId.equals(mScreenAccount.getUserId())
                    || (mSharingDesktopUserId.equals(mMyAccount.getUserId())
                    && mScreenAccount.getUserId().equals(mMyAccount.getUserId())))) {
                mView.hideScreenAccountVideo();
                mView.showFlowView(false);
                mView.updateScreenAccountView(null,
                        mScreenAccount.getUserId(),
                        mScreenAccount.getAudioStatus() == DeviceState.DS_Active.getValue());
                mView.updateScreenKpsLevel(NetLevelUtil.INSTANCE.getNetLevel(mScreenAccount.getUpNetQuality()));
            } else {
                mView.showScreenAccountVideo();
                mView.showFlowView(true);
                mView.updateFlowViewLevel(NetLevelUtil.INSTANCE.getNetLevel(mScreenAccount.getDownNetQuality()));
                mView.updateFlowViewAudio(mScreenAccount.getAudioStatus() == DeviceState.DS_Active.getValue());
                mView.updateFlowViewName(mScreenAccount.getUserId());
            }
            mView.setScreenAccountStreamId(mScreenAccount.getUserId() + "", MtSets.isDebug());

        }
    }

    void updateAccountView(UserAccount account) {
        if(account == null) return;
        mGroupView.notifyItemChanged(account);
        if (mScreenAccount.getUserId().equals(account.getUserId())) {
            setScreenAccount(account);
        }
    }

    void updateWaterMarkVisibility() {
        mView.getScreenTextureView().setWaterMark(mMyAccount.getUserId(), mMyAccount.getUserId());
        mView.getScreenTextureView().setWaterMarkSize(ViewUtil.dp2px(mView.getActivity(), 30));
        mView.getScreenTextureView().showWaterMark(mWaterMarkOn);
        mGroupView.showWaterMark(mWaterMarkOn);
        mGroupView.updateWaterMark();
    }

    private void startFlow() {
        Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {

                    @Override
                    public void onSubscribe(Disposable d) {
                        mFlowDisposable = d;
                    }

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onNext(Long count) {
                        long hour = count / 3600;
                        long minute = count % 3600 / 60;
                        long second = count % 3600 % 60;
                        mView.onFlow(String.format("%02d:%02d:%02d", hour, minute, second));
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    @Override
    public void switchCamera() {
        mIsBackCamera = !mIsBackCamera;
        if (ErtcEzmHelper.ertcEngine != null) {
            ErtcEzmHelper.ertcEngine.switchCamera();
        }
    }

    @Override
    public void toggleMicro() {
        //从hiklink崩溃日志发现的
        //规避空指针
        if (mMyAccount == null) {
            return;
        }
        boolean hasAudioPermission = ContextCompat.checkSelfPermission(mView.getActivity(), Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
        if (mMyAccount.getAudioStatus() != DeviceState.DS_Active.getValue() && !hasAudioPermission) {
            mView.requestToggleMicrophonePermission();
            return;
        }
        if (mMyAccount.getAudioStatus() == DeviceState.DS_Active.getValue()) {
            toggleMicro(DeviceState.DS_Closed);
            mView.showToast(R.string.ys_mt_room_toast_audio_off);
        } else {
            toggleMicro(DeviceState.DS_Active);
            mView.showToast(R.string.ys_mt_room_toast_audio_on);
        }
    }

    void toggleMicro(final DeviceState state) {
        LogUtil.d("EZRTCImpl", "enableLocalAudio state:" + state.name());
        if(ErtcEzmHelper.ertcEngine == null) {
            LogUtil.d("EZRTCImpl", "enableLocalAudio ErtcEzmHelper.ertcEngine == null");
            return;
        }
        ErtcEzmHelper.ertcEngine.enableLocalAudio(state == DeviceState.DS_Active);
        mMyAccount.setAudioStatus(state.getValue());
        LogUtil.d("EZRTCImpl", "self bindView toggleMicro account:" + mMyAccount.getUserId());
        mView.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mView.setMicroState(state == DeviceState.DS_Active);
                updateAccountView(mMyAccount);
                //自己操作自己不会走notifyMyAccount，需要手动通知
                EventBus.getDefault().post(new MtAccountNotifyEvent(mMyAccount));
            }
        });
    }

    @Override
    public void toggleCamera() {
        //从hiklink崩溃日志发现的
        //规避空指针
        if (mMyAccount == null) {
            return;
        }
        if (isSharing() && mMyAccount.getVideoStatus() != DeviceState.DS_Active.getValue()) {
            mView.showToast(R.string.ys_mt_room_toast_video_off_force_sharing);
            return;
        }
        boolean hasVideoPermission = ContextCompat.checkSelfPermission(mView.getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        if (mMyAccount.getVideoStatus() != DeviceState.DS_Active.getValue() && !hasVideoPermission) {
            mView.requestToggleCameraPermission();
            return;
        }

        if (mMyAccount.getVideoStatus() == DeviceState.DS_Active.getValue()) {
            toggleCamera(DeviceState.DS_Closed);
            //防止退出activity时执行autoCloseVideo()导致toast
            if (!mView.getActivity().isFinishing())
                mView.showToast(R.string.ys_mt_room_toast_video_off);
        } else {
            toggleCamera(DeviceState.DS_Active);
            mView.showToast(R.string.ys_mt_room_toast_video_on);
        }
    }

    public void toggleCamera(DeviceState state) {
        mView.setCameraState(state == DeviceState.DS_Active);
        if(ErtcEzmHelper.ertcEngine == null) {
            LogUtil.d("EZRTCImpl", "enableLocalVideo ErtcEzmHelper.ertcEngine == null state:" + state.name());
            return;
        }
        LogUtil.d("EZRTCImpl", "enableLocalVideo:" + state.name());
        enableLocalVideo(state == DeviceState.DS_Active);
        mMyAccount.setVideoStatus(state.getValue());
        LogUtil.d("EZRTCImpl", "self bindView toggleCamera account:" + mMyAccount.getUserId());
        updateAccountView(mMyAccount);
    }

    @Override
    public void toggleSound() {
        mSoundOn = !mSoundOn;
        mView.setSoundState(mSoundOn);
        if(ErtcEzmHelper.ertcEngine != null) {
            ErtcEzmHelper.ertcEngine.setSpeakerPhoneOn(mSoundOn);
        }
    }

    @Override
    public void toMemberManage() {
        mView.showToast("待实现");
    }

    @Override
    public void toMemberManageCalling() {
        mView.showToast("待实现");
    }

    @Override
    public void toMeetingSets() {
        autoCloseVideo();
        MeetingSetsActivity.start(mView.getActivity(),
                mWaterMarkOn,
                true,
                mRoomData.roomId,
                isAudioMode);
    }

    /**
     * 有些手机共享照片选择图片以后无数据返回
     */
    @Override
    public void toAlbumProxy() {
        mView.showToast("待实现");
    }

    @Override
    public void toBeautyConfig() {
        autoCloseVideo();
        //三星手机,关闭摄像机入会,横竖屏切换以后进入美颜会打不开相机,怀疑是相机被占用,调用此方法解除占用
//        mRoomClient.enableSendVideo(Models.DeviceState.DS_Closed);
        if (ErtcEzmHelper.ertcEngine != null) {
            enableLocalVideo(false);
        }
        canBeauty = false;
        //todo 美颜设置
//        FURenderer.getInstance().release();
        BeautyConfigActivity.startBeautyConfig(mView.getActivity());
    }

    @Override
    public void onNewIntent() {
    }

    @SuppressLint("NewApi")
    @Override
    public void showMonitor() {
        mView.animCoverHide();
        mMonitorDialog = new ErtcMonitorDialog(mView.getActivity());
        mMonitorDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                ErtcEzmHelper.ertcEngine.setQualityInterval(MONITOR_GAP_DEFAULT);
                mMonitorDialog = null;
                mView.animCoverShow();
            }
        });
        mMonitorDialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                mMonitorDialog.onSharingTypeChanged(mSharingType, TextUtils.equals(mSharingAccountId, mMyAccount.getUserId()));

                ErtcEzmHelper.ertcEngine.setQualityInterval(MONITOR_GAP_LOW);
            }
        });
        mMonitorDialog.show();
    }

    @Override
    public void onMessageEvent(MtExitRoomEvent event) {
        release("received MtExitRoomEvent");
    }

    @Override
    public void onMessageEvent(MtSwitchStimulationEvent event) {
        mIsVoiceStimulation = event.enable;
    }

    @Override
    public void onMessageEvent(MtSwitchMemberToastEvent event) {
        mIsShowMemberToast = event.enable;
    }

    @Override
    public void onMessageEvent(MtSwitchWaterMarkEvent event) {
        mView.showToast("待实现");
    }

    @Override
    public void onMessageEvent(MtToggleSelfAudioEvent event) {
        toggleMicro();
    }

    @Override
    public void onMessageEvent(MtAudioModeEvent event) {
        isAudioMode = event.enable;
        //todo 音频模式
        if(!isSharing()){
            //取消所有订阅
            if(event.enable) {
                synchronized (ErtcRoomPresenter.sAccountList) {
                    for (UserAccount account : ErtcRoomPresenter.sAccountList) {
                        if (account.getVideoStatus() == DeviceState.DS_Active.getValue()) {
                            account.setVideoStatus(event.enable ? DeviceState.DS_Closed.getValue() : DeviceState.DS_Active.getValue());
                            mGroupView.notifyItemChanged(account);
                        }
                    }
                }
                if (mScreenAccount.getVideoStatus() == DeviceState.DS_Active.getValue()) {
                    mScreenAccount.setVideoStatus(event.enable ? DeviceState.DS_Closed.getValue() : DeviceState.DS_Active.getValue());
                }
                setScreenAccount(mScreenAccount);
            } else {
                Iterator<String> iter = accountVideoStateMap.keySet().iterator();
                while (iter.hasNext()){
                    String userId = iter.next();
                    for (UserAccount account : ErtcRoomPresenter.sAccountList) {
                        if (account.getUserId().equals(userId)) {
                            boolean notify = account.getVideoStatus() == DeviceState.DS_Closed.getValue() && accountVideoStateMap.get(userId);
                            account.setVideoStatus(accountVideoStateMap.get(userId) ? DeviceState.DS_Active.getValue() : DeviceState.DS_Closed.getValue());
                            if(notify) {
                                mGroupView.notifyItemChanged(account);
                            }
                            break;
                        }
                    }
                    if(mScreenAccount.getUserId().equals(userId)) {
                        mScreenAccount.setVideoStatus(accountVideoStateMap.get(userId) ? DeviceState.DS_Active.getValue() : DeviceState.DS_Closed.getValue());
                        setScreenAccount(mScreenAccount);
                    }
                }
            }
        }
    }

    @Override
    public void onMessageEvent(MtToTestEvent event) {
        TestConfigActivity.start(mView.getActivity());
    }

    @Override
    public void onMessageEvent(MtCallStateEvent event) {
        switch (event.state) {
            case TelephonyManager.CALL_STATE_RINGING://响铃
                LogUtil.i("MtCallStateEvent", "TelephonyManager===响铃");
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK://接听或拨打
                LogUtil.i("MtCallStateEvent","TelephonyManager===接听或拨打");
                if (mMyAccount.getAudioStatus() == DeviceState.DS_Active.getValue()) {
                    toggleMicro();
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE://挂断
                LogUtil.i("MtCallStateEvent","TelephonyManager===挂断");
                break;
        }
    }

    @Override
    public void onMessageEvent(MtLanActionEvent event) {
        switch (event.action) {
            case MtAction.ACTION_LEAVE_ROOM:
                release("ACTION_LEAVE_ROOM");
                break;
            case MtAction.ACTION_SET_AUDIO:
                if (event.status == 1) {
                    if (mMyAccount.getAudioStatus() != DeviceState.DS_Active.getValue())
                        toggleMicro(DeviceState.DS_Active);
                } else {
                    if (mMyAccount.getAudioStatus() != DeviceState.DS_Closed.getValue())
                        toggleMicro(DeviceState.DS_Closed);
                }
                break;
            case MtAction.ACTION_SET_VIDEO:
                if (event.status == 1) {
                    if (mMyAccount.getVideoStatus() != DeviceState.DS_Active.getValue())
                        toggleCamera(DeviceState.DS_Active);
                } else {
                    if (mMyAccount.getVideoStatus() != DeviceState.DS_Closed.getValue())
                        toggleCamera(DeviceState.DS_Closed);
                }
                break;
            case MtAction.ACTION_SET_SPEAKER:
                if (event.status == DeviceState.DS_Active.getValue()) {
                    if (!mSoundOn){
                        toggleSound();
                    }
                } else {
                    if (mSoundOn){
                        toggleSound();
                    }
                }
                break;
        }
    }

    void onErtcShareModeDesktop(String sharingStreamId) {
        try {
            //shareStreamId != mSharingDesktopStreamId这个情况是一方掉线以后mSharingDesktopStreamId未更改
            if (mSharingDesktopUserId.isEmpty() || sharingStreamId != mSharingDesktopUserId) {
                mSharingDesktopUserId = sharingStreamId;

                startShare(!TextUtils.equals(mSharingAccountId, mMyAccount.getUserId()));

                //录屏时，必须打开TextureView
                if (mScreenAccount.getUserId().equals(mSharingDesktopUserId)) {
                    updateScreenView();
                } else {
                    synchronized (ErtcRoomPresenter.sAccountList) {
                        for (UserAccount account1 : ErtcRoomPresenter.sAccountList) {
                            if (account1.getUserId().equals(mSharingDesktopUserId)) {
                                mGroupView.notifyItemChanged(account1);
                                mGroupView.notifySwitchToScreen(account1);
                                break;
                            }
                        }
                    }
                }
                mPictureInPictureSaved = mPictureInPicture;
                setPInP(false);
                mGroupView.hideGroupView();
                mView.getScreenTextureView().setEnableScale(mView.getActivity(), true);
                mView.getScreenTextureView().cleanLastFrame();

                if(!TextUtils.equals(mSharingAccountId, mMyAccount.getUserId())) {
                    if (ErtcEzmHelper.ertcEngine != null) {
                        ErtcEzmHelper.ertcEngine.setShareViewScaleEnable(true);
                        ErtcEzmHelper.ertcEngine.setLocalViewChanged(null);
                        ErtcEzmHelper.ertcEngine.setRemoteViewChanged(null, mScreenAccount.getUserId());
                        ErtcEzmHelper.ertcEngine.setScreenShareWindow(mView.getScreenTextureView().getVideoCanvasView());
                        mView.getScreenTextureView().hideProgress();
                    }
                }
            }
        } catch (Exception e) {
            mSharingDesktopUserId = "";
            mSharingDesktopMask = 0;
        }
    }


    /**
     * @param isSelfSharing
     * @param isOffline     掉线以后，仅停止录屏，否则重连以后如果有其他人共享则会有问题
     */
    void onErtcShareModeNone(boolean isSelfSharing, boolean isOffline) {
        if (!TextUtils.isEmpty(mSharingAccountId) && !isSelfSharing) {
            mView.showToast(String.format(mView.getActivity().getResources().getString(R.string.ys_mt_room_share_stop_format), mSharingAccountId));
        }
        if (!mSharingDesktopUserId.isEmpty()) {
            LogUtil.d("EZRTCImpl", "self bindView getScreenTextureView onShareModeNone");
            mView.getScreenTextureView().setEnableScale(mView.getActivity(), false);
            if (mSharingDesktopUserId.equals(mMyAccount.getUserId())) {
                if (isOffline) {
                    stopScreenShare();
                } else {
                    stopRecording();
                }
            }
            if (mScreenAccount.getUserId().equals(mSharingDesktopUserId)) {
                ErtcEzmHelper.ertcEngine.setRemoteVideoStreamType(mScreenAccount.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG);

                //解决残留共享最后一帧的问题
                mView.getScreenTextureView().cleanLastFrame();
            }
            mSharingDesktopUserId = "";
            mSharingDesktopMask = 0;
            if(ErtcEzmHelper.ertcEngine != null) {
                ErtcEzmHelper.ertcEngine.setShareViewScaleEnable(false);
                ErtcEzmHelper.ertcEngine.setScreenShareWindow(null);
                if (mScreenAccount.getUserId().equals(mMyAccount.getUserId())) {
                    LogUtil.d("EZRTCImpl", "onErtcShareModeNone setLocalViewChanged");
                    ErtcEzmHelper.ertcEngine.setLocalViewChanged(mMyAccount.getVideoStatus() == DeviceState.DS_Active.getValue() ? mView.getScreenTextureView().getVideoCanvasView() : null);
                    mView.getScreenTextureView().hideProgress();
                } else {
                    LogUtil.d("EZRTCImpl", "setRemoteViewChanged onErtcShareModeNone id:" + mScreenAccount.getUserId() + " state:" + mScreenAccount.getVideoStatus());
                    ErtcEzmHelper.ertcEngine.setRemoteViewChanged(mScreenAccount.getVideoStatus() == DeviceState.DS_Active.getValue() ? mView.getScreenTextureView().getVideoCanvasView() : null, mScreenAccount.getUserId());
                    if(mScreenAccount.getVideoStatus() == DeviceState.DS_Active.getValue()) {
                        mView.getScreenTextureView().showProgress();
                    } else {
                        mView.getScreenTextureView().hideProgress();
                    }
                }

            }
            updateScreenView();
        }
        setPInP(mPictureInPictureSaved);
        if (mPictureInPictureSaved) {
            mGroupView.showGroupView();
        }
        mView.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
        stopShare();
    }

    @Override
    public void onConfigurationChanged(int orientation) {
        //横竖屏切换时情空一下画布
        LogUtil.d("EZRTCImpl", "onConfigurationChanged orientation:" + orientation);
        mView.getScreenTextureView().cleanLastFrame();
    }

    public boolean isBusyRecording = false;
    @Override
    public void startRecord() {
        if (isBusyRecording) {
            LogUtil.i("EZRTCImpl", "startRecord===BusyRecording===停止录屏");
            stopScreenShare();
            isBusyRecording = false;
        } else {
            LogUtil.i("EZRTCImpl", "startRecord===开始录屏");
            if (ErtcEzmHelper.ertcEngine != null) {
                ErtcEzmHelper.ertcEngine.initShareScreen("Screen_Crasher", new OnApplyResultListener() {
                    @Override
                    public void onResult(boolean success) {
                        if (!success) {
                            onShareConflict("会议分享人数达到上限，您不能分享了");
                        } else {
                            if (!mSharingDesktopUserId.isEmpty() && !mSharingDesktopUserId.equals(mMyAccount.getUserId())) {
                                onShareConflict("录屏回调===共享冲突，停止自己的录屏");
                            }
                        }
                    }
                });
                ErtcEzmHelper.ertcEngine.requestShareScreenPermission(getView().getActivity(), REQUEST_MEDIA_PROJECTION);
            }
        }
    }

    @Override
    public void createScreenRecorder(int requestCode, int resultCode, Intent data) {
        LogUtil.d("EZRTCImpl", "createScreenRecorder ");
        isBusyRecording = true;
        mSharingType = SharingType.ST_Desktop;
        isErtcSharingScreen = true;
        mSharingAccountId = mMyAccount.getUserId();
        startShare(!TextUtils.equals(mSharingAccountId, mMyAccount.getUserId()));
        toggleCamera(DeviceState.DS_Closed);
        //横竖屏切换时会暂停，所以加这个判断
        if (mSharingDesktopUserId.isEmpty()) {
            mSharingDesktopUserId = mMyAccount.getUserId();
            bindFloatService();
            //回到桌面
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addCategory(Intent.CATEGORY_HOME);
            mView.getActivity().startActivity(intent);
        }
    }

    @Override
    public void stopShareService() {
        Intent intent = new Intent(mView.getActivity(), ErtcVideoMeetingService.class);
        mView.getActivity().stopService(intent);
    }

    @Override
    public void onLeave() {
        mView.showHostLeaveDialog();
    }

    @Override
    public void endMeeting() {
        ErtcEzmHelper.ertcEngine.dissolveRoom();
        release("endMeeting 会议结束");
    }

    @Override
    public void setErtcEngineIsNullLeaveState(boolean state) {
        isErtcEngineNullLeave = state;
    }

    /**
     * @param cause 记录退出原因
     */
    @Override
    public void release(String cause) {
        LogUtil.i("EZRTCImpl", "release===cause[" + cause + "]");
        if(ErtcEzmHelper.ertcEngine != null) {
            ErtcEzmHelper.ertcEngine.setLocalView(null);
            ErtcEzmHelper.ertcEngine.setLocalViewChanged(null);
            ErtcEzmHelper.ertcEngine.setScreenShareWindow(null);
            enableLocalVideo(false);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    ErtcEzmHelper.ertcEngine.exitRoom();
                }
            }).start();
            ErtcEzmHelper.ertcEngine.setRTCListener(null);
            ErtcEzmHelper.ertcEngine.setRtcStatsListener(null);
        }
       
        YsBaseActivity.TOP_ACTIVITY = null;
        cancelCoverHandler();
        unbindFloatService();
        if (mFlowDisposable != null) {
            mFlowDisposable.dispose();
            mFlowDisposable = null;
        }
       
        if (mView != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mView.getActivity().finishAndRemoveTask();
            } else {
                mView.finish();
            }
        }
        ErtcRoomPresenter.sAccountList.clear();
    }


    @Override
    public void onPause() {
    }

    @Override
    public void onStop() {
        mIsOnFront = false;
        autoCloseVideo();
    }

    @Override
    public void onRestart() {
        mIsOnFront = true;
        autoOpenVideo();
    }

    @Override
    public void onResume() {
        //todo 美颜设置
        mIsBeautyEnable = MtSets.isEnableBeauty();
        canBeauty = true;
    }

    private void autoCloseVideo() {
        if (mMyAccount != null && mMyAccount.getVideoStatus() == DeviceState.DS_Active.getValue()) {
            mNeedCloseVideo = true;
            toggleCamera(DeviceState.DS_Closed);
        }
    }

    private void autoOpenVideo() {
        if (mNeedCloseVideo && !isSharing() && mMyAccount.getVideoStatus() != DeviceState.DS_Active.getValue()) {
            toggleCamera(DeviceState.DS_Active);
            mNeedCloseVideo = false;
        }
    }

    @SuppressLint("NewApi")
    @Override
    public boolean isDestroy() {
        return mView.getActivity() == null || mView.getActivity().isDestroyed() || mView.getActivity().isFinishing();
    }

    @Override
    public void cancelCoverHandler() {
        if (mCoverHandler != null) {
            mCoverHandler.removeCallbacks(mCoverRunnable);
            mCoverHandler = null;
        }
    }

    @Override
    public void setLowStream(UserAccount account) {
        //如果此人在大图，不切换为小图
        if (account.getUserId().equals(mScreenAccount.getUserId())) {
            setHighStream(account);
            return;
        }
        LogUtil.i("EZRTCImpl", "setRemoteVideoStreamType setLowStream===取小流===" + "nickname:" + account.getUserId());
        ErtcEzmHelper.ertcEngine.setRemoteVideoStreamType(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL);
    }

    @Override
    public void setLowStreamForce(UserAccount account) {
        LogUtil.i("EZRTCImpl", "setRemoteVideoStreamType setLowStreamForce===取小流===" + "nickname:" + account.getUserId());
        ErtcEzmHelper.ertcEngine.setRemoteVideoStreamType(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL);
    }

    @Override
    public void setHighStream(UserAccount account) {
        if (account.getUserId().equals(mMyAccount.getUserId())) {
            return;
        }
        if (mForceLowStream) {
            LogUtil.i("EZRTCImpl", "setRemoteVideoStreamType setHighStream===取小流==mForceLowStream==" + "nickname:" + account.getUserId());
            ErtcEzmHelper.ertcEngine.setRemoteVideoStreamType(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL);
        } else {
            LogUtil.i("EZRTCImpl", "setRemoteVideoStreamType setHighStream===取大流===" + "nickname:" + account.getUserId());
            ErtcEzmHelper.ertcEngine.setRemoteVideoStreamType(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG);
        }
    }

    /**
     * 不接收所有人视频流
     */
    @Override
    public void disableReceiveStreamAll() {
        if(ErtcEzmHelper.ertcEngine != null) {

        }
    }

    @Override
    public void disableReceiveStream(String userId) {
        synchronized (ErtcRoomPresenter.sAccountList) {
            for (UserAccount account : ErtcRoomPresenter.sAccountList) {
                if (account.getUserId().equals(userId)) {
                    if(ErtcEzmHelper.ertcEngine != null) {
                        ErtcEzmHelper.ertcEngine.subScribe(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG, false);
                    }
                    break;
                }
            }
        }
    }

    @Override
    public void enableReceiveStream(String userId) {
        synchronized (ErtcRoomPresenter.sAccountList) {
            for (UserAccount account : ErtcRoomPresenter.sAccountList) {
                if (account.getUserId().equals(userId)) {
                    if(ErtcEzmHelper.ertcEngine != null) {
                        ErtcEzmHelper.ertcEngine.subScribe(account.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG, true);
                    }
                    break;
                }
            }
        }
    }

    @Override
    public String getSharingDesktopUserId() {
        return mSharingDesktopUserId;
    }

    @Override
    public void setScreenAccount(UserAccount account) {
        if (mScreenAccount != null) {
            if (account == null || !mScreenAccount.getUserId().equals(account.getUserId())) {
                mView.getScreenTextureView().cleanLastFrame();
            }
        }
        if (account != null) {
            LogUtil.d("EZRTCImpl", "setScreenAccount size：" + sAccountList.size() +" accountId:" + account.getUserId() + " screenId:" + mScreenAccount.getUserId() + " myid:" + mMyAccount.getUserId());
            if(ErtcEzmHelper.ertcEngine != null) {
                if (account.getUserId().equals(mMyAccount.getUserId())) {
                    //切换本地为大屏
                    //目前大屏是远端，远端大屏设为null
//                    if (!mScreenAccount.getUserId().equals(account.getUserId())) {
//                        LogUtil.d("EZRTCImpl", "setRemoteViewChanged setScreenAccount id:" + mScreenAccount.getUserId() + " null sAccountList.size()>=1");
//                        ErtcEzmHelper.ertcEngine.setRemoteViewChanged(null, mScreenAccount.getUserId());
//                    }
                    LogUtil.d("EZRTCImpl", "setScreenAccount setLocalViewChanged");
                    ErtcEzmHelper.ertcEngine.setLocalViewChanged(account.getVideoStatus() == DeviceState.DS_Active.getValue() ? mView.getScreenTextureView().getVideoCanvasView() : null);
                    mView.getScreenTextureView().hideProgress();
                } else {
                    //切换远端为大屏
                    //目前大屏是本地，本地大屏设为null
                    //目前大屏是其他远端，其他远端大屏设为null
//                    if (mScreenAccount.getUserId().equals(mMyAccount.getUserId())) {
//                        LogUtil.d("EZRTCImpl", "setScreenAccount setLocalViewChanged null");
//                        ErtcEzmHelper.ertcEngine.setLocalViewChanged(null);
//                    } else if(!mScreenAccount.getUserId().equals(account.getUserId())) {
//                        LogUtil.d("EZRTCImpl", "setScreenAccount setRemoteViewChanged null " + mScreenAccount.getUserId());
//                        ErtcEzmHelper.ertcEngine.setRemoteViewChanged(null, mScreenAccount.getUserId());
//                    }
                    LogUtil.d("EZRTCImpl", "setScreenAccount setRemoteViewChanged" + account.getUserId());
                    ErtcEzmHelper.ertcEngine.setRemoteViewChanged(account.getVideoStatus() == DeviceState.DS_Active.getValue() ? mView.getScreenTextureView().getVideoCanvasView() : null, account.getUserId());
                    if(account.getVideoStatus() == DeviceState.DS_Active.getValue() && !mScreenAccount.getUserId().equals(account.getUserId())) {
                        mView.getScreenTextureView().showProgress();
                    } else {
                        mView.getScreenTextureView().hideProgress();
                    }
                }
            }
            if (mScreenAccount == null || !mScreenAccount.getUserId().equals(account.getUserId())) {
                setHighStream(account);
            }
            mScreenAccount = account;
            updateScreenView();
            if (mDesktopPInPBinder != null)
                mDesktopPInPBinder.setAccount(mScreenAccount, mSharingType);
        }
    }

    @Override
    public UserAccount getScreenAccount() {
        return mScreenAccount;
    }

    @Override
    public UserAccount getMyAccount() {
        return mMyAccount;
    }

    @Override
    public void openWhiteBoard() {
        mView.showToast("待实现");
    }

    @Override
    public void shareWithPhoto(Uri data) {
        mView.showToast("待实现");
    }

    @Override
    public boolean closeShare() {
        cancelCoverHandler();//弹出分享的时候不要隐藏
        //不是主持人时，不是自己发起的共享不能取消
//        if (mSharingType != SharingType.ST_None && !TextUtils.equals(mSharingAccountId, mMyAccount.getUserId())) {
//            return true;
//        }
        if (mSharingType != SharingType.ST_None) {
            String title = null;
            if (TextUtils.equals(mSharingAccountId, mMyAccount.getUserId())) {
                title = mView.getActivity().getResources().getString(R.string.ys_mt_room_share_end_title);
            } else if (mSharingAccountId != null) {
                title = String.format(mView.getActivity().getResources().getString(R.string.ys_mt_room_share_end_title_host_format), mSharingAccountId);
            } else {
                title = mView.getActivity().getResources().getString(R.string.ys_mt_room_share_end_title_host);
            }
            final String finalTitle = title;
            mStopShareDialog = new EZDialog.Builder(mView.getActivity())
                    .setTitle(title)
                    .setPositiveButton(R.string.ezm_confirm, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            LogUtil.i("EZRTCImpl", finalTitle + "====确定");
                            if(TextUtils.equals(mSharingAccountId, mMyAccount.getUserId())) {
                                stopShareForce();
                            } else {
                                ErtcEzmHelper.ertcEngine.forceCloseOtherScreenShare();
                            }
                        }
                    })
                    .setNegativeButton(R.string.ezm_cancel, null)
                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            mStopShareDialog = null;
                        }
                    })
                    .show();
            return true;
        }
        return false;
    }

    @Override
    public void setPInP(boolean on) {
        if (mPictureInPicture == on) {
            return;
        }
        mPictureInPicture = on;
        //关闭以后不接收其他人的视频流
        if (!mPictureInPicture) {
            disableReceiveStreamAll();
            if(ErtcEzmHelper.ertcEngine != null && !mScreenAccount.getUserId().equals(mMyAccount.getUserId())) {
                ErtcEzmHelper.ertcEngine.subScribe(mScreenAccount.getUserId(), RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG, true);
            }
        } else {
            Set<String> set = mGroupView.getCurrentPageAccounts();
            if(!mScreenAccount.getUserId().equals(mMyAccount.getUserId())) {
                set.add(mScreenAccount.getUserId());
            }
            for (String string : set) {
                enableReceiveStream(string);
            }
        }
    }

    @Override
    public boolean isPInP() {
        return mPictureInPicture;
    }

    //如果多方同时开始共享，判断不是自己则关闭自己的共享
    //多人同时点共享导致冲突，关掉自己的共享
    void onShareConflict(String log) {
        LogUtil.i("EZRTCImpl", log);
        mView.showToast(R.string.ys_mt_room_share_conflict_toast);
        //仅停止录屏
        stopScreenShare();
    }

    void stopScreenShare() {
        if(ErtcEzmHelper.ertcEngine != null) {
            isErtcSharingScreen = false;
            mSharingAccountId = "";
            mSharingDesktopUserId = "";
            ErtcEzmHelper.ertcEngine.stopScreenShare();
            mSharingType = SharingType.ST_None;
        }
//        stopShareService();
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////
    //录屏
    /////////////////////////////////////////////////////////////////////////////////////////////////
    private void initRecording() {
        if(ErtcEzmHelper.ertcEngine != null) {
            RTCConstant.ERTCVideoEncParam videoEncParam = new RTCConstant.ERTCVideoEncParam();
            videoEncParam.videoResolution = ConstantKeys.resolutionShare;
            videoEncParam.videoFps = ConstantKeys.videoFpsShare;
            videoEncParam.videoBitrate = ConstantKeys.resolutionShare.getRecommendBitrate();
            ErtcEzmHelper.ertcEngine.setScreenShareEncoderParam(videoEncParam);
            LogUtil.d("EZRTCImpl", "share param fps:" + videoEncParam.videoFps + " Resolution:"+ videoEncParam.videoResolution.getWidth() + "x" + videoEncParam.videoResolution.getHeight());
        }
    }

    @SuppressLint("NewApi")
    public void stopRecording() {
        LogUtil.i("EZRTCImpl", "stopRecording===停止录屏");
        //回到app
        AirActivity.start(mView.getActivity());
        //如果此时开启了画中画，应该关闭
        stopDesktopPInP();
        //停止录屏
        stopShareForce();
    }

    private void bindFloatService() {
        if (mFloatIntent == null) {
            mFloatIntent = new Intent(mView.getActivity(), FloatingButtonService.class);
        }
        mView.getActivity().bindService(mFloatIntent, mFloatingButtonConnection, Service.BIND_AUTO_CREATE);
    }

    private void unbindFloatService() {
        try {
            if (mFloatIntent != null) {
                mView.getActivity().unbindService(mFloatingButtonConnection);
            }
        } catch (Exception e) {
        }
    }

    void startShare(boolean disable) {
        //如果是disable，不需要改变icon
        mView.setShareState(disable, disable);
    }

    void stopShareForce() {
        isForceStopShare = true;
        if(isErtcSharingScreen) {
            stopScreenShare();
        }
        stopShare();
        isBusyRecording = false;
    }

    private void stopShare() {
        unbindFloatService();
        //SAASCMC-1127【停止共享】主持人和共享发起方（非主持人）同时点停止共享，主持人先确认停止共享，屏幕共享方停止共享弹窗一直存在
        if (mStopShareDialog != null && mStopShareDialog.isShowing()) {
            mStopShareDialog.dismiss();
        }
        mView.setShareState(true, false);
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////
    //桌面画中画
    /////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public void startDesktopPInP() {
        bindPInPService();
        mPictureInPictureSaved = mPictureInPicture;
        setPInP(false);
        mGroupView.hideGroupView();
        //隐藏activity
        mView.getActivity().moveTaskToBack(true);
    }

    @Override
    public boolean isSharing() {
        return mSharingType != SharingType.ST_None;
    }

    private void bindPInPService() {
        if (mPInPIntent == null) {
            mPInPIntent = new Intent(mView.getActivity(), ErtcPictureInPictureService.class);
        }
        mView.getActivity().bindService(mPInPIntent, mDesktopPInPConnection, Service.BIND_AUTO_CREATE);
    }

    private void unbindPInPService() {
        try {
            if (mPInPIntent != null) {
                mView.getActivity().unbindService(mDesktopPInPConnection);
            }
        } catch (Exception e) {
        }
    }

    @SuppressLint("NewApi")
    public void stopDesktopPInP() {
        try {
            if (mPInPIntent != null) {
                unbindPInPService();
                mPInPIntent = null;
                setPInP(mPictureInPictureSaved);
                if (mPictureInPictureSaved) {
                    mGroupView.showGroupView();
                }
                //回到app
                AndroidUtil.moveAppToFront(mView.getActivity());//这句代码不能去，部分手机单独startActivity无法回到页面
                Intent intent = new Intent(mView.getActivity(), ErtcRoomActivity.class);
                mView.getActivity().startActivity(intent);
            }
        } catch (Exception e) {
        }
    }

    @Override
    public void onDestroy() {
        //未走release，导致资源未释放的情况
        if (mFlowDisposable != null) {
            //异常退出时保存房间信息
            release("onDestroy[异常退出]===setSavedRoomInfo:" + mRoomData.roomId);
        } else if(isErtcEngineNullLeave) {
            isErtcEngineNullLeave = false;
            release("onDestroy[异常退出]===isErtcEngineNullLeave");
        } else {
            LogUtil.i("EZRTCImpl", "onDestroy[正常退出]===setSavedRoomInfo(null)");
//            MtSets.setSavedRoomInfo(null, null);
        }
        LogUtil.i("EZRTCImpl", "=========================================================onDestroy");
        ErtcEzmHelper.getInstance().release();
        unbindFloatService();
        unbindPInPService();
    }

    @Override
    public ErtcRoomContract.View getView() {
        return mView;
    }

}
