public void onRepNormalGroupList(IMGroup.IMNormalGroupListRsp normalGroupListRsp) {
    logger.i("group#onRepNormalGroupList");
    int groupSize = normalGroupListRsp.getGroupVersionListCount();
    logger.i("group#onRepNormalGroupList cnt:%d", groupSize);
    List<IMBaseDefine.GroupVersionInfo> versionInfoList =
        normalGroupListRsp.getGroupVersionListList();

    /** 对比DB中的version字段 */
    // 这块对比的可以抽离出来
    List<IMBaseDefine.GroupVersionInfo> needInfoList = new ArrayList<>();

    for (IMBaseDefine.GroupVersionInfo groupVersionInfo : versionInfoList) {
      int groupId = groupVersionInfo.getGroupId();
      int version = groupVersionInfo.getVersion();
      if (groupMap.containsKey(groupId) && groupMap.get(groupId).getVersion() == version) {
        continue;
      }
      IMBaseDefine.GroupVersionInfo versionInfo =
          IMBaseDefine.GroupVersionInfo.newBuilder().setVersion(0).setGroupId(groupId).build();
      needInfoList.add(versionInfo);
    }

    // 事件触发的时候需要注意 todo
    if (needInfoList.size() > 0) {
      reqGetGroupDetailInfo(needInfoList);
    }
  }
 /** 联系人页面正式群的请求 todo 正式群与临时群逻辑上的分开的,但是底层应该是想通的 */
 private void reqGetNormalGroupList() {
   logger.i("group#reqGetNormalGroupList");
   int loginId = imLoginManager.getLoginId();
   IMGroup.IMNormalGroupListReq normalGroupListReq =
       IMGroup.IMNormalGroupListReq.newBuilder().setUserId(loginId).build();
   int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
   int cid = IMBaseDefine.GroupCmdID.CID_GROUP_NORMAL_LIST_REQUEST_VALUE;
   imSocketManager.sendRequest(normalGroupListReq, sid, cid);
   logger.i("group#send packet to server");
 }
  public void onRepUnreadMsgContactList(IMMessage.IMUnreadMsgCntRsp unreadMsgCntRsp) {
    logger.i("unread#2onRepUnreadMsgContactList");
    totalUnreadCount = unreadMsgCntRsp.getTotalCnt();
    List<IMBaseDefine.UnreadInfo> unreadInfoList = unreadMsgCntRsp.getUnreadinfoListList();
    logger.i(
        "unread#unreadMsgCnt:%d, unreadMsgInfoCnt:%d", unreadInfoList.size(), totalUnreadCount);

    for (IMBaseDefine.UnreadInfo unreadInfo : unreadInfoList) {
      UnreadEntity unreadEntity = ProtoBuf2JavaBean.getUnreadEntity(unreadInfo);
      // 屏蔽的设定
      addIsForbidden(unreadEntity);
      unreadMsgMap.put(unreadEntity.getSessionKey(), unreadEntity);
    }
    triggerEvent(new UnreadEvent(UnreadEvent.Event.UNREAD_MSG_LIST_OK));
  }
  /** 1. 加载本地信息 2. 从session中获取 群组信息,从本地中获取这些群组的version信息 3. 合并上述的merge结果, version groupId 请求 */
  private void loadSessionGroupInfo() {
    logger.i("group#loadSessionGroupInfo");

    List<SessionEntity> sessionInfoList = IMSessionManager.instance().getRecentSessionList();

    List<IMBaseDefine.GroupVersionInfo> needReqList = new ArrayList<>();
    for (SessionEntity sessionInfo : sessionInfoList) {
      int version = 0;
      if (sessionInfo.getPeerType() == DBConstant.SESSION_TYPE_GROUP
      /** 群组 */
      ) {
        if (groupMap.containsKey(sessionInfo.getPeerId())) {
          version = groupMap.get(sessionInfo.getPeerId()).getVersion();
        }

        IMBaseDefine.GroupVersionInfo versionInfo =
            IMBaseDefine.GroupVersionInfo.newBuilder()
                .setVersion(version)
                .setGroupId(sessionInfo.getPeerId())
                .build();
        needReqList.add(versionInfo);
      }
    }
    // 事件触发的时候需要注意
    if (needReqList.size() > 0) {
      reqGetGroupDetailInfo(needReqList);
      return;
    }
  }
  /**
   * 服务端主动发送已读通知
   *
   * @param readNotify
   */
  public void onNotifyRead(IMMessage.IMMsgDataReadNotify readNotify) {
    logger.d("chat#onNotifyRead");
    // 发送此信令的用户id
    int trigerId = readNotify.getUserId();
    int loginId = IMLoginManager.instance().getLoginId();
    if (trigerId != loginId) {
      logger.i("onNotifyRead# trigerId:%s,loginId:%s not Equal", trigerId, loginId);
      return;
    }
    // 现在的逻辑是msgId之后的 全部都是已读的
    // 不做复杂判断了,简单处理
    int msgId = readNotify.getMsgId();
    int peerId = readNotify.getSessionId();
    int sessionType = ProtoBuf2JavaBean.getJavaSessionType(readNotify.getSessionType());
    String sessionKey = EntityChangeEngine.getSessionKey(peerId, sessionType);

    // 通知栏也要去除掉
    NotificationManager notifyMgr =
        (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
    if (notifyMgr == null) {
      return;
    }
    int notificationId = IMNotificationManager.instance().getSessionNotificationId(sessionKey);
    notifyMgr.cancel(notificationId);

    UnreadEntity unreadSession = findUnread(sessionKey);
    if (unreadSession != null && unreadSession.getLaststMsgId() <= msgId) {
      // 清空会话session
      logger.d("chat#onNotifyRead# unreadSession onLoginOut");
      readUnreadSession(sessionKey);
    }
  }
 /** 请求未读消息列表 */
 private void reqUnreadMsgContactList() {
   logger.i("unread#1reqUnreadMsgContactList");
   int loginId = IMLoginManager.instance().getLoginId();
   IMMessage.IMUnreadMsgCntReq unreadMsgCntReq =
       IMMessage.IMUnreadMsgCntReq.newBuilder().setUserId(loginId).build();
   int sid = IMBaseDefine.ServiceID.SID_MSG_VALUE;
   int cid = IMBaseDefine.MessageCmdID.CID_MSG_UNREAD_CNT_REQUEST_VALUE;
   imSocketManager.sendRequest(unreadMsgCntReq, sid, cid);
 }
 public UnreadEntity findUnread(String sessionKey) {
   logger.d("unread#findUnread# buddyId:%s", sessionKey);
   if (TextUtils.isEmpty(sessionKey) || unreadMsgMap.size() <= 0) {
     logger.i("unread#findUnread# no unread info");
     return null;
   }
   if (unreadMsgMap.containsKey(sessionKey)) {
     return unreadMsgMap.get(sessionKey);
   }
   return null;
 }
  public void onRepGroupDetailInfo(IMGroup.IMGroupInfoListRsp groupInfoListRsp) {
    logger.i("group#onRepGroupDetailInfo");
    int groupSize = groupInfoListRsp.getGroupInfoListCount();
    int userId = groupInfoListRsp.getUserId();
    int loginId = imLoginManager.getLoginId();
    logger.i("group#onRepGroupDetailInfo cnt:%d", groupSize);
    if (groupSize <= 0 || userId != loginId) {
      logger.i("group#onRepGroupDetailInfo size empty or userid[%d]≠ loginId[%d]", userId, loginId);
      return;
    }
    ArrayList<GroupEntity> needDb = new ArrayList<>();
    for (IMBaseDefine.GroupInfo groupInfo : groupInfoListRsp.getGroupInfoListList()) {
      // 群组的详细信息
      // 保存在DB中
      // GroupManager 中的变量
      GroupEntity groupEntity = ProtoBuf2JavaBean.getGroupEntity(groupInfo);
      groupMap.put(groupEntity.getPeerId(), groupEntity);
      needDb.add(groupEntity);
    }

    dbInterface.batchInsertOrUpdateGroup(needDb);
    triggerEvent(new GroupEvent(GroupEvent.Event.GROUP_INFO_UPDATED));
  }
  /** 1. 加载本地信息 2. 请求正规群信息 , 与本地进行对比 3. version groupId 请求 */
  public void onLocalLoginOk() {
    logger.i("group#loadFromDb");

    if (!EventBus.getDefault().isRegistered(inst)) {
      EventBus.getDefault().registerSticky(inst);
    }

    // 加载本地group
    List<GroupEntity> localGroupInfoList = dbInterface.loadAllGroup();
    for (GroupEntity groupInfo : localGroupInfoList) {
      groupMap.put(groupInfo.getPeerId(), groupInfo);
    }

    triggerEvent(new GroupEvent(GroupEvent.Event.GROUP_INFO_OK));
  }
  /** 请求群组的详细信息 */
  public void reqGetGroupDetailInfo(List<IMBaseDefine.GroupVersionInfo> versionInfoList) {
    logger.i("group#reqGetGroupDetailInfo");
    if (versionInfoList == null || versionInfoList.size() <= 0) {
      logger.e("group#reqGetGroupDetailInfo# please check your params,cause by empty/null");
      return;
    }
    int loginId = imLoginManager.getLoginId();
    IMGroup.IMGroupInfoListReq groupInfoListReq =
        IMGroup.IMGroupInfoListReq.newBuilder()
            .setUserId(loginId)
            .addAllGroupVersionList(versionInfoList)
            .build();

    int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
    int cid = IMBaseDefine.GroupCmdID.CID_GROUP_INFO_REQUEST_VALUE;
    imSocketManager.sendRequest(groupInfoListReq, sid, cid);
  }
  /** 创建群 默认是创建临时群,且客户端只能创建临时群 */
  public void reqCreateTempGroup(String groupName, Set<Integer> memberList) {

    logger.i("group#reqCreateTempGroup, tempGroupName = %s", groupName);

    int loginId = imLoginManager.getLoginId();

    IMGroup.IMGroupCreateReq groupCreateReq =
        IMGroup.IMGroupCreateReq.newBuilder()
            .setUserId(loginId)
            .setGroupType(IMBaseDefine.GroupType.GROUP_TYPE_TMP)
            .setGroupName(groupName)
            .setGroupAvatar("") // todo 群头像 现在是四宫格
            .addAllMemberIdList(memberList)
            .build();

    int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
    int cid = IMBaseDefine.GroupCmdID.CID_GROUP_CREATE_REQUEST_VALUE;
    imSocketManager.sendRequest(
        groupCreateReq,
        sid,
        cid,
        new Packetlistener() {
          @Override
          public void onSuccess(Object response) {
            try {
              IMGroup.IMGroupCreateRsp groupCreateRsp =
                  IMGroup.IMGroupCreateRsp.parseFrom((CodedInputStream) response);
              IMGroupManager.instance().onReqCreateTempGroup(groupCreateRsp);
            } catch (IOException e) {
              logger.e("reqCreateTempGroup parse error");
              triggerEvent(new GroupEvent(GroupEvent.Event.CREATE_GROUP_FAIL));
            }
          }

          @Override
          public void onFaild() {
            triggerEvent(new GroupEvent(GroupEvent.Event.CREATE_GROUP_FAIL));
          }

          @Override
          public void onTimeout() {
            triggerEvent(new GroupEvent(GroupEvent.Event.CREATE_GROUP_TIMEOUT));
          }
        });
  }
  private void reqChangeGroupMember(
      int groupId, IMBaseDefine.GroupModifyType groupModifyType, Set<Integer> changeMemberlist) {
    logger.i("group#reqChangeGroupMember, changeGroupMemberType = %s", groupModifyType.toString());

    final int loginId = imLoginManager.getLoginId();
    IMGroup.IMGroupChangeMemberReq groupChangeMemberReq =
        IMGroup.IMGroupChangeMemberReq.newBuilder()
            .setUserId(loginId)
            .setChangeType(groupModifyType)
            .addAllMemberIdList(changeMemberlist)
            .setGroupId(groupId)
            .build();

    int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
    int cid = IMBaseDefine.GroupCmdID.CID_GROUP_CHANGE_MEMBER_REQUEST_VALUE;
    imSocketManager.sendRequest(
        groupChangeMemberReq,
        sid,
        cid,
        new Packetlistener() {
          @Override
          public void onSuccess(Object response) {
            try {
              IMGroup.IMGroupChangeMemberRsp groupChangeMemberRsp =
                  IMGroup.IMGroupChangeMemberRsp.parseFrom((CodedInputStream) response);
              IMGroupManager.instance().onReqChangeGroupMember(groupChangeMemberRsp);
            } catch (IOException e) {
              logger.e("reqChangeGroupMember parse error!");
              triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_MEMBER_FAIL));
            }
          }

          @Override
          public void onFaild() {
            triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_MEMBER_FAIL));
          }

          @Override
          public void onTimeout() {
            triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_MEMBER_TIMEOUT));
          }
        });
  }
  /** 屏蔽群消息 IMGroupShieldReq 备注:应为屏蔽之后大部分操作依旧需要客户端做 */
  public void reqShieldGroup(final int groupId, final int shieldType) {
    final GroupEntity entity = groupMap.get(groupId);
    if (entity == null) {
      logger.i("GroupEntity do not exist!");
      return;
    }
    final int loginId = IMLoginManager.instance().getLoginId();
    IMGroup.IMGroupShieldReq shieldReq =
        IMGroup.IMGroupShieldReq.newBuilder()
            .setShieldStatus(shieldType)
            .setGroupId(groupId)
            .setUserId(loginId)
            .build();
    int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
    int cid = IMBaseDefine.GroupCmdID.CID_GROUP_SHIELD_GROUP_REQUEST_VALUE;
    imSocketManager.sendRequest(
        shieldReq,
        sid,
        cid,
        new Packetlistener() {
          @Override
          public void onSuccess(Object response) {
            try {
              IMGroup.IMGroupShieldRsp groupShieldRsp =
                  IMGroup.IMGroupShieldRsp.parseFrom((CodedInputStream) response);
              int resCode = groupShieldRsp.getResultCode();
              if (resCode != 0) {
                triggerEvent(new GroupEvent(GroupEvent.Event.SHIELD_GROUP_FAIL));
                return;
              }
              if (groupShieldRsp.getGroupId() != groupId || groupShieldRsp.getUserId() != loginId) {
                return;
              }
              // 更新DB状态
              entity.setStatus(shieldType);
              dbInterface.insertOrUpdateGroup(entity);
              // 更改未读计数状态
              boolean isFor = shieldType == DBConstant.GROUP_STATUS_SHIELD;
              IMUnreadMsgManager.instance()
                  .setForbidden(
                      EntityChangeEngine.getSessionKey(groupId, DBConstant.SESSION_TYPE_GROUP),
                      isFor);
              triggerEvent(new GroupEvent(GroupEvent.Event.SHIELD_GROUP_OK, entity));

            } catch (IOException e) {
              logger.e("reqChangeGroupMember parse error!");
              triggerEvent(new GroupEvent(GroupEvent.Event.SHIELD_GROUP_FAIL));
            }
          }

          @Override
          public void onFaild() {
            triggerEvent(new GroupEvent(GroupEvent.Event.SHIELD_GROUP_FAIL));
          }

          @Override
          public void onTimeout() {
            triggerEvent(new GroupEvent(GroupEvent.Event.SHIELD_GROUP_TIMEOUT));
          }
        });
  }