public synchronized boolean onIncomingMessage(
        ChatSession ses, final org.awesomeapp.messenger.model.Message msg) {
      String body = msg.getBody();
      String username = msg.getFrom().getAddress();
      String bareUsername = msg.getFrom().getBareAddress();
      String nickname = getNickName(username);
      long time = msg.getDateTime().getTime();

      if (msg.getID() != null && Imps.messageExists(mContentResolver, msg.getID())) {
        return false; // this message is a duplicate
      }

      insertOrUpdateChat(body);

      boolean wasMessageSeen = false;

      if (msg.getID() == null) insertMessageInDb(nickname, body, time, msg.getType());
      else insertMessageInDb(nickname, body, time, msg.getType(), 0, msg.getID());

      int N = mRemoteListeners.beginBroadcast();
      for (int i = 0; i < N; i++) {
        IChatListener listener = mRemoteListeners.getBroadcastItem(i);
        try {
          boolean wasSeen = listener.onIncomingMessage(ChatSessionAdapter.this, msg);

          if (wasSeen) wasMessageSeen = wasSeen;

        } catch (RemoteException e) {
          // The RemoteCallbackList will take care of removing the
          // dead listeners.
        }
      }
      mRemoteListeners.finishBroadcast();

      // Due to the move to fragments, we could have listeners for ChatViews that are not visible on
      // the screen.
      // This is for fragments adjacent to the current one.  Therefore we can't use the existence of
      // listeners
      // as a filter on notifications.
      if (!wasMessageSeen) {
        // reinstated body display here in the notification; perhaps add preferences to turn that
        // off
        mStatusBarNotifier.notifyChat(
            mConnection.getProviderId(),
            mConnection.getAccountId(),
            getId(),
            bareUsername,
            nickname,
            body,
            false);
      }

      mHasUnreadMessages = true;
      return true;
    }
    @Override
    public void onIncomingReceipt(ChatSession ses, String id) {
      Imps.updateConfirmInDb(mContentResolver, mContactId, id, true);

      synchronized (mRemoteListeners) {
        int N = mRemoteListeners.beginBroadcast();
        for (int i = 0; i < N; i++) {
          IChatListener listener = mRemoteListeners.getBroadcastItem(i);
          try {
            listener.onIncomingReceipt(ChatSessionAdapter.this, id);
          } catch (RemoteException e) {
            // The RemoteCallbackList will take care of removing the
            // dead listeners.
          }
        }
        mRemoteListeners.finishBroadcast();
      }
    }
 Uri insertMessageInDb(String contact, String body, long time, int type, int errCode, String id) {
   boolean isEncrypted = true;
   try {
     isEncrypted = getDefaultOtrChatSession().isChatEncrypted();
   } catch (RemoteException e) {
     // Leave it as encrypted so it gets stored in memory
     // FIXME(miron)
   }
   return Imps.insertMessageInDb(
       mContentResolver,
       mIsGroupChat,
       mContactId,
       isEncrypted,
       contact,
       body,
       time,
       type,
       errCode,
       id,
       null);
 }
    @Override
    public void onTransferComplete(
        boolean outgoing,
        String offerId,
        String from,
        String url,
        String mimeType,
        String filePath) {

      try {

        if (outgoing) {
          Imps.updateConfirmInDb(service.getContentResolver(), mContactId, offerId, true);
        } else {

          try {
            boolean isVerified = getDefaultOtrChatSession().isKeyVerified(from);

            int type =
                isVerified
                    ? Imps.MessageType.INCOMING_ENCRYPTED_VERIFIED
                    : Imps.MessageType.INCOMING_ENCRYPTED;

            insertOrUpdateChat(filePath);

            Uri messageUri =
                Imps.insertMessageInDb(
                    service.getContentResolver(),
                    mIsGroupChat,
                    getId(),
                    true,
                    from,
                    filePath,
                    System.currentTimeMillis(),
                    type,
                    0,
                    offerId,
                    mimeType);

            int percent = (int) (100);

            String[] path = url.split("/");
            String sanitizedPath = SystemServices.sanitize(path[path.length - 1]);

            final int N = mRemoteListeners.beginBroadcast();
            for (int i = 0; i < N; i++) {
              IChatListener listener = mRemoteListeners.getBroadcastItem(i);
              try {
                listener.onIncomingFileTransferProgress(sanitizedPath, percent);
              } catch (RemoteException e) {
                // The RemoteCallbackList will take care of removing the
                // dead listeners.
              }
            }
            mRemoteListeners.finishBroadcast();

            if (N == 0) {
              String nickname = getNickName(from);

              mStatusBarNotifier.notifyChat(
                  mConnection.getProviderId(),
                  mConnection.getAccountId(),
                  getId(),
                  from,
                  nickname,
                  service.getString(R.string.file_notify_text, mimeType, nickname),
                  false);
            }
          } catch (Exception e) {
            Log.e(ImApp.LOG_TAG, "Error updating file transfer progress", e);
          }
        }

        /**
         * if (mimeType != null && mimeType.startsWith("audio")) { MediaPlayer mp = new
         * MediaPlayer(); try { mp.setDataSource(file.getCanonicalPath());
         *
         * <p>mp.prepare(); mp.start();
         *
         * <p>} catch (IOException e) { // TODO Auto-generated catch block //e.printStackTrace(); }
         * }
         */
      } catch (Exception e) {
        //   mHandler.showAlert(service.getString(R.string.error_chat_file_transfer_title),
        // service.getString(R.string.error_chat_file_transfer_body));
        OtrDebugLogger.log("error reading file", e);
      }
    }