use of org.matrix.androidsdk.core.model.MatrixError in project matrix-android-sdk by matrix-org.
the class EventsThread method executeInitialSync.
private void executeInitialSync() {
Log.d(LOG_TAG, "Requesting initial sync...");
long initialSyncStartTime = System.currentTimeMillis();
while (!isInitialSyncDone()) {
final CountDownLatch latch = new CountDownLatch(1);
mEventsRestClient.syncFromToken(null, 0, DEFAULT_CLIENT_TIMEOUT_MS, mIsOnline ? null : "offline", mFilterOrFilterId, new SimpleApiCallback<SyncResponse>(mFailureCallback) {
@Override
public void onSuccess(SyncResponse syncResponse) {
Log.d(LOG_TAG, "Received initial sync response.");
mNextServerTimeoutms = hasDevicesChanged(syncResponse) ? 0 : mDefaultServerTimeoutms;
mListener.onSyncResponse(syncResponse, null, (0 == mNextServerTimeoutms));
mCurrentToken = syncResponse.nextBatch;
// unblock the events thread
latch.countDown();
}
private void sleepAndUnblock() {
Log.i(LOG_TAG, "Waiting a bit before retrying");
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
public void run() {
latch.countDown();
}
}, RETRY_WAIT_TIME_MS);
}
@Override
public void onNetworkError(Exception e) {
if (isInitialSyncDone()) {
// Ignore error
// FIXME I think this is the source of infinite initial sync if a network error occurs
// FIXME because latch is not counted down. TO BE TESTED
onSuccess(null);
} else {
Log.e(LOG_TAG, "Sync V2 onNetworkError " + e.getMessage(), e);
super.onNetworkError(e);
sleepAndUnblock();
}
}
@Override
public void onMatrixError(MatrixError e) {
super.onMatrixError(e);
if (MatrixError.isConfigurationErrorCode(e.errcode)) {
mListener.onConfigurationError(e.errcode);
} else {
mListener.onSyncError(e);
sleepAndUnblock();
}
}
@Override
public void onUnexpectedError(Exception e) {
super.onUnexpectedError(e);
Log.e(LOG_TAG, "Sync V2 onUnexpectedError " + e.getMessage(), e);
sleepAndUnblock();
}
});
// block until the initial sync callback is invoked.
try {
latch.await();
} catch (InterruptedException e) {
Log.e(LOG_TAG, "Interrupted whilst performing initial sync.", e);
} catch (Exception e) {
// reported by GA
// The thread might have been killed.
Log.e(LOG_TAG, "latch.await() failed " + e.getMessage(), e);
}
}
long initialSyncEndTime = System.currentTimeMillis();
long initialSyncDuration = initialSyncEndTime - initialSyncStartTime;
if (mMetricsListener != null) {
mMetricsListener.onInitialSyncFinished(initialSyncDuration);
}
}
use of org.matrix.androidsdk.core.model.MatrixError in project matrix-android-sdk by matrix-org.
the class MXCallsManager method getConferenceUserRoom.
/**
* Get the room with the conference user dedicated for the passed room.
*
* @param roomId the room id.
* @param callback the async callback.
*/
private void getConferenceUserRoom(final String roomId, final ApiCallback<Room> callback) {
Log.d(LOG_TAG, "getConferenceUserRoom with room id " + roomId);
String conferenceUserId = getConferenceUserId(roomId);
Room conferenceRoom = null;
Collection<Room> rooms = mSession.getDataHandler().getStore().getRooms();
// Use an existing 1:1 with the conference user; else make one
for (Room room : rooms) {
if (room.isConferenceUserRoom() && room.getNumberOfMembers() == 2 && null != room.getMember(conferenceUserId)) {
conferenceRoom = room;
break;
}
}
if (null != conferenceRoom) {
Log.d(LOG_TAG, "getConferenceUserRoom : the room already exists");
final Room fConferenceRoom = conferenceRoom;
mSession.getDataHandler().getStore().commit();
mUIThreadHandler.post(new Runnable() {
@Override
public void run() {
callback.onSuccess(fConferenceRoom);
}
});
} else {
Log.d(LOG_TAG, "getConferenceUserRoom : create the room");
CreateRoomParams params = new CreateRoomParams();
params.preset = CreateRoomParams.PRESET_PRIVATE_CHAT;
params.invitedUserIds = Arrays.asList(conferenceUserId);
mSession.createRoom(params, new ApiCallback<String>() {
@Override
public void onSuccess(String roomId) {
Log.d(LOG_TAG, "getConferenceUserRoom : the room creation succeeds");
Room room = mSession.getDataHandler().getRoom(roomId);
if (null != room) {
room.setIsConferenceUserRoom(true);
mSession.getDataHandler().getStore().commit();
callback.onSuccess(room);
}
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "getConferenceUserRoom : failed " + e.getMessage(), e);
callback.onNetworkError(e);
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(LOG_TAG, "getConferenceUserRoom : failed " + e.getMessage());
callback.onMatrixError(e);
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "getConferenceUserRoom : failed " + e.getMessage(), e);
callback.onUnexpectedError(e);
}
});
}
}
use of org.matrix.androidsdk.core.model.MatrixError in project matrix-android-sdk by matrix-org.
the class MXCall method sendHangup.
/**
* send an hang up event
*
* @param reason the reason
*/
protected void sendHangup(String reason) {
JsonObject hangupContent = new JsonObject();
hangupContent.add("version", new JsonPrimitive(0));
hangupContent.add("call_id", new JsonPrimitive(mCallId));
if (!TextUtils.isEmpty(reason)) {
hangupContent.add("reason", new JsonPrimitive(reason));
}
Event event = new Event(Event.EVENT_TYPE_CALL_HANGUP, hangupContent, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId());
// local notification to indicate the end of call
mUIThreadHandler.post(() -> dispatchOnCallEnd(END_CALL_REASON_USER_HIMSELF));
Log.d(LOG_TAG, "## sendHangup(): reason=" + reason);
// send hang up event to the server
mCallSignalingRoom.sendEvent(event, new ApiCallback<Void>() {
@Override
public void onSuccess(Void info) {
Log.d(LOG_TAG, "## sendHangup(): onSuccess");
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "## sendHangup(): onNetworkError Msg=" + e.getMessage(), e);
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(LOG_TAG, "## sendHangup(): onMatrixError Msg=" + e.getMessage());
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "## sendHangup(): onUnexpectedError Msg=" + e.getMessage(), e);
}
});
}
use of org.matrix.androidsdk.core.model.MatrixError in project matrix-android-sdk by matrix-org.
the class MXCallsManager method createCallInRoom.
/**
* Create an IMXCall in the room defines by its room Id.
* -> for a 1:1 call, it is a standard call.
* -> for a conference call,
* ----> the conference user is invited to the room (if it was not yet invited)
* ----> the call signaling room is created (or retrieved) with the conference
* ----> and the call is started
*
* @param roomId the room roomId
* @param isVideo true to start a video call
* @param callback the async callback
*/
public void createCallInRoom(final String roomId, final boolean isVideo, final ApiCallback<IMXCall> callback) {
Log.d(LOG_TAG, "createCallInRoom in " + roomId);
final Room room = mSession.getDataHandler().getRoom(roomId);
// sanity check
if (null != room) {
if (isSupported()) {
int joinedMembers = room.getNumberOfJoinedMembers();
Log.d(LOG_TAG, "createCallInRoom : the room has " + joinedMembers + " joined members");
if (joinedMembers > 1) {
if (joinedMembers == 2) {
// So it seems safer to reject the call creation it it will fail.
if (room.isEncrypted() && mSession.getCrypto() != null && mSession.getCrypto().warnOnUnknownDevices()) {
room.getJoinedMembersAsync(new SimpleApiCallback<List<RoomMember>>(callback) {
@Override
public void onSuccess(List<RoomMember> members) {
if (members.size() != 2) {
// Safety check
callback.onUnexpectedError(new Exception("Wrong number of members"));
return;
}
String userId1 = members.get(0).getUserId();
String userId2 = members.get(1).getUserId();
// force the refresh to ensure that the devices list is up-to-date
mSession.getCrypto().checkUnknownDevices(Arrays.asList(userId1, userId2), new SimpleApiCallback<Void>(callback) {
@Override
public void onSuccess(Void anything) {
final IMXCall call = getCallWithCallId(null, true);
call.setRooms(room, room);
call.setIsVideo(isVideo);
dispatchOnOutgoingCall(call);
if (null != callback) {
mUIThreadHandler.post(() -> callback.onSuccess(call));
}
}
});
}
});
} else {
final IMXCall call = getCallWithCallId(null, true);
call.setIsVideo(isVideo);
dispatchOnOutgoingCall(call);
call.setRooms(room, room);
if (null != callback) {
mUIThreadHandler.post(() -> callback.onSuccess(call));
}
}
} else {
Log.d(LOG_TAG, "createCallInRoom : inviteConferenceUser");
inviteConferenceUser(room, new ApiCallback<Void>() {
@Override
public void onSuccess(Void info) {
Log.d(LOG_TAG, "createCallInRoom : inviteConferenceUser succeeds");
getConferenceUserRoom(room.getRoomId(), new ApiCallback<Room>() {
@Override
public void onSuccess(Room conferenceRoom) {
Log.d(LOG_TAG, "createCallInRoom : getConferenceUserRoom succeeds");
final IMXCall call = getCallWithCallId(null, true);
call.setRooms(room, conferenceRoom);
call.setIsConference(true);
call.setIsVideo(isVideo);
dispatchOnOutgoingCall(call);
if (null != callback) {
mUIThreadHandler.post(() -> callback.onSuccess(call));
}
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "createCallInRoom : getConferenceUserRoom failed " + e.getMessage(), e);
if (null != callback) {
callback.onNetworkError(e);
}
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(LOG_TAG, "createCallInRoom : getConferenceUserRoom failed " + e.getMessage());
if (null != callback) {
callback.onMatrixError(e);
}
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "createCallInRoom : getConferenceUserRoom failed " + e.getMessage(), e);
if (null != callback) {
callback.onUnexpectedError(e);
}
}
});
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "createCallInRoom : inviteConferenceUser fails " + e.getMessage(), e);
if (null != callback) {
callback.onNetworkError(e);
}
}
@Override
public void onMatrixError(MatrixError e) {
Log.e(LOG_TAG, "createCallInRoom : inviteConferenceUser fails " + e.getMessage());
if (null != callback) {
callback.onMatrixError(e);
}
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "createCallInRoom : inviteConferenceUser fails " + e.getMessage(), e);
if (null != callback) {
callback.onUnexpectedError(e);
}
}
});
}
} else {
if (null != callback) {
callback.onMatrixError(new MatrixError(MatrixError.NOT_SUPPORTED, "too few users"));
}
}
} else {
if (null != callback) {
callback.onMatrixError(new MatrixError(MatrixError.NOT_SUPPORTED, "VOIP is not supported"));
}
}
} else {
if (null != callback) {
callback.onMatrixError(new MatrixError(MatrixError.NOT_FOUND, "room not found"));
}
}
}
use of org.matrix.androidsdk.core.model.MatrixError in project matrix-android-sdk by matrix-org.
the class MXCallsManager method checkPendingIncomingCalls.
/**
* check if there is a pending incoming call
*/
public void checkPendingIncomingCalls() {
// Log.d(LOG_TAG, "checkPendingIncomingCalls");
mUIThreadHandler.post(() -> {
if (mxPendingIncomingCallId.size() > 0) {
for (String callId : mxPendingIncomingCallId) {
final IMXCall call = getCallWithCallId(callId);
if (null != call) {
final Room room = call.getRoom();
// If there are some unknown devices, the answer event would not be encrypted.
if ((null != room) && room.isEncrypted() && mSession.getCrypto() != null && mSession.getCrypto().warnOnUnknownDevices() && room.getNumberOfJoinedMembers() == 2) {
// test if the encrypted events are sent only to the verified devices (any room)
mSession.getCrypto().getGlobalBlacklistUnverifiedDevices(new SimpleApiCallback<Boolean>() {
@Override
public void onSuccess(Boolean sendToVerifiedDevicesOnly) {
if (sendToVerifiedDevicesOnly) {
dispatchOnIncomingCall(call, null);
} else {
// test if the encrypted events are sent only to the verified devices (only this room)
mSession.getCrypto().isRoomBlacklistUnverifiedDevices(room.getRoomId(), new SimpleApiCallback<Boolean>() {
@Override
public void onSuccess(Boolean sendToVerifiedDevicesOnly) {
if (sendToVerifiedDevicesOnly) {
dispatchOnIncomingCall(call, null);
} else {
room.getJoinedMembersAsync(new ApiCallback<List<RoomMember>>() {
@Override
public void onNetworkError(Exception e) {
dispatchOnIncomingCall(call, null);
}
@Override
public void onMatrixError(MatrixError e) {
dispatchOnIncomingCall(call, null);
}
@Override
public void onUnexpectedError(Exception e) {
dispatchOnIncomingCall(call, null);
}
@Override
public void onSuccess(List<RoomMember> members) {
String userId1 = members.get(0).getUserId();
String userId2 = members.get(1).getUserId();
Log.d(LOG_TAG, "## checkPendingIncomingCalls() : check the unknown devices");
//
mSession.getCrypto().checkUnknownDevices(Arrays.asList(userId1, userId2), new ApiCallback<Void>() {
@Override
public void onSuccess(Void anything) {
Log.d(LOG_TAG, "## checkPendingIncomingCalls() : no unknown device");
dispatchOnIncomingCall(call, null);
}
@Override
public void onNetworkError(Exception e) {
Log.e(LOG_TAG, "## checkPendingIncomingCalls() : checkUnknownDevices failed " + e.getMessage(), e);
dispatchOnIncomingCall(call, null);
}
@Override
public void onMatrixError(MatrixError e) {
MXUsersDevicesMap<MXDeviceInfo> unknownDevices = null;
if (e instanceof MXCryptoError) {
MXCryptoError cryptoError = (MXCryptoError) e;
if (MXCryptoError.UNKNOWN_DEVICES_CODE.equals(cryptoError.errcode)) {
unknownDevices = (MXUsersDevicesMap<MXDeviceInfo>) cryptoError.mExceptionData;
}
}
if (null != unknownDevices) {
Log.d(LOG_TAG, "## checkPendingIncomingCalls() :" + " checkUnknownDevices found some unknown devices");
} else {
Log.e(LOG_TAG, "## checkPendingIncomingCalls() :" + " checkUnknownDevices failed " + e.getMessage());
}
dispatchOnIncomingCall(call, unknownDevices);
}
@Override
public void onUnexpectedError(Exception e) {
Log.e(LOG_TAG, "## checkPendingIncomingCalls() :" + " checkUnknownDevices failed " + e.getMessage(), e);
dispatchOnIncomingCall(call, null);
}
});
}
});
}
}
});
}
}
});
} else {
dispatchOnIncomingCall(call, null);
}
}
}
}
mxPendingIncomingCallId.clear();
});
}
Aggregations