use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.
the class MXDataHandler method manageResponse.
/**
* Manage the sync response in the UI thread.
*
* @param syncResponse the syncResponse to manage.
* @param fromToken the start sync token
* @param isCatchingUp true when there is a pending catch-up
*/
private void manageResponse(final SyncResponse syncResponse, final String fromToken, final boolean isCatchingUp) {
if (!isAlive()) {
Log.e(LOG_TAG, "manageResponse : ignored because the session has been closed");
return;
}
boolean isInitialSync = (null == fromToken);
boolean isEmptyResponse = true;
// sanity check
if (null != syncResponse) {
Log.d(LOG_TAG, "onSyncComplete");
// to ensure to decrypt them properly
if ((null != syncResponse.toDevice) && (null != syncResponse.toDevice.events) && (syncResponse.toDevice.events.size() > 0)) {
Log.d(LOG_TAG, "manageResponse : receives " + syncResponse.toDevice.events.size() + " toDevice events");
for (Event toDeviceEvent : syncResponse.toDevice.events) {
handleToDeviceEvent(toDeviceEvent);
}
}
// to be able to update direct chats dictionary during invites handling.
if (null != syncResponse.accountData) {
Log.d(LOG_TAG, "Received " + syncResponse.accountData.size() + " accountData events");
manageAccountData(syncResponse.accountData, isInitialSync);
}
// sanity check
if (null != syncResponse.rooms) {
// joined rooms events
if ((null != syncResponse.rooms.join) && (syncResponse.rooms.join.size() > 0)) {
Log.d(LOG_TAG, "Received " + syncResponse.rooms.join.size() + " joined rooms");
Set<String> roomIds = syncResponse.rooms.join.keySet();
// Handle first joined rooms
for (String roomId : roomIds) {
try {
if (null != mLeftRoomsStore.getRoom(roomId)) {
Log.d(LOG_TAG, "the room " + roomId + " moves from left to the joined ones");
mLeftRoomsStore.deleteRoom(roomId);
}
getRoom(roomId).handleJoinedRoomSync(syncResponse.rooms.join.get(roomId), isInitialSync);
} catch (Exception e) {
Log.e(LOG_TAG, "## manageResponse() : handleJoinedRoomSync failed " + e.getMessage() + " for room " + roomId);
}
}
isEmptyResponse = false;
}
// invited room management
if ((null != syncResponse.rooms.invite) && (syncResponse.rooms.invite.size() > 0)) {
Log.d(LOG_TAG, "Received " + syncResponse.rooms.invite.size() + " invited rooms");
Set<String> roomIds = syncResponse.rooms.invite.keySet();
HashMap<String, List<String>> updatedDirectChatRoomsDict = null;
boolean hasChanged = false;
for (String roomId : roomIds) {
try {
Log.d(LOG_TAG, "## manageResponse() : the user has been invited to " + roomId);
if (null != mLeftRoomsStore.getRoom(roomId)) {
Log.d(LOG_TAG, "the room " + roomId + " moves from left to the invited ones");
mLeftRoomsStore.deleteRoom(roomId);
}
Room room = getRoom(roomId);
InvitedRoomSync invitedRoomSync = syncResponse.rooms.invite.get(roomId);
room.handleInvitedRoomSync(invitedRoomSync);
// Handle here the invites to a direct chat.
if (room.isDirectChatInvitation()) {
// Retrieve the inviter user id.
String participantUserId = null;
for (Event event : invitedRoomSync.inviteState.events) {
if (null != event.sender) {
participantUserId = event.sender;
break;
}
}
if (null != participantUserId) {
// Prepare the updated dictionary.
if (null == updatedDirectChatRoomsDict) {
if (null != this.getStore().getDirectChatRoomsDict()) {
// Consider the current dictionary.
updatedDirectChatRoomsDict = new HashMap<>(this.getStore().getDirectChatRoomsDict());
} else {
updatedDirectChatRoomsDict = new HashMap<>();
}
}
ArrayList<String> roomIdsList;
if (updatedDirectChatRoomsDict.containsKey(participantUserId)) {
roomIdsList = new ArrayList<>(updatedDirectChatRoomsDict.get(participantUserId));
} else {
roomIdsList = new ArrayList<>();
}
// Check whether the room was not yet seen as direct chat
if (roomIdsList.indexOf(roomId) < 0) {
Log.d(LOG_TAG, "## manageResponse() : add this new invite in direct chats");
// update room list with the new room
roomIdsList.add(roomId);
updatedDirectChatRoomsDict.put(participantUserId, roomIdsList);
hasChanged = true;
}
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "## manageResponse() : handleInvitedRoomSync failed " + e.getMessage() + " for room " + roomId);
}
}
isEmptyResponse = false;
if (hasChanged) {
mAccountDataRestClient.setAccountData(mCredentials.userId, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, updatedDirectChatRoomsDict, new ApiCallback<Void>() {
@Override
public void onSuccess(Void info) {
Log.d(LOG_TAG, "## manageResponse() : succeeds");
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
// TODO: we should try again.
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
}
});
}
}
// when inviting after leaving a room, the room is defined in the both leave & invite rooms list.
if ((null != syncResponse.rooms.leave) && (syncResponse.rooms.leave.size() > 0)) {
Log.d(LOG_TAG, "Received " + syncResponse.rooms.leave.size() + " left rooms");
Set<String> roomIds = syncResponse.rooms.leave.keySet();
for (String roomId : roomIds) {
// RoomSync leftRoomSync = syncResponse.rooms.leave.get(roomId);
// Presently we remove the existing room from the rooms list.
// FIXME SYNC V2 Archive/Display the left rooms!
// For that create 'handleArchivedRoomSync' method
String membership = RoomMember.MEMBERSHIP_LEAVE;
Room room = getRoom(roomId);
// check if the room still exists.
if (null != room) {
// use 'handleJoinedRoomSync' to pass the last events to the room before leaving it.
// The room will then able to notify its listeners.
room.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
RoomMember member = room.getMember(getUserId());
if (null != member) {
membership = member.membership;
}
Log.d(LOG_TAG, "## manageResponse() : leave the room " + roomId);
}
if (!TextUtils.equals(membership, RoomMember.MEMBERSHIP_KICK) && !TextUtils.equals(membership, RoomMember.MEMBERSHIP_BAN)) {
// ensure that the room data are properly deleted
this.getStore().deleteRoom(roomId);
onLeaveRoom(roomId);
} else {
onRoomKick(roomId);
}
// don't add to the left rooms if the user has been kicked / banned
if ((mAreLeftRoomsSynced) && TextUtils.equals(membership, RoomMember.MEMBERSHIP_LEAVE)) {
Room leftRoom = getRoom(mLeftRoomsStore, roomId, true);
leftRoom.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
}
}
isEmptyResponse = false;
}
}
// groups
if (null != syncResponse.groups) {
// Handle invited groups
if ((null != syncResponse.groups.invite) && !syncResponse.groups.invite.isEmpty()) {
// Handle invited groups
for (String groupId : syncResponse.groups.invite.keySet()) {
InvitedGroupSync invitedGroupSync = syncResponse.groups.invite.get(groupId);
mGroupsManager.onNewGroupInvitation(groupId, invitedGroupSync.profile, invitedGroupSync.inviter, !isInitialSync);
}
}
// Handle joined groups
if ((null != syncResponse.groups.join) && !syncResponse.groups.join.isEmpty()) {
for (String groupId : syncResponse.groups.join.keySet()) {
mGroupsManager.onJoinGroup(groupId, !isInitialSync);
}
}
// Handle left groups
if ((null != syncResponse.groups.leave) && !syncResponse.groups.leave.isEmpty()) {
// Handle joined groups
for (String groupId : syncResponse.groups.leave.keySet()) {
mGroupsManager.onLeaveGroup(groupId, !isInitialSync);
}
}
}
// Handle presence of other users
if ((null != syncResponse.presence) && (null != syncResponse.presence.events)) {
Log.d(LOG_TAG, "Received " + syncResponse.presence.events.size() + " presence events");
for (Event presenceEvent : syncResponse.presence.events) {
handlePresenceEvent(presenceEvent);
}
}
if (null != mCrypto) {
mCrypto.onSyncCompleted(syncResponse, fromToken, isCatchingUp);
}
IMXStore store = getStore();
if (!isEmptyResponse && (null != store)) {
store.setEventStreamToken(syncResponse.nextBatch);
store.commit();
}
}
if (isInitialSync) {
if (!isCatchingUp) {
startCrypto(true);
} else {
// the events thread sends a dummy initial sync event
// when the application is restarted.
mIsStartingCryptoWithInitialSync = !isEmptyResponse;
}
onInitialSyncComplete((null != syncResponse) ? syncResponse.nextBatch : null);
} else {
if (!isCatchingUp) {
startCrypto(mIsStartingCryptoWithInitialSync);
}
try {
onLiveEventsChunkProcessed(fromToken, (null != syncResponse) ? syncResponse.nextBatch : fromToken);
} catch (Exception e) {
Log.e(LOG_TAG, "onLiveEventsChunkProcessed failed " + e.getMessage());
}
try {
// check if an incoming call has been received
mCallsManager.checkPendingIncomingCalls();
} catch (Exception e) {
Log.e(LOG_TAG, "checkPendingIncomingCalls failed " + e + " " + e.getMessage());
}
}
}
use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.
the class MXCrypto method setDeviceVerification.
/**
* Update the blocked/verified state of the given device.
*
* @param verificationStatus the new verification status
* @param deviceId the unique identifier for the device.
* @param userId the owner of the device
* @param callback the asynchronous callback
*/
public void setDeviceVerification(final int verificationStatus, final String deviceId, final String userId, final ApiCallback<Void> callback) {
if (hasBeenReleased()) {
return;
}
final ArrayList<String> userRoomIds = new ArrayList<>();
Collection<Room> rooms = mSession.getDataHandler().getStore().getRooms();
for (Room room : rooms) {
if (room.isEncrypted()) {
RoomMember roomMember = room.getMember(userId);
// test if the user joins the room
if ((null != roomMember) && TextUtils.equals(roomMember.membership, RoomMember.MEMBERSHIP_JOIN)) {
userRoomIds.add(room.getRoomId());
}
}
}
getEncryptingThreadHandler().post(new Runnable() {
@Override
public void run() {
MXDeviceInfo device = mCryptoStore.getUserDevice(deviceId, userId);
// Sanity check
if (null == device) {
Log.e(LOG_TAG, "## setDeviceVerification() : Unknown device " + userId + ":" + deviceId);
if (null != callback) {
getUIHandler().post(new Runnable() {
@Override
public void run() {
callback.onSuccess(null);
}
});
}
return;
}
if (device.mVerified != verificationStatus) {
device.mVerified = verificationStatus;
mCryptoStore.storeUserDevice(userId, device);
}
if (null != callback) {
getUIHandler().post(new Runnable() {
@Override
public void run() {
callback.onSuccess(null);
}
});
}
}
});
}
use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.
the class MXCrypto method setEncryptionInRoom.
/**
* Configure a room to use encryption.
* This method must be called in getEncryptingThreadHandler
*
* @param roomId the room id to enable encryption in.
* @param algorithm the encryption config for the room.
* @param inhibitDeviceQuery true to suppress device list query for users in the room (for now)
* @return true if the operation succeeds.
*/
private boolean setEncryptionInRoom(String roomId, String algorithm, boolean inhibitDeviceQuery) {
if (hasBeenReleased()) {
return false;
}
// If we already have encryption in this room, we should ignore this event
// (for now at least. Maybe we should alert the user somehow?)
String existingAlgorithm = mCryptoStore.getRoomAlgorithm(roomId);
if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(existingAlgorithm, algorithm)) {
Log.e(LOG_TAG, "## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in " + roomId);
return false;
}
Class<IMXEncrypting> encryptingClass = MXCryptoAlgorithms.sharedAlgorithms().encryptorClassForAlgorithm(algorithm);
if (null == encryptingClass) {
Log.e(LOG_TAG, "## setEncryptionInRoom() : Unable to encrypt with " + algorithm);
return false;
}
mCryptoStore.storeRoomAlgorithm(roomId, algorithm);
IMXEncrypting alg;
try {
Constructor<?> ctor = encryptingClass.getConstructors()[0];
alg = (IMXEncrypting) ctor.newInstance();
} catch (Exception e) {
Log.e(LOG_TAG, "## setEncryptionInRoom() : fail to load the class");
return false;
}
alg.initWithMatrixSession(mSession, roomId);
synchronized (mRoomEncryptors) {
mRoomEncryptors.put(roomId, alg);
}
// we just invalidate everyone in the room.
if (null == existingAlgorithm) {
Log.d(LOG_TAG, "Enabling encryption in " + roomId + " for the first time; invalidating device lists for all users therein");
Room room = mSession.getDataHandler().getRoom(roomId);
if (null != room) {
Collection<RoomMember> members = room.getJoinedMembers();
List<String> userIds = new ArrayList<>();
for (RoomMember m : members) {
userIds.add(m.getUserId());
}
getDeviceList().startTrackingDeviceList(userIds);
if (!inhibitDeviceQuery) {
getDeviceList().refreshOutdatedDeviceLists();
}
}
}
return true;
}
use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.
the class MXCallsManager method inviteConferenceUser.
/**
* Invite the conference user to a room.
* It is mandatory before starting a conference call.
*
* @param room the room
* @param callback the async callback
*/
private void inviteConferenceUser(final Room room, final ApiCallback<Void> callback) {
Log.d(LOG_TAG, "inviteConferenceUser " + room.getRoomId());
String conferenceUserId = getConferenceUserId(room.getRoomId());
RoomMember conferenceMember = room.getMember(conferenceUserId);
if ((null != conferenceMember) && TextUtils.equals(conferenceMember.membership, RoomMember.MEMBERSHIP_JOIN)) {
mUIThreadHandler.post(new Runnable() {
@Override
public void run() {
callback.onSuccess(null);
}
});
} else {
room.invite(conferenceUserId, callback);
}
}
use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.
the class RoomState method getMemberName.
/**
* Return an unique display name of the member userId.
*
* @param userId the user id
* @return unique display name
*/
public String getMemberName(String userId) {
// sanity check
if (null == userId) {
return null;
}
String displayName;
synchronized (this) {
if (null == mMemberDisplayNameByUserId) {
mMemberDisplayNameByUserId = new HashMap<>();
}
displayName = mMemberDisplayNameByUserId.get(userId);
}
if (null != displayName) {
return displayName;
}
// Get the user display name from the member list of the room
RoomMember member = getMember(userId);
// Do not consider null display name
if ((null != member) && !TextUtils.isEmpty(member.displayname)) {
displayName = member.displayname;
synchronized (this) {
ArrayList<String> matrixIds = new ArrayList<>();
// Disambiguate users who have the same display name in the room
for (RoomMember aMember : mMembers.values()) {
if (displayName.equals(aMember.displayname)) {
matrixIds.add(aMember.getUserId());
}
}
// index it i.e bob (<Matrix id>)
if (matrixIds.size() > 1) {
displayName += " (" + userId + ")";
}
}
} else if ((null != member) && TextUtils.equals(member.membership, RoomMember.MEMBERSHIP_INVITE)) {
User user = ((MXDataHandler) mDataHandler).getUser(userId);
if (null != user) {
displayName = user.displayname;
}
}
if (null == displayName) {
// By default, use the user ID
displayName = userId;
}
mMemberDisplayNameByUserId.put(userId, displayName);
return displayName;
}
Aggregations