public static void startEventStreamService(Context context) {
    // the events stream service is launched
    // either the application has never be launched
    // or the service has been killed on low memory
    if (EventStreamService.getInstance() == null) {
      ArrayList<String> matrixIds = new ArrayList<String>();
      Collection<MXSession> sessions =
          Matrix.getInstance(context.getApplicationContext()).getSessions();

      if ((null != sessions) && (sessions.size() > 0)) {
        Log.d(LOG_TAG, "restart EventStreamService");

        for (MXSession session : sessions) {
          Boolean isSessionReady = session.getDataHandler().getStore().isReady();

          if (!isSessionReady) {
            session.getDataHandler().getStore().open();
          }

          // session to activate
          matrixIds.add(session.getCredentials().userId);
        }

        Intent intent = new Intent(context, EventStreamService.class);
        intent.putExtra(
            EventStreamService.EXTRA_MATRIX_IDS, matrixIds.toArray(new String[matrixIds.size()]));
        intent.putExtra(
            EventStreamService.EXTRA_STREAM_ACTION,
            EventStreamService.StreamAction.START.ordinal());
        context.startService(intent);
      }
    }
  }
  public static void goToRoomPage(
      final MXSession aSession,
      final String roomId,
      final Activity fromActivity,
      final Intent intentParam) {
    // check first if the 1:1 room already exists
    MXSession session = (aSession == null) ? Matrix.getMXSession(fromActivity, null) : aSession;

    // sanity check
    if ((null == session) || !session.isActive()) {
      return;
    }

    final MXSession fSession = session;

    Room room = session.getDataHandler().getRoom(roomId);

    // do not open a leaving room.
    // it does not make.
    if ((null != room) && (room.isLeaving())) {
      return;
    }

    fromActivity.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            // if the activity is not the home activity
            if (!(fromActivity instanceof HomeActivity)) {
              // pop to the home activity
              Intent intent = new Intent(fromActivity, HomeActivity.class);
              intent.setFlags(
                  android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
                      | android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP);
              intent.putExtra(HomeActivity.EXTRA_JUMP_TO_ROOM_ID, roomId);
              intent.putExtra(HomeActivity.EXTRA_JUMP_MATRIX_ID, fSession.getCredentials().userId);
              if (null != intentParam) {
                intent.putExtra(HomeActivity.EXTRA_ROOM_INTENT, intentParam);
              }
              fromActivity.startActivity(intent);
            } else {
              // already to the home activity
              // so just need to open the room activity
              Intent intent = new Intent(fromActivity, RoomActivity.class);
              intent.putExtra(RoomActivity.EXTRA_ROOM_ID, roomId);
              intent.putExtra(RoomActivity.EXTRA_MATRIX_ID, fSession.getCredentials().userId);
              if (null != intentParam) {
                intent.putExtra(HomeActivity.EXTRA_ROOM_INTENT, intentParam);
              }
              fromActivity.startActivity(intent);
            }
          }
        });
  }
  private void refreshRoomMember() {
    mRoom = mSession.getDataHandler().getRoom(mRoomId);

    if (null != mRoom) {
      // find out the room member
      Collection<RoomMember> members = mRoom.getMembers();
      for (RoomMember member : members) {
        if (member.getUserId().equals(mMemberId)) {
          mMember = member;
          break;
        }
      }
    }
  }
  private void updatePresenceInfo() {
    // update the presence ring
    IMXStore store = mSession.getDataHandler().getStore();
    User user = store.getUser(mMemberId);

    ImageView presenceRingView = (ImageView) findViewById(R.id.imageView_presenceRing);

    String presence = null;

    if (null != user) {
      presence = user.presence;
    }

    if (User.PRESENCE_ONLINE.equals(presence)) {
      presenceRingView.setColorFilter(this.getResources().getColor(R.color.presence_online));
    } else if (User.PRESENCE_UNAVAILABLE.equals(presence)) {
      presenceRingView.setColorFilter(this.getResources().getColor(R.color.presence_unavailable));
    } else if (User.PRESENCE_OFFLINE.equals(presence)) {
      presenceRingView.setColorFilter(this.getResources().getColor(R.color.presence_unavailable));
    } else {
      presenceRingView.setColorFilter(android.R.color.transparent);
    }

    TextView presenceTextView = (TextView) findViewById(R.id.textView_lastPresence);

    if ((user == null) || (user.lastActiveAgo == null)) {
      presenceTextView.setVisibility(View.GONE);
    } else {
      presenceTextView.setVisibility(View.VISIBLE);

      if (User.PRESENCE_OFFLINE.equals(user.presence)) {
        presenceTextView.setText(User.PRESENCE_OFFLINE);
        presenceTextView.setTextColor(Color.RED);
      } else {
        presenceTextView.setText(buildLastActiveDisplay(user.getRealLastActiveAgo()));
        presenceTextView.setTextColor(Color.BLACK);
      }
    }
  }
  /**
   * Offer to send some dedicated intent data to an existing room
   *
   * @param fromActivity the caller activity
   * @param intent the intent param
   * @param session the session/
   */
  public static void sendFilesTo(
      final Activity fromActivity, final Intent intent, final MXSession session) {
    // sanity check
    if ((null == session) || !session.isActive()) {
      return;
    }

    final ArrayList<RoomSummary> mergedSummaries = new ArrayList<RoomSummary>();
    mergedSummaries.addAll(session.getDataHandler().getStore().getSummaries());

    Collections.sort(
        mergedSummaries,
        new Comparator<RoomSummary>() {
          @Override
          public int compare(RoomSummary lhs, RoomSummary rhs) {
            if (lhs == null || lhs.getLatestEvent() == null) {
              return 1;
            } else if (rhs == null || rhs.getLatestEvent() == null) {
              return -1;
            }

            if (lhs.getLatestEvent().getOriginServerTs()
                > rhs.getLatestEvent().getOriginServerTs()) {
              return -1;
            } else if (lhs.getLatestEvent().getOriginServerTs()
                < rhs.getLatestEvent().getOriginServerTs()) {
              return 1;
            }
            return 0;
          }
        });

    AlertDialog.Builder builderSingle = new AlertDialog.Builder(fromActivity);
    builderSingle.setTitle(fromActivity.getText(R.string.send_files_in));
    final ArrayAdapter<String> arrayAdapter =
        new ArrayAdapter<String>(fromActivity, R.layout.dialog_room_selection);

    for (RoomSummary summary : mergedSummaries) {
      arrayAdapter.add(summary.getRoomName());
    }

    builderSingle.setNegativeButton(
        fromActivity.getText(R.string.cancel),
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
          }
        });

    builderSingle.setAdapter(
        arrayAdapter,
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(DialogInterface dialog, final int which) {
            dialog.dismiss();
            fromActivity.runOnUiThread(
                new Runnable() {
                  @Override
                  public void run() {
                    RoomSummary summary = mergedSummaries.get(which);
                    CommonActivityUtils.goToRoomPage(
                        session, summary.getRoomId(), fromActivity, intent);
                  }
                });
          }
        });
    builderSingle.show();
  }
  public static void goToOneToOneRoom(
      final MXSession aSession,
      final String otherUserId,
      final Activity fromActivity,
      final ApiCallback<Void> callback) {
    // sanity check
    if (null == otherUserId) {
      return;
    }

    // check first if the 1:1 room already exists
    MXSession session = (aSession == null) ? Matrix.getMXSession(fromActivity, null) : aSession;

    // no session is provided
    if (null == session) {
      // get the default one.
      session = Matrix.getInstance(fromActivity.getApplicationContext()).getDefaultSession();
    }

    // sanity check
    if ((null == session) || !session.isActive()) {
      return;
    }

    final MXSession fSession = session;

    // so, list the existing room, and search the 2 users room with this other users
    String roomId = null;
    Collection<Room> rooms = session.getDataHandler().getStore().getRooms();

    for (Room room : rooms) {
      Collection<RoomMember> members = room.getMembers();

      if (members.size() == 2) {
        for (RoomMember member : members) {
          if (member.getUserId().equals(otherUserId)) {
            roomId = room.getRoomId();
            break;
          }
        }
      }
    }

    // the room already exists -> switch to it
    if (null != roomId) {
      CommonActivityUtils.goToRoomPage(session, roomId, fromActivity, null);

      // everything is ok
      if (null != callback) {
        callback.onSuccess(null);
      }
    } else {
      session.createRoom(
          null,
          null,
          RoomState.VISIBILITY_PRIVATE,
          null,
          new SimpleApiCallback<String>(fromActivity) {

            @Override
            public void onSuccess(String roomId) {
              final Room room = fSession.getDataHandler().getRoom(roomId);

              room.invite(
                  otherUserId,
                  new SimpleApiCallback<Void>(this) {
                    @Override
                    public void onSuccess(Void info) {
                      CommonActivityUtils.goToRoomPage(
                          fSession, room.getRoomId(), fromActivity, null);

                      callback.onSuccess(null);
                    }

                    @Override
                    public void onMatrixError(MatrixError e) {
                      if (null != callback) {
                        callback.onMatrixError(e);
                      }
                    }

                    @Override
                    public void onNetworkError(Exception e) {
                      if (null != callback) {
                        callback.onNetworkError(e);
                      }
                    }

                    @Override
                    public void onUnexpectedError(Exception e) {
                      if (null != callback) {
                        callback.onUnexpectedError(e);
                      }
                    }
                  });
            }

            @Override
            public void onMatrixError(MatrixError e) {
              if (null != callback) {
                callback.onMatrixError(e);
              }
            }

            @Override
            public void onNetworkError(Exception e) {
              if (null != callback) {
                callback.onNetworkError(e);
              }
            }

            @Override
            public void onUnexpectedError(Exception e) {
              if (null != callback) {
                callback.onUnexpectedError(e);
              }
            }
          });
    }
  }
  @Override
  protected void onResume() {
    super.onResume();

    mSession.getDataHandler().getRoom(mRoom.getRoomId()).addEventListener(mEventListener);
  }
  @Override
  protected void onPause() {
    super.onPause();

    mSession.getDataHandler().getRoom(mRoom.getRoomId()).removeEventListener(mEventListener);
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    if (CommonActivityUtils.shouldRestartApp()) {
      CommonActivityUtils.restartApp(this);
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_member_details);

    Intent intent = getIntent();
    if (!intent.hasExtra(EXTRA_ROOM_ID)) {
      Log.e(LOG_TAG, "No room ID extra.");
      finish();
      return;
    }
    mRoomId = intent.getStringExtra(EXTRA_ROOM_ID);

    if (!intent.hasExtra(EXTRA_MEMBER_ID)) {
      Log.e(LOG_TAG, "No member ID extra.");
      finish();
      return;
    }

    mMemberId = intent.getStringExtra(EXTRA_MEMBER_ID);

    mSession = getSession(intent);

    if (null == mSession) {
      Log.e(LOG_TAG, "The no session");
      finish();
      return;
    }

    mRoom = mSession.getDataHandler().getRoom(mRoomId);

    if (null == mRoom) {
      Log.e(LOG_TAG, "The room is not found");
      finish();
      return;
    }

    // find out the room member
    Collection<RoomMember> members = mRoom.getMembers();
    for (RoomMember member : members) {
      if (member.getUserId().equals(mMemberId)) {
        mMember = member;
        break;
      }
    }

    // sanity checks
    if (null == mMember) {
      Log.e(LOG_TAG, "The user " + mMemberId + " is not in the room " + mRoomId);
      finish();
      return;
    }

    mButtonsList = new ArrayList<Button>();
    mButtonsList.add((Button) findViewById(R.id.contact_button_1));
    mButtonsList.add((Button) findViewById(R.id.contact_button_2));
    mButtonsList.add((Button) findViewById(R.id.contact_button_3));
    mButtonsList.add((Button) findViewById(R.id.contact_button_4));

    // set the click listener for each button
    for (Button button : mButtonsList) {
      button.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              String text = (String) ((Button) v).getText();

              final View refreshingView = findViewById(R.id.profile_mask);
              final ApiCallback callback =
                  new SimpleApiCallback<Void>(MemberDetailsActivity.this) {
                    @Override
                    public void onMatrixError(MatrixError e) {
                      if (MatrixError.FORBIDDEN.equals(e.errcode)) {
                        Toast.makeText(MemberDetailsActivity.this, e.error, Toast.LENGTH_LONG)
                            .show();
                      }

                      MemberDetailsActivity.this.refresh();
                    }

                    @Override
                    public void onSuccess(Void info) {
                      MemberDetailsActivity.this.refresh();
                    }
                  };

              // disable the buttons
              for (Button button : mButtonsList) {
                button.setEnabled(false);
              }

              if (text.equals(getResources().getString(R.string.kick))) {
                refreshingView.setVisibility(View.VISIBLE);
                mRoom.kick(mMember.getUserId(), callback);
              } else if (text.equals(getResources().getString(R.string.ban))) {
                refreshingView.setVisibility(View.VISIBLE);
                mRoom.ban(mMember.getUserId(), null, callback);
              } else if (text.equals(getResources().getString(R.string.unban))) {
                refreshingView.setVisibility(View.VISIBLE);
                mRoom.unban(mMember.getUserId(), callback);
              } else if (text.equals(getResources().getString(R.string.invite))) {
                refreshingView.setVisibility(View.VISIBLE);
                mRoom.invite(mMember.getUserId(), callback);
              } else if (text.equals(getResources().getString(R.string.chat))) {
                refreshingView.setVisibility(View.VISIBLE);
                MemberDetailsActivity.this.runOnUiThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        CommonActivityUtils.goToOneToOneRoom(
                            mSession,
                            mMemberId,
                            MemberDetailsActivity.this,
                            new SimpleApiCallback<Void>(MemberDetailsActivity.this) {
                              @Override
                              public void onMatrixError(MatrixError e) {
                                if (MatrixError.FORBIDDEN.equals(e.errcode)) {
                                  Toast.makeText(
                                          MemberDetailsActivity.this, e.error, Toast.LENGTH_LONG)
                                      .show();
                                }
                                MemberDetailsActivity.this.refresh();
                              }

                              @Override
                              public void onNetworkError(Exception e) {
                                Toast.makeText(
                                        MemberDetailsActivity.this,
                                        e.getLocalizedMessage(),
                                        Toast.LENGTH_LONG)
                                    .show();
                                MemberDetailsActivity.this.refresh();
                              }

                              @Override
                              public void onUnexpectedError(Exception e) {
                                Toast.makeText(
                                        MemberDetailsActivity.this,
                                        e.getLocalizedMessage(),
                                        Toast.LENGTH_LONG)
                                    .show();
                                MemberDetailsActivity.this.refresh();
                              }
                            });
                      }
                    });
              } else if (text.equals(getResources().getString(R.string.set_power_level))) {
                String title = getResources().getString(R.string.set_power_level);
                String initText =
                    mRoom.getLiveState().getPowerLevels().getUserPowerLevel(mMemberId) + "";

                final AlertDialog alert =
                    CommonActivityUtils.createEditTextAlert(
                        MemberDetailsActivity.this,
                        title,
                        null,
                        initText,
                        new CommonActivityUtils.OnSubmitListener() {
                          @Override
                          public void onSubmit(String text) {
                            if (text.length() == 0) {
                              return;
                            }

                            int newPowerLevel = -1;

                            try {
                              newPowerLevel = Integer.parseInt(text);
                            } catch (Exception e) {
                            }

                            if (newPowerLevel >= 0) {
                              refreshingView.setVisibility(View.VISIBLE);
                              mRoom.updateUserPowerLevels(
                                  mMember.getUserId(), newPowerLevel, callback);
                            } else {
                              MemberDetailsActivity.this.refresh();
                            }
                          }

                          @Override
                          public void onCancelled() {
                            MemberDetailsActivity.this.refresh();
                          }
                        });

                MemberDetailsActivity.this.runOnUiThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        alert.show();
                      }
                    });
              }
            }
          });
    }

    // load the thumbnail
    mThumbnailImageView = (ImageView) findViewById(R.id.avatar_img);

    // set the title
    mMatrixIdTextView = (TextView) findViewById(R.id.textView_matrixid);

    // refresh the activity views
    refresh();
  }
  /**
   * Init the dialog view.
   *
   * @param v the dialog view.
   */
  void initView(View v) {
    mListView = ((ListView) v.findViewById(R.id.listView_members));

    IMXStore store = mSession.getDataHandler().getStore();

    // remove the current room members
    ArrayList<String> idsToIgnore = new ArrayList<String>();
    Room room = store.getRoom(mRoomId);
    Collection<RoomMember> currentMembers = room.getMembers();

    for (RoomMember member : currentMembers) {
      idsToIgnore.add(member.getUserId());
    }

    // get the members list
    ArrayList<RoomMember> members_OneToOne = new ArrayList<RoomMember>();
    ArrayList<String> ids_OneToOne = new ArrayList<String>();

    ArrayList<RoomMember> members_MaxTenMembers = new ArrayList<RoomMember>();
    ArrayList<String> ids_MaxTenMembers = new ArrayList<String>();

    ArrayList<RoomMember> members_BigRooms = new ArrayList<RoomMember>();
    ArrayList<String> ids_BigRooms = new ArrayList<String>();

    Collection<RoomSummary> summaries = store.getSummaries();

    for (RoomSummary summary : summaries) {
      // not the current summary
      if (!summary.getRoomId().equals(mRoomId)) {
        Collection<RoomMember> otherRoomMembers = room.getMembers();

        for (RoomMember member : otherRoomMembers) {
          String userID = member.getUserId();

          // accepted User ID or still active users
          if ((idsToIgnore.indexOf(userID) < 0)
              && (RoomMember.MEMBERSHIP_JOIN.equals(member.membership))) {
            int posOneToOne = ids_OneToOne.indexOf(userID);
            int posTenMembers = ids_MaxTenMembers.indexOf(userID);
            int posBigRooms = ids_BigRooms.indexOf(userID);

            if (otherRoomMembers.size() <= 2) {
              if (posBigRooms >= 0) {
                members_BigRooms.remove(posBigRooms);
                ids_BigRooms.remove(posBigRooms);
              }

              if (posTenMembers >= 0) {
                members_MaxTenMembers.remove(posTenMembers);
                ids_MaxTenMembers.remove(posTenMembers);
              }

              if (posOneToOne < 0) {
                members_OneToOne.add(member);
                ids_OneToOne.add(member.getUserId());
              }
            } else if (otherRoomMembers.size() <= 10) {
              if (posBigRooms >= 0) {
                members_BigRooms.remove(posBigRooms);
                ids_BigRooms.remove(posBigRooms);
              }

              if ((posTenMembers < 0) && (posOneToOne < 0)) {
                members_MaxTenMembers.add(member);
                ids_MaxTenMembers.add(member.getUserId());
              }
            } else {
              if ((posBigRooms < 0) && (posTenMembers < 0) && (posOneToOne < 0)) {
                members_BigRooms.add(member);
                ids_BigRooms.add(member.getUserId());
              }
            }
          }
        }
      }
    }

    mAdapter =
        new MembersInvitationAdapter(
            getActivity(), R.layout.adapter_item_members_invitation, getMXMediasCache());

    Collections.sort(members_OneToOne, alphaComparator);
    Collections.sort(members_MaxTenMembers, alphaComparator);
    Collections.sort(members_BigRooms, alphaComparator);

    mAdapter.addAll(members_OneToOne);
    mAdapter.addAll(members_MaxTenMembers);
    mAdapter.addAll(members_BigRooms);

    ArrayList<Integer> bounds = new ArrayList<Integer>();
    ArrayList<String> sectionTitles = new ArrayList<String>();

    int index = 0;

    if (members_OneToOne.size() > 0) {
      bounds.add(index);
      sectionTitles.add(getActivity().getResources().getString(R.string.members_one_to_one));
      index += members_OneToOne.size();
    }

    if (members_MaxTenMembers.size() > 0) {
      bounds.add(index);
      sectionTitles.add(
          getActivity().getResources().getString(R.string.members_small_room_members));
      index += members_MaxTenMembers.size();
    }

    if (members_BigRooms.size() > 0) {
      bounds.add(index);
      sectionTitles.add(
          getActivity().getResources().getString(R.string.members_large_room_members));
      index += members_BigRooms.size();
    }

    mAdapter.setSectionTiles(bounds, sectionTitles);

    mListView.setAdapter(mAdapter);
  }