/**
   * Initiate a pre-recorded video sharing session
   *
   * @param contact Remote contact
   * @param content Video content to share
   * @param player Media player
   * @return CSh session
   * @throws CoreException
   */
  public VideoStreamingSession initiatePreRecordedVideoSharingSession(
      String contact, VideoContent content, IMediaPlayer player) throws CoreException {
    if (logger.isActivated()) {
      logger.info(
          "Initiate a pre-recorded video sharing session with contact "
              + contact
              + ", file "
              + content.toString());
    }

    // Test if call is established
    if (!getImsModule().getCallManager().isCallConnected()) {
      if (logger.isActivated()) {
        logger.debug("Rich call not established: cancel the initiation");
      }
      throw new CoreException("Call not established");
    }

    // Reject if there are already 2 bidirectional sessions with a given contact
    boolean rejectInvitation = false;
    Vector<ContentSharingSession> currentSessions = getCShSessions();
    if (currentSessions.size() >= 2) {
      // Already a bidirectional session
      if (logger.isActivated()) {
        logger.debug("Max sessions reached");
      }
      rejectInvitation = true;
    } else if (currentSessions.size() == 1) {
      ContentSharingSession currentSession = currentSessions.elementAt(0);
      if (!(currentSession instanceof TerminatingVideoStreamingSession)) {
        // Originating session already used
        if (logger.isActivated()) {
          logger.debug("Max originating sessions reached");
        }
        rejectInvitation = true;
      } else if (!PhoneUtils.compareNumbers(contact, currentSession.getRemoteContact())) {
        // Not the same contact
        if (logger.isActivated()) {
          logger.debug("Only bidirectional session with same contact authorized");
        }
        rejectInvitation = true;
      }
    }
    if (rejectInvitation) {
      if (logger.isActivated()) {
        logger.debug("The max number of sharing sessions is achieved: cancel the initiation");
      }
      throw new CoreException("Max content sharing sessions achieved");
    }

    // Create a new session
    OriginatingPreRecordedVideoStreamingSession session =
        new OriginatingPreRecordedVideoStreamingSession(
            this, player, content, PhoneUtils.formatNumberToSipUri(contact));

    // Start the session
    session.startSession();
    return session;
  }
  /**
   * Receive a new geoloc sharing invitation
   *
   * @param session Geoloc sharing session
   */
  public void receiveGeolocSharingInvitation(GeolocTransferSession session) {
    if (logger.isActivated()) {
      logger.info("Receive geoloc sharing invitation from " + session.getRemoteContact());
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(session.getRemoteContact());

    // Update rich call history
    RichCall.getInstance()
        .addCall(
            number,
            session.getSessionID(),
            RichCallData.EVENT_INCOMING,
            session.getContent(),
            RichCallData.STATUS_STARTED);

    // Add session in the list
    GeolocSharingSession sessionApi = new GeolocSharingSession(session);
    addGeolocSharingSession(sessionApi);

    // Broadcast intent related to the received invitation
    Intent intent = new Intent(RichCallApiIntents.GEOLOC_SHARING_INVITATION);
    intent.putExtra("contact", number);
    intent.putExtra("contactDisplayname", session.getRemoteDisplayName());
    intent.putExtra("sessionId", session.getSessionID());
    AndroidFactory.getApplicationContext().sendBroadcast(intent);
  }
Exemple #3
0
  /**
   * Receive a new geoloc sharing invitation
   *
   * @param session Geoloc sharing session
   */
  public void receiveGeolocSharingInvitation(GeolocTransferSession session) {
    if (logger.isActivated()) {
      logger.info("Receive geoloc sharing invitation from " + session.getRemoteContact());
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(session.getRemoteContact());

    // Add session in the list
    GeolocSharingImpl sessionApi = new GeolocSharingImpl(session);
    GeolocSharingServiceImpl.addGeolocSharingSession(sessionApi);

    // Broadcast intent related to the received invitation
    Intent intent = new Intent(GeolocSharingIntent.ACTION_NEW_INVITATION);
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    intent.putExtra(GeolocSharingIntent.EXTRA_CONTACT, number);
    intent.putExtra(GeolocSharingIntent.EXTRA_DISPLAY_NAME, session.getRemoteDisplayName());
    intent.putExtra(GeolocSharingIntent.EXTRA_SHARING_ID, session.getSessionID());
    AndroidFactory.getApplicationContext().sendBroadcast(intent);

    // Notify geoloc sharing invitation listeners
    synchronized (lock) {
      final int N = listeners.beginBroadcast();
      for (int i = 0; i < N; i++) {
        try {
          listeners.getBroadcastItem(i).onNewGeolocSharing(session.getSessionID());
        } catch (Exception e) {
          if (logger.isActivated()) {
            logger.error("Can't notify listener", e);
          }
        }
      }
      listeners.finishBroadcast();
    }
  }
  /**
   * Receive a new video sharing invitation
   *
   * @param session Video sharing session
   */
  public void receiveVideoSharingInvitation(VideoStreamingSession session) {
    if (logger.isActivated()) {
      logger.info("Receive video sharing invitation from " + session.getRemoteContact());
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(session.getRemoteContact());
    VideoContent content = (VideoContent) session.getContent();

    // Update rich call history
    RichCall.getInstance()
        .addCall(
            number,
            session.getSessionID(),
            RichCallData.EVENT_INCOMING,
            content,
            RichCallData.STATUS_STARTED);

    // Add session in the list
    VideoSharingSession sessionApi = new VideoSharingSession(session);
    addVideoSharingSession(sessionApi);

    // Broadcast intent related to the received invitation
    Intent intent = new Intent(RichCallApiIntents.VIDEO_SHARING_INVITATION);
    intent.putExtra("contact", number);
    intent.putExtra("contactDisplayname", session.getRemoteDisplayName());
    intent.putExtra("sessionId", session.getSessionID());
    intent.putExtra("videotype", content.getEncoding());
    intent.putExtra("videowidth", content.getWidth());
    intent.putExtra("videoheight", content.getHeight());
    AndroidFactory.getApplicationContext().sendBroadcast(intent);
  }
Exemple #5
0
  /**
   * Constructor
   *
   * @param parent IMS service
   * @param invite Initial INVITE request
   */
  public TerminatingOne2OneChatSession(ImsService parent, SipRequest invite) {
    super(parent, PhoneUtils.extractNumberFromUri(SipUtils.getAssertedIdentity(invite)));

    // Set first message
    InstantMessage firstMsg = ChatUtils.getFirstMessage(invite);
    setFirstMesssage(firstMsg);

    // Create dialog path
    createTerminatingDialogPath(invite);

    // Set contribution ID
    String id = ChatUtils.getContributionId(invite);
    setContributionID(id);
    if (RcsSettings.getInstance().isCPMSupported()) {
      if (logger.isActivated()) {
        logger.info("TerminatingFOne2OneSession1  CPMS");
      }
      setConversationID(ChatUtils.getCoversationId(invite));
      setInReplyID(ChatUtils.getInReplyId(invite));
    }

    if (logger.isActivated()) {
      logger.info("TerminatingOne2OneChatSession From: " + ChatUtils.getFromAias(invite));
      logger.info("TerminatingOne2OneChatSession Display name: " + this.getRemoteDisplayName());
    }
    setRemoteDisplayName(this.getRemoteDisplayName());
  }
  /**
   * Receive an image sharing invitation
   *
   * @param invite Initial invite
   */
  public void receiveImageSharingInvitation(SipRequest invite) {
    if (logger.isActivated()) {
      logger.info("Receive an image sharing session invitation");
    }

    // Test if call is established
    if (!getImsModule().getCallManager().isCallConnected()) {
      if (logger.isActivated()) {
        logger.debug("Rich call not established: reject the invitation");
      }
      sendErrorResponse(invite, 606);
      return;
    }

    // Reject if there are already 2 bidirectional sessions with a given contact
    boolean rejectInvitation = false;
    String contact = SipUtils.getAssertedIdentity(invite);
    Vector<ContentSharingSession> currentSessions = getCShSessions();
    if (currentSessions.size() >= 2) {
      // Already a bidirectional session
      if (logger.isActivated()) {
        logger.debug("Max sessions reached");
      }
      rejectInvitation = true;
    } else if (currentSessions.size() == 1) {
      ContentSharingSession currentSession = currentSessions.elementAt(0);
      if (currentSession instanceof TerminatingImageTransferSession) {
        // Terminating session already used
        if (logger.isActivated()) {
          logger.debug("Max terminating sessions reached");
        }
        rejectInvitation = true;
      } else if (!PhoneUtils.compareNumbers(contact, currentSession.getRemoteContact())) {
        // Not the same contact
        if (logger.isActivated()) {
          logger.debug("Only bidirectional session with same contact authorized");
        }
        rejectInvitation = true;
      }
    }
    if (rejectInvitation) {
      if (logger.isActivated()) {
        logger.debug("The max number of sharing sessions is achieved: reject the invitation");
      }
      sendErrorResponse(invite, 486);
      return;
    }

    // Create a new session
    ImageTransferSession session = new TerminatingImageTransferSession(this, invite);

    // Start the session
    session.startSession();

    // Notify listener
    getImsModule().getCore().getListener().handleContentSharingTransferInvitation(session);
  }
 /**
  * Returns display name of the remote contact
  *
  * @return String
  */
 public String getRemoteDisplayName() {
   String displayName = null;
   try {
     String from = getDialogPath().getInvite().getFrom();
     displayName = PhoneUtils.extractDisplayNameFromUri(from);
   } catch (Exception e) {
     displayName = null;
   }
   return displayName;
 }
  /**
   * Receive an instant message (SIP MESSAGE)
   *
   * @param intent Resolved intent
   * @param message Instant message request
   */
  public void receiveSipInstantMessage(Intent intent, SipRequest message) {
    // Broadcast intent related to the received invitation
    String contact = SipUtils.getAssertedIdentity(message);
    String number = PhoneUtils.extractNumberFromUri(contact);
    String displayName = SipUtils.getDisplayNameFromUri(message.getFrom());
    intent.putExtra(MultimediaMessageIntent.EXTRA_CONTACT, number);
    intent.putExtra(MultimediaMessageIntent.EXTRA_DISPLAY_NAME, displayName);
    intent.putExtra(MultimediaMessageIntent.EXTRA_CONTENT, message.getRawContent());

    // Broadcast intent related to the received invitation
    AndroidFactory.getApplicationContext().sendBroadcast(intent);
  }
  /**
   * A new presence sharing invitation has been received
   *
   * @param contact Contact
   */
  public void handlePresenceSharingInvitation(String contact) {
    if (logger.isActivated()) {
      logger.debug("Handle event presence sharing invitation");
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(contact);

    // Broadcast intent related to the received invitation
    Intent intent = new Intent(PresenceApiIntents.PRESENCE_INVITATION);
    intent.putExtra("contact", number);
    getApplicationContext().sendBroadcast(intent);
  }
 @Override
 public void exitFromChatMode(String number) {
   Logger.d(TAG, "exitFromChatMode() entry, number " + number);
   if (PluginUtils.getMessagingMode() == 0) {
     if (number.startsWith(IpMessageConsts.JOYN_START)) {
       number = number.substring(4);
     }
   }
   Message controllerMessage =
       PluginController.obtainMessage(
           ChatController.EVENT_HIDE_WINDOW, PhoneUtils.formatNumberToInternational(number));
   controllerMessage.sendToTarget();
   super.exitFromChatMode(number);
 }
  /**
   * Receive a new SIP session invitation
   *
   * @param intent Resolved intent
   * @param session SIP session
   */
  public void receiveSipSessionInvitation(Intent intent, GenericSipSession session) {
    // Add session in the list
    MultimediaSessionImpl sessionApi = new MultimediaSessionImpl(session);
    MultimediaSessionServiceImpl.addSipSession(sessionApi);

    // Broadcast intent related to the received invitation
    String number = PhoneUtils.extractNumberFromUri(session.getRemoteContact());
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    intent.putExtra(MultimediaSessionIntent.EXTRA_CONTACT, number);
    intent.putExtra(MultimediaSessionIntent.EXTRA_DISPLAY_NAME, session.getRemoteDisplayName());
    intent.putExtra(MultimediaSessionIntent.EXTRA_SESSION_ID, session.getSessionID());

    // Broadcast intent related to the received invitation
    AndroidFactory.getApplicationContext().sendBroadcast(intent);
  }
  /**
   * Receive a new video sharing invitation
   *
   * @param session Video sharing session
   */
  public void receiveVideoSharingInvitation(VideoStreamingSession session) {
    if (logger.isActivated()) {
      logger.info("Receive video sharing invitation from " + session.getRemoteContact());
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(session.getRemoteContact());

    // Update rich call history
    VideoContent content = (VideoContent) session.getContent();
    RichCallHistory.getInstance()
        .addVideoSharing(
            number,
            session.getSessionID(),
            VideoSharing.Direction.INCOMING,
            content,
            VideoSharing.State.INVITED);

    // Add session in the list
    VideoSharingImpl sessionApi = new VideoSharingImpl(session);
    VideoSharingServiceImpl.addVideoSharingSession(sessionApi);

    // Broadcast intent related to the received invitation
    Intent intent = new Intent(VideoSharingIntent.ACTION_NEW_INVITATION);
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    intent.putExtra(VideoSharingIntent.EXTRA_CONTACT, number);
    intent.putExtra(VideoSharingIntent.EXTRA_DISPLAY_NAME, session.getRemoteDisplayName());
    intent.putExtra(VideoSharingIntent.EXTRA_SHARING_ID, session.getSessionID());
    intent.putExtra(VideoSharingIntent.EXTRA_ENCODING, content.getEncoding());
    intent.putExtra(VideoSharingIntent.EXTRA_WIDTH, session.getVideoWidth());
    intent.putExtra(VideoSharingIntent.EXTRA_HEIGHT, session.getVideoHeight());
    AndroidFactory.getApplicationContext().sendBroadcast(intent);

    // Notify video sharing invitation listeners
    synchronized (lock) {
      final int N = listeners.beginBroadcast();
      for (int i = 0; i < N; i++) {
        try {
          listeners.getBroadcastItem(i).onNewVideoSharing(session.getSessionID());
        } catch (Exception e) {
          if (logger.isActivated()) {
            logger.error("Can't notify listener", e);
          }
        }
      }
      listeners.finishBroadcast();
    }
  }
  /**
   * Capabilities update notification has been received
   *
   * @param contact Contact
   * @param capabilities Capabilities
   */
  public void handleCapabilitiesNotification(String contact, Capabilities capabilities) {
    if (logger.isActivated()) {
      logger.debug(
          "Handle capabilities update notification for "
              + contact
              + " ("
              + capabilities.toString()
              + ")");
    }

    // Extract number from contact
    String number = PhoneUtils.extractNumberFromUri(contact);

    // Broadcast intent containing the new capabilities
    Intent intent = new Intent(CapabilityApiIntents.CONTACT_CAPABILITIES);
    intent.putExtra("contact", number);
    intent.putExtra("capabilities", capabilities);
    getApplicationContext().sendBroadcast(intent);
    // TODO keep only one intent here

    // Send GSMA UI Connector intent
    Intent intentGsma = new Intent(GsmaUiConnector.ACTION_CAPABILITIES_CHANGED);
    intentGsma.putExtra(GsmaUiConnector.EXTRA_CONTACT, number);
    intentGsma.putExtra(GsmaUiConnector.EXTRA_CAPABILITY_CHAT, capabilities.isImSessionSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_FT, capabilities.isFileTransferSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_IMAGE_SHARE, capabilities.isImageSharingSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_VIDEO_SHARE, capabilities.isVideoSharingSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_GEOLOCATION_PUSH,
        capabilities.isGeolocationPushSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_CS_VIDEO, capabilities.isCsVideoSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_PRESENCE_DISCOVERY,
        capabilities.isPresenceDiscoverySupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_SOCIAL_PRESENCE, capabilities.isSocialPresenceSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_IPVOICECALL, capabilities.isIPVoiceCallSupported());
    intentGsma.putExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_IPVIDEOCALL, capabilities.isIPVideoCallSupported());
    intentGsma.putStringArrayListExtra(
        GsmaUiConnector.EXTRA_CAPABILITY_EXTENSIONS, capabilities.getSupportedExtensions());
    getApplicationContext().sendBroadcast(intentGsma);
  }
  @Override
  public Cursor query(
      Uri uri, String[] projectionIn, String selection, String[] selectionArgs, String sort) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    // Generate the body of the query
    int match = uriMatcher.match(uri);
    switch (match) {
      case CHATS:
      case RCSAPI_CHATS:
        qb.setTables(TABLE_CHAT);
        break;
      case MESSAGES:
      case RCSAPI_MESSAGES:
        qb.setTables(TABLE_MESSAGE);
        break;
      case CHAT_ID:
      case RCSAPI_CHAT_ID:
        qb.setTables(TABLE_CHAT);
        qb.appendWhere(ChatData.KEY_CHAT_ID + "=");
        qb.appendWhere(uri.getPathSegments().get(1));
        break;
      case MESSAGE_ID:
      case RCSAPI_MESSAGE_ID:
        qb.setTables(TABLE_MESSAGE);
        qb.appendWhere(
            MessageData.KEY_CHAT_ID
                + "= '"
                + PhoneUtils.formatNumberToInternational(uri.getPathSegments().get(1))
                + "'");
        break;
      default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    SQLiteDatabase db = openHelper.getReadableDatabase();
    Cursor c = qb.query(db, projectionIn, selection, selectionArgs, null, null, sort);

    // Register the contexts ContentResolver to be notified if the cursor result set changes
    if (c != null) {
      c.setNotificationUri(getContext().getContentResolver(), uri);
    }

    return c;
  }
 @Override
 public int delete(Uri uri, String where, String[] whereArgs) {
   SQLiteDatabase db = openHelper.getWritableDatabase();
   int count = 0;
   switch (uriMatcher.match(uri)) {
     case CHATS:
     case RCSAPI_CHATS:
       count = db.delete(TABLE_CHAT, where, whereArgs);
       break;
     case CHAT_ID:
     case RCSAPI_CHAT_ID:
       count =
           db.delete(
               TABLE_CHAT,
               ChatData.KEY_ID
                   + "="
                   + uri.getPathSegments().get(1)
                   + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
               whereArgs);
       break;
     case MESSAGES:
     case RCSAPI_MESSAGES:
       count = db.delete(TABLE_MESSAGE, where, whereArgs);
       break;
     case MESSAGE_ID:
     case RCSAPI_MESSAGE_ID:
       count =
           db.delete(
               TABLE_MESSAGE,
               MessageData.KEY_ID
                   + "="
                   + PhoneUtils.formatNumberToInternational(uri.getPathSegments().get(1))
                   + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
               whereArgs);
       break;
     default:
       throw new SQLException("Failed to delete row " + uri);
   }
   getContext().getContentResolver().notifyChange(uri, null);
   return count;
 }
 @Override
 public void sendChatMode(String number, int status) {
   Logger.d(TAG, "sendChatMode() the number is " + number + " status is " + status);
   boolean isEmpty = true;
   if (PluginUtils.getMessagingMode() == 0) {
     if (number.startsWith(IpMessageConsts.JOYN_START)) {
       number = number.substring(4);
     }
   }
   if (status == ContactStatus.STOP_TYPING) {
     isEmpty = true;
   } else if (status == ContactStatus.TYPING) {
     isEmpty = false;
   }
   Message controllerMessage =
       PluginController.obtainMessage(
           ChatController.EVENT_TEXT_CHANGED,
           PhoneUtils.formatNumberToInternational(number),
           isEmpty);
   controllerMessage.sendToTarget();
 }
  /**
   * A new presence info notification has been received
   *
   * @param contact Contact
   * @param presense Presence info document
   */
  public void handlePresenceInfoNotification(String contact, PidfDocument presence) {
    if (logger.isActivated()) {
      logger.debug("Handle event presence info notification for " + contact);
    }

    try {
      // Test if person item is not null
      Person person = presence.getPerson();
      if (person == null) {
        if (logger.isActivated()) {
          logger.debug("Presence info is empty (i.e. no item person found) for contact " + contact);
        }
        return;
      }

      // Check if its a notification for a contact or for me
      String me = ImsModule.IMS_USER_PROFILE.getPublicUri();
      if (PhoneUtils.compareNumbers(me, contact)) {
        // Notification for me
        presenceInfoNotificationForMe(presence);
      } else {
        // Check that the contact exist in database
        int rcsStatus = ContactsManager.getInstance().getContactSharingStatus(contact);
        if (rcsStatus == -1) {
          if (logger.isActivated()) {
            logger.debug("Contact " + contact + " is not a RCS contact, by-pass the notification");
          }
          return;
        }

        // Notification for a contact
        presenceInfoNotificationForContact(contact, presence);
      }
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("Internal exception", e);
      }
    }
  }
 @Override
 public void enterChatMode(String number) {
   Logger.d(TAG, "enterChatMode() entry, number " + number);
   if (PluginUtils.getMessagingMode() == 0) {
     if (number.startsWith(IpMessageConsts.JOYN_START)) {
       number = number.substring(4);
     }
   }
   Message controllerMessage =
       PluginController.obtainMessage(
           ChatController.EVENT_SHOW_WINDOW, PhoneUtils.formatNumberToInternational(number));
   controllerMessage.sendToTarget();
   if ((PluginUtils.getMessagingMode() == 1) && (PluginUtils.translateThreadId(number) == 1)) {
     Logger.v(TAG, "enterChatMode(), open Window = " + number);
     Intent intent = new Intent(InvitationDialog.ACTION);
     intent.putExtra(RcsNotification.CONTACT, number);
     intent.putExtra(InvitationDialog.KEY_STRATEGY, InvitationDialog.STRATEGY_IPMES_SEND_BY_SMS);
     intent.putExtra("showDialog", true);
     intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
     AndroidFactory.getApplicationContext().startActivity(intent);
   }
   super.enterChatMode(number);
 }
  /**
   * A new presence sharing notification has been received
   *
   * @param contact Contact
   * @param status Status
   * @param reason Reason
   */
  public void handlePresenceSharingNotification(String contact, String status, String reason) {
    if (logger.isActivated()) {
      logger.debug(
          "Handle event presence sharing notification for "
              + contact
              + " ("
              + status
              + ":"
              + reason
              + ")");
    }

    try {
      // Check if its a notification for a contact or for the end user
      String me = ImsModule.IMS_USER_PROFILE.getPublicUri();
      if (PhoneUtils.compareNumbers(me, contact)) {
        // End user notification
        if (logger.isActivated()) {
          logger.debug("Presence sharing notification for me: by-pass it");
        }
      } else {
        // Update contacts database
        ContactsManager.getInstance().setContactSharingStatus(contact, status, reason);

        // Broadcast intent
        Intent intent = new Intent(PresenceApiIntents.PRESENCE_SHARING_CHANGED);
        intent.putExtra("contact", contact);
        intent.putExtra("status", status);
        intent.putExtra("reason", reason);
        AndroidFactory.getApplicationContext().sendBroadcast(intent);
      }
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("Internal exception", e);
      }
    }
  }
 /**
  * Get vodafone account mapped with the specific number.
  *
  * @param number The number to be mapped to vodafone account.
  * @return The vodafone account.
  * @throws ServerApiException
  */
 public String getNumberViaVfAccount(String number) throws ServerApiException {
   ServerApiUtils.testPermission();
   ServerApiUtils.testCore();
   return PhoneUtils.getNumberViaVfAccount(number);
 }
  /**
   * Add a participant to the session
   *
   * @param participant Participant
   */
  public void addParticipant(String participant) {
    try {
      if (logger.isActivated()) {
        logger.debug("Add one participant (" + participant + ") to the session");
      }

      // Re-use INVITE dialog path
      SessionAuthenticationAgent authenticationAgent = getAuthenticationAgent();

      // Increment the Cseq number of the dialog path
      getDialogPath().incrementCseq();

      // Send REFER request
      if (logger.isActivated()) {
        logger.debug("Send REFER");
      }
      String contactUri = PhoneUtils.formatNumberToSipUri(participant);
      SipRequest refer = SipMessageFactory.createRefer(getDialogPath(), contactUri);
      SipTransactionContext ctx =
          getImsService()
              .getImsModule()
              .getSipManager()
              .sendSubsequentRequest(getDialogPath(), refer);

      // Wait response
      if (logger.isActivated()) {
        logger.debug("Wait response");
      }
      ctx.waitResponse(SipManager.TIMEOUT);

      // Analyze received message
      if (ctx.getStatusCode() == 407) {
        // 407 response received
        if (logger.isActivated()) {
          logger.debug("407 response received");
        }

        // Set the Proxy-Authorization header
        authenticationAgent.readProxyAuthenticateHeader(ctx.getSipResponse());

        // Increment the Cseq number of the dialog path
        getDialogPath().incrementCseq();

        // Create a second REFER request with the right token
        if (logger.isActivated()) {
          logger.info("Send second REFER");
        }
        refer = SipMessageFactory.createRefer(getDialogPath(), contactUri);

        // Set the Authorization header
        authenticationAgent.setProxyAuthorizationHeader(refer);

        // Send REFER request
        ctx =
            getImsService()
                .getImsModule()
                .getSipManager()
                .sendSubsequentRequest(getDialogPath(), refer);

        // Wait response
        if (logger.isActivated()) {
          logger.debug("Wait response");
        }
        ctx.waitResponse(SipManager.TIMEOUT);

        // Analyze received message
        if ((ctx.getStatusCode() >= 200) && (ctx.getStatusCode() < 300)) {
          // 200 OK response
          if (logger.isActivated()) {
            logger.debug("200 OK response received");
          }

          // Notify listeners
          for (int i = 0; i < getListeners().size(); i++) {
            ((ChatSessionListener) getListeners().get(i)).handleAddParticipantSuccessful();
          }
        } else {
          // Error
          if (logger.isActivated()) {
            logger.debug("REFER has failed (" + ctx.getStatusCode() + ")");
          }

          // Notify listeners
          for (int i = 0; i < getListeners().size(); i++) {
            ((ChatSessionListener) getListeners().get(i))
                .handleAddParticipantFailed(ctx.getReasonPhrase());
          }
        }
      } else if ((ctx.getStatusCode() >= 200) && (ctx.getStatusCode() < 300)) {
        // 200 OK received
        if (logger.isActivated()) {
          logger.debug("200 OK response received");
        }

        // Notify listeners
        for (int i = 0; i < getListeners().size(); i++) {
          ((ChatSessionListener) getListeners().get(i)).handleAddParticipantSuccessful();
        }
      } else {
        // Error responses
        if (logger.isActivated()) {
          logger.debug("No response received");
        }

        // Notify listeners
        for (int i = 0; i < getListeners().size(); i++) {
          ((ChatSessionListener) getListeners().get(i))
              .handleAddParticipantFailed(ctx.getReasonPhrase());
        }
      }
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("REFER request has failed", e);
      }

      // Notify listeners
      for (int i = 0; i < getListeners().size(); i++) {
        ((ChatSessionListener) getListeners().get(i)).handleAddParticipantFailed(e.getMessage());
      }
    }
  }
  /**
   * A new presence info notification has been received for a given contact
   *
   * @param contact Contact
   * @param presense Presence info document
   */
  public void presenceInfoNotificationForContact(String contact, PidfDocument presence) {
    if (logger.isActivated()) {
      logger.debug("Presence info notification for contact " + contact);
    }

    try {
      // Extract number from contact
      String number = PhoneUtils.extractNumberFromUri(contact);

      // Get the current presence info
      ContactInfo currentContactInfo = ContactsManager.getInstance().getContactInfo(contact);
      ContactInfo newContactInfo = currentContactInfo;
      if (currentContactInfo == null) {
        if (logger.isActivated()) {
          logger.warn("Contact " + contact + " not found in EAB: by-pass the notification");
        }
        return;
      }
      PresenceInfo newPresenceInfo = currentContactInfo.getPresenceInfo();
      if (newPresenceInfo == null) {
        newPresenceInfo = new PresenceInfo();
        newContactInfo.setPresenceInfo(newPresenceInfo);
      }

      // Update the current capabilities
      Capabilities capabilities = new Capabilities();
      Vector<Tuple> tuples = presence.getTuplesList();
      for (int i = 0; i < tuples.size(); i++) {
        Tuple tuple = (Tuple) tuples.elementAt(i);

        boolean state = false;
        if (tuple.getStatus().getBasic().getValue().equals("open")) {
          state = true;
        }

        String id = tuple.getService().getId();
        if (id.equalsIgnoreCase(PresenceUtils.FEATURE_RCS2_VIDEO_SHARE)) {
          capabilities.setVideoSharingSupport(state);
        } else if (id.equalsIgnoreCase(PresenceUtils.FEATURE_RCS2_IMAGE_SHARE)) {
          capabilities.setImageSharingSupport(state);
        } else if (id.equalsIgnoreCase(PresenceUtils.FEATURE_RCS2_FT)) {
          capabilities.setFileTransferSupport(state);
        } else if (id.equalsIgnoreCase(PresenceUtils.FEATURE_RCS2_CS_VIDEO)) {
          capabilities.setCsVideoSupport(state);
        } else if (id.equalsIgnoreCase(PresenceUtils.FEATURE_RCS2_CHAT)) {
          capabilities.setImSessionSupport(state);
        }
      }
      newContactInfo.setCapabilities(capabilities);

      // Update presence status
      String presenceStatus = PresenceInfo.UNKNOWN;
      Person person = presence.getPerson();
      OverridingWillingness willingness = person.getOverridingWillingness();
      if (willingness != null) {
        if ((willingness.getBasic() != null) && (willingness.getBasic().getValue() != null)) {
          presenceStatus = willingness.getBasic().getValue();
        }
      }
      newPresenceInfo.setPresenceStatus(presenceStatus);

      // Update the presence info
      newPresenceInfo.setTimestamp(person.getTimestamp());
      if (person.getNote() != null) {
        newPresenceInfo.setFreetext(person.getNote().getValue());
      }
      if (person.getHomePage() != null) {
        newPresenceInfo.setFavoriteLink(new FavoriteLink(person.getHomePage()));
      }

      // Update geoloc info
      if (presence.getGeopriv() != null) {
        Geoloc geoloc =
            new Geoloc(
                presence.getGeopriv().getLatitude(),
                presence.getGeopriv().getLongitude(),
                presence.getGeopriv().getAltitude());
        newPresenceInfo.setGeoloc(geoloc);
      }
      newContactInfo.setPresenceInfo(newPresenceInfo);

      // Update contacts database
      ContactsManager.getInstance().setContactInfo(newContactInfo, currentContactInfo);

      // Get photo Etag values
      String lastEtag = ContactsManager.getInstance().getContactPhotoEtag(contact);
      String newEtag = null;
      if (person.getStatusIcon() != null) {
        newEtag = person.getStatusIcon().getEtag();
      }

      // Test if the photo has been removed
      if ((lastEtag != null) && (person.getStatusIcon() == null)) {
        if (logger.isActivated()) {
          logger.debug("Photo has been removed for " + contact);
        }

        // Update contacts database
        ContactsManager.getInstance().setContactPhotoIcon(contact, null);

        // Broadcast intent
        Intent intent = new Intent(PresenceApiIntents.CONTACT_PHOTO_CHANGED);
        intent.putExtra("contact", number);
        AndroidFactory.getApplicationContext().sendBroadcast(intent);
      } else
      // Test if the photo has been changed
      if ((person.getStatusIcon() != null) && (newEtag != null)) {
        if ((lastEtag == null) || (!lastEtag.equals(newEtag))) {
          if (logger.isActivated()) {
            logger.debug("Photo has changed for " + contact + ", download it in background");
          }

          // Download the photo in background
          downloadPhotoForContact(contact, presence.getPerson().getStatusIcon().getUrl(), newEtag);
        }
      }

      // Broadcast intent
      Intent intent = new Intent(PresenceApiIntents.CONTACT_INFO_CHANGED);
      intent.putExtra("contact", number);
      getApplicationContext().sendBroadcast(intent);
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("Internal exception", e);
      }
    }
  }