/**
   * 服务端主动发送已读通知
   *
   * @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);
    }
  }
 /**
  * 回话是否已经被设定为屏蔽
  *
  * @param unreadEntity
  */
 private void addIsForbidden(UnreadEntity unreadEntity) {
   if (unreadEntity.getSessionType() == DBConstant.SESSION_TYPE_GROUP) {
     GroupEntity groupEntity = IMGroupManager.instance().findGroup(unreadEntity.getPeerId());
     if (groupEntity != null && groupEntity.getStatus() == DBConstant.GROUP_STATUS_SHIELD) {
       unreadEntity.setForbidden(true);
     }
   }
 }
 public int getTotalUnreadCount() {
   int count = 0;
   for (UnreadEntity entity : unreadMsgMap.values()) {
     if (!entity.isForbidden()) {
       count = count + entity.getUnReadCnt();
     }
   }
   return count;
 }
  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));
  }
 public void ackReadMsg(UnreadEntity unreadEntity) {
   logger.d("chat#ackReadMsg -> msg:%s", unreadEntity);
   int loginId = loginManager.getLoginId();
   IMBaseDefine.SessionType sessionType =
       Java2ProtoBuf.getProtoSessionType(unreadEntity.getSessionType());
   IMMessage.IMMsgDataReadAck readAck =
       IMMessage.IMMsgDataReadAck.newBuilder()
           .setMsgId(unreadEntity.getLaststMsgId())
           .setSessionId(unreadEntity.getPeerId())
           .setSessionType(sessionType)
           .setUserId(loginId)
           .build();
   int sid = IMBaseDefine.ServiceID.SID_MSG_VALUE;
   int cid = IMBaseDefine.MessageCmdID.CID_MSG_READ_ACK_VALUE;
   imSocketManager.sendRequest(readAck, sid, cid);
 }
  private void handleMsgRecv(UnreadEntity entity) {
    logger.d("notification#recv unhandled message");
    int peerId = entity.getPeerId();
    int sessionType = entity.getSessionType();
    logger.d("notification#msg no one handled, peerId:%d, sessionType:%d", peerId, sessionType);

    // 判断是否设定了免打扰
    if (entity.isForbidden()) {
      logger.d("notification#GROUP_STATUS_SHIELD");
      return;
    }

    // PC端是否登陆 取消 【暂时先关闭】
    //        if(IMLoginManager.instance().isPcOnline()){
    //            logger.d("notification#isPcOnline");
    //            return;
    //        }

    // 全局开关
    boolean globallyOnOff =
        configurationSp.getCfg(
            SysConstant.SETTING_GLOBAL, ConfigurationSp.CfgDimension.NOTIFICATION);
    if (globallyOnOff) {
      logger.d("notification#shouldGloballyShowNotification is false, return");
      return;
    }

    // 单独的设置
    boolean singleOnOff =
        configurationSp.getCfg(entity.getSessionKey(), ConfigurationSp.CfgDimension.NOTIFICATION);
    if (singleOnOff) {
      logger.d("notification#shouldShowNotificationBySession is false, return");
      return;
    }

    // if the message is a multi login message which send from another terminal,not need notificate
    // to status bar
    // 判断是否是自己的消息
    if (IMLoginManager.instance().getLoginId() != peerId) {
      showNotification(entity);
    }
  }
  private void showNotification(final UnreadEntity unreadEntity) {
    // todo eric need to set the exact size of the big icon
    // 服务端有些特定的支持 尺寸是不是要调整一下 todo 100*100  下面的就可以不要了
    ImageSize targetSize = new ImageSize(80, 80);
    int peerId = unreadEntity.getPeerId();
    int sessionType = unreadEntity.getSessionType();
    String avatarUrl = "";
    String title = "";
    String content = unreadEntity.getLatestMsgData();
    String unit = ctx.getString(R.string.msg_cnt_unit);
    int totalUnread = unreadEntity.getUnReadCnt();

    if (unreadEntity.getSessionType() == DBConstant.SESSION_TYPE_SINGLE) {
      UserEntity contact = IMContactManager.instance().findContact(peerId);
      if (contact != null) {
        title = contact.getMainName();
        avatarUrl = contact.getAvatar();
      } else {
        title = "User_" + peerId;
        avatarUrl = "";
      }

    } else {
      GroupEntity group = IMGroupManager.instance().findGroup(peerId);
      if (group != null) {
        title = group.getMainName();
        avatarUrl = group.getAvatar();
      } else {
        title = "Group_" + peerId;
        avatarUrl = "";
      }
    }
    // 获取头像
    avatarUrl = IMUIHelper.getRealAvatarUrl(avatarUrl);
    final String ticker = String.format("[%d%s]%s: %s", totalUnread, unit, title, content);
    final int notificationId = getSessionNotificationId(unreadEntity.getSessionKey());
    final Intent intent = new Intent(ctx, MessageActivity.class);
    intent.putExtra(IntentConstant.KEY_SESSION_KEY, unreadEntity.getSessionKey());

    logger.d("notification#notification avatarUrl:%s", avatarUrl);
    final String finalTitle = title;
    ImageLoader.getInstance()
        .loadImage(
            avatarUrl,
            targetSize,
            null,
            new SimpleImageLoadingListener() {

              @Override
              public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                logger.d("notification#icon onLoadComplete");
                // holder.image.setImageBitmap(loadedImage);
                showInNotificationBar(finalTitle, ticker, loadedImage, notificationId, intent);
              }

              @Override
              public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                logger.d("notification#icon onLoadFailed");
                // 服务器支持的格式有哪些
                // todo eric default avatar is too small, need big size(128 * 128)
                Bitmap defaultBitmap =
                    BitmapFactory.decodeResource(
                        ctx.getResources(),
                        IMUIHelper.getDefaultAvatarResId(unreadEntity.getSessionType()));
                showInNotificationBar(finalTitle, ticker, defaultBitmap, notificationId, intent);
              }
            });
  }
  public void add(MessageEntity msg) {
    // 更新session list中的msg信息
    // 更新未读消息计数
    if (msg == null) {
      logger.d("unread#unreadMgr#add msg is null!");
      return;
    }
    // isFirst场景:出现一条未读消息,出现小红点,需要触发 [免打扰的情况下]
    boolean isFirst = false;
    logger.d("unread#unreadMgr#add unread msg:%s", msg);
    UnreadEntity unreadEntity;
    int loginId = IMLoginManager.instance().getLoginId();
    String sessionKey = msg.getSessionKey();
    boolean isSend = msg.isSend(loginId);
    if (isSend) {
      IMNotificationManager.instance().cancelSessionNotifications(sessionKey);
      return;
    }

    if (unreadMsgMap.containsKey(sessionKey)) {
      unreadEntity = unreadMsgMap.get(sessionKey);
      // 判断最后一条msgId是否相同
      if (unreadEntity.getLaststMsgId() == msg.getMsgId()) {
        return;
      }
      unreadEntity.setUnReadCnt(unreadEntity.getUnReadCnt() + 1);
    } else {
      isFirst = true;
      unreadEntity = new UnreadEntity();
      unreadEntity.setUnReadCnt(1);
      unreadEntity.setPeerId(msg.getPeerId(isSend));
      unreadEntity.setSessionType(msg.getSessionType());
      unreadEntity.buildSessionKey();
    }

    unreadEntity.setLatestMsgData(msg.getMessageDisplay());
    unreadEntity.setLaststMsgId(msg.getMsgId());
    addIsForbidden(unreadEntity);

    /** 放入manager 状态中 */
    unreadMsgMap.put(unreadEntity.getSessionKey(), unreadEntity);

    /** 没有被屏蔽才会发送广播 */
    if (!unreadEntity.isForbidden() || isFirst) {
      UnreadEvent unreadEvent = new UnreadEvent();
      unreadEvent.event = UnreadEvent.Event.UNREAD_MSG_RECEIVED;
      unreadEvent.entity = unreadEntity;
      triggerEvent(unreadEvent);
    }
  }
 /** 设定未读回话为屏蔽回话 仅限于群组 todo */
 public void setForbidden(String sessionKey, boolean isFor) {
   UnreadEntity unreadEntity = unreadMsgMap.get(sessionKey);
   if (unreadEntity != null) {
     unreadEntity.setForbidden(isFor);
   }
 }