mListeners = new HashSet<>();
-
- public HeadsetConnectionReceiver() {
- }
-
- /**
- * @param context the application context
- * @return the shared instance
- */
- public static HeadsetConnectionReceiver getSharedInstance(Context context) {
- if (null == mSharedInstance) {
- mSharedInstance = new HeadsetConnectionReceiver();
- context.registerReceiver(mSharedInstance, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
- context.registerReceiver(mSharedInstance, new IntentFilter(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED));
- context.registerReceiver(mSharedInstance, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
- context.registerReceiver(mSharedInstance, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
- context.registerReceiver(mSharedInstance, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
- }
-
- return mSharedInstance;
- }
-
- /**
- * Add a listener.
- *
- * @param listener the listener to add.
- */
- public void addListener(OnHeadsetStatusUpdateListener listener) {
- synchronized (LOG_TAG) {
- mListeners.add(listener);
- }
- }
-
- /**
- * Remove a listener.
- *
- * @param listener the listener to remove.
- */
- public void removeListener(OnHeadsetStatusUpdateListener listener) {
- synchronized (LOG_TAG) {
- mListeners.remove(listener);
- }
- }
-
- /**
- * Dispatch onBluetoothHeadsetUpdate to the listeners.
- *
- * @param isConnected true if a bluetooth headset is connected.
- */
- private void onBluetoothHeadsetUpdate(boolean isConnected) {
- synchronized (LOG_TAG) {
- for (OnHeadsetStatusUpdateListener listener : mListeners) {
- try {
- listener.onBluetoothHeadsetUpdate(isConnected);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## onBluetoothHeadsetUpdate()) failed " + e.getMessage(), e);
- }
- }
- }
- }
-
- /**
- * Dispatch onWireHeadsetUpdate to the listeners.
- *
- * @param isPlugged true if the wire headset is plugged.
- */
- private void onWiredHeadsetUpdate(boolean isPlugged) {
- synchronized (LOG_TAG) {
- for (OnHeadsetStatusUpdateListener listener : mListeners) {
- try {
- listener.onWiredHeadsetUpdate(isPlugged);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## onWiredHeadsetUpdate()) failed " + e.getMessage(), e);
- }
- }
- }
- }
-
- @Override
- public void onReceive(final Context aContext, final Intent aIntent) {
- Log.d(LOG_TAG, "## onReceive() : " + aIntent.getExtras());
- String action = aIntent.getAction();
-
- if (TextUtils.equals(action, Intent.ACTION_HEADSET_PLUG)
- || TextUtils.equals(action, BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
- || TextUtils.equals(action, BluetoothAdapter.ACTION_STATE_CHANGED)
- || TextUtils.equals(action, BluetoothDevice.ACTION_ACL_CONNECTED)
- || TextUtils.equals(action, BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
-
- Boolean newState = null;
- final boolean isBTHeadsetUpdate;
-
- if (TextUtils.equals(action, Intent.ACTION_HEADSET_PLUG)) {
- int state = aIntent.getIntExtra("state", -1);
-
- switch (state) {
- case 0:
- Log.d(LOG_TAG, "Headset is unplugged");
- newState = false;
- break;
- case 1:
- Log.d(LOG_TAG, "Headset is plugged");
- newState = true;
- break;
- default:
- Log.d(LOG_TAG, "undefined state");
- }
- isBTHeadsetUpdate = false;
- } else {
- int state = BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET);
-
- Log.d(LOG_TAG, "bluetooth headset state " + state);
- newState = (BluetoothAdapter.STATE_CONNECTED == state);
- isBTHeadsetUpdate = mIsHeadsetPlugged != newState;
- }
-
- if (newState != mIsHeadsetPlugged) {
- mIsHeadsetPlugged = newState;
-
- // wait a little else route to BT headset does not work.
- new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
- @Override
- public void run() {
- if (isBTHeadsetUpdate) {
- onBluetoothHeadsetUpdate(mIsHeadsetPlugged);
- } else {
- onWiredHeadsetUpdate(mIsHeadsetPlugged);
- }
- }
- }, 1000);
- }
- }
- }
-
- private static AudioManager mAudioManager = null;
-
- /**
- * @return the audio manager
- */
- private static AudioManager getAudioManager(Context context) {
- if (null == mAudioManager) {
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- }
-
- return mAudioManager;
- }
-
-
- /**
- * @param context the context
- * @return true if the headset is plugged
- */
- @SuppressLint("Deprecation")
- public static boolean isHeadsetPlugged(Context context) {
- if (null == mIsHeadsetPlugged) {
- AudioManager audioManager = getAudioManager(context);
- mIsHeadsetPlugged = isBTHeadsetPlugged() || audioManager.isWiredHeadsetOn();
- }
-
- return mIsHeadsetPlugged;
- }
-
- /**
- * @return true if bluetooth headset is plugged
- */
- public static boolean isBTHeadsetPlugged() {
- return (BluetoothAdapter.STATE_CONNECTED == BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET));
- }
-}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCall.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCall.java
deleted file mode 100644
index a0a2c419..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCall.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import android.view.View;
-
-import com.google.gson.JsonObject;
-
-import im.vector.matrix.android.internal.legacy.MXSession;
-import im.vector.matrix.android.internal.legacy.data.Room;
-import im.vector.matrix.android.internal.legacy.rest.model.Event;
-
-/**
- * Audio/video call interface.
- * See {@link MXWebRtcCall} and {@link MXChromeCall}.
- */
-public interface IMXCall {
-
- // call ending use cases (see {@link #dispatchOnCallEnd}):
- int END_CALL_REASON_UNDEFINED = -1;
- /**
- * the callee has rejected the incoming call
- **/
- int END_CALL_REASON_PEER_HANG_UP = 0;
- /**
- * the callee has rejected the incoming call from another device
- **/
- int END_CALL_REASON_PEER_HANG_UP_ELSEWHERE = 1;
- /**
- * call ended by the local user himself
- **/
- int END_CALL_REASON_USER_HIMSELF = 2;
-
- // call state events
-
- // the call is an empty shell nothing has been initialized
- String CALL_STATE_CREATED = "IMXCall.CALL_STATE_CREATED";
-
- // the call view is creating and being inserting.
- String CALL_STATE_CREATING_CALL_VIEW = "IMXCall.CALL_STATE_CREATING_CALL_VIEW";
-
- // the call view is managed.
- // the call can start from now.
- String CALL_STATE_READY = "IMXCall.CALL_STATE_READY";
-
- // incoming/outgoing calls : initializing the local audio / video
- String CALL_STATE_WAIT_LOCAL_MEDIA = "IMXCall.CALL_STATE_WAIT_LOCAL_MEDIA";
-
- // incoming calls : the local media is retrieved
- String CALL_STATE_WAIT_CREATE_OFFER = "IMXCall.CALL_STATE_WAIT_CREATE_OFFER";
-
- // outgoing calls : the call invitation is sent
- String CALL_STATE_INVITE_SENT = "IMXCall.CALL_STATE_INVITE_SENT";
-
- // the device is ringing
- // incoming calls : after applying the incoming params
- // outgoing calls : after getting the m.call.invite echo
- String CALL_STATE_RINGING = "IMXCall.CALL_STATE_RINGING";
-
- // incoming calls : create the call answer
- String CALL_STATE_CREATE_ANSWER = "IMXCall.CALL_STATE_CREATE_ANSWER";
-
- // the call is connecting
- String CALL_STATE_CONNECTING = "IMXCall.CALL_STATE_CONNECTING";
-
- // the call is in progress
- String CALL_STATE_CONNECTED = "IMXCall.CALL_STATE_CONNECTED";
-
- // call is ended
- String CALL_STATE_ENDED = "IMXCall.CALL_STATE_ENDED";
-
- // error codes
- // cannot initialize the camera
- String CALL_ERROR_CAMERA_INIT_FAILED = "IMXCall.CALL_ERROR_CAMERA_INIT_FAILED";
-
- // cannot initialize the call.
- String CALL_ERROR_CALL_INIT_FAILED = "IMXCall.CALL_ERROR_CALL_INIT_FAILED";
-
- // ICE error
- String CALL_ERROR_ICE_FAILED = "IMXCall.CALL_ERROR_ICE_FAILED";
-
- // the user did not respond to the call.
- String CALL_ERROR_USER_NOT_RESPONDING = "IMXCall.CALL_ERROR_USER_NOT_RESPONDING";
-
- // creator
-
- /**
- * Create the callview
- */
- void createCallView();
-
- /**
- * The activity is paused.
- */
- void onPause();
-
- /**
- * The activity is resumed.
- */
- void onResume();
-
- // actions (must be done after dispatchOnViewReady()
-
- /**
- * Start a call.
- *
- * @param aLocalVideoPosition position of the local video attendee
- */
- void placeCall(VideoLayoutConfiguration aLocalVideoPosition);
-
- /**
- * Prepare a call reception.
- *
- * @param aCallInviteParams the invitation Event content
- * @param aCallId the call ID
- * @param aLocalVideoPosition position of the local video attendee
- */
- void prepareIncomingCall(JsonObject aCallInviteParams, String aCallId, VideoLayoutConfiguration aLocalVideoPosition);
-
- /**
- * The call has been detected as an incoming one.
- * The application launched the dedicated activity and expects to launch the incoming call.
- *
- * @param aLocalVideoPosition position of the local video attendee
- */
- void launchIncomingCall(VideoLayoutConfiguration aLocalVideoPosition);
-
- /**
- * The video will be displayed according to the values set in aConfigurationToApply.
- *
- * @param aConfigurationToApply the new position to be applied
- */
- void updateLocalVideoRendererPosition(VideoLayoutConfiguration aConfigurationToApply);
-
- // events thread
-
- /**
- * Manage the call events.
- *
- * @param event the call event.
- */
- void handleCallEvent(Event event);
-
- // user actions
-
- /**
- * The call is accepted.
- */
- void answer();
-
- /**
- * The call has been has answered on another device.
- */
- void onAnsweredElsewhere();
-
- /**
- * The call is hung up.
- *
- * @param reason the reason
- */
- void hangup(String reason);
-
- /**
- * Add a listener to the call manager.
- *
- * @param callListener the call listener
- */
- void addListener(IMXCallListener callListener);
-
- /**
- * Remove a listener from the call manager.
- *
- * @param callListener the call listener
- */
- void removeListener(IMXCallListener callListener);
-
- // getters / setters
-
- /**
- * @return the callId
- */
- String getCallId();
-
- /**
- * Set the callId
- *
- * @param callId the call id
- */
- void setCallId(String callId);
-
- /**
- * @return the linked room
- */
- Room getRoom();
-
- /**
- * Set the linked rooms (conference call)
- *
- * @param room the room
- * @param callSignalingRoom the call signaling room.
- */
- void setRooms(Room room, Room callSignalingRoom);
-
- /**
- * @return the call signaling room
- */
- Room getCallSignalingRoom();
-
- /**
- * @return the session
- */
- MXSession getSession();
-
- /**
- * @return true if the call is an incoming call.
- */
- boolean isIncoming();
-
- /**
- * Set the call type: video or voice
- *
- * @param isVideo true for video call, false for VoIP
- */
- void setIsVideo(boolean isVideo);
-
- /**
- * @return true if the call is a video call.
- */
- boolean isVideo();
-
- /**
- * Defines the call conference status
- *
- * @param isConference the conference status
- */
- void setIsConference(boolean isConference);
-
- /**
- * @return true if the call is a conference call.
- */
- boolean isConference();
-
- /**
- * @return the callstate (must be a CALL_STATE_XX value)
- */
- String getCallState();
-
- /**
- * @return the callView
- */
- View getCallView();
-
- /**
- * @return the callView visibility
- */
- int getVisibility();
-
- /**
- * Set the callview visibility
- *
- * @param visibility true to make the callview visible
- * @return true if the operation succeeds
- */
- boolean setVisibility(int visibility);
-
- /**
- * @return the call start time in ms since epoch, -1 if not defined.
- */
- long getCallStartTime();
-
- /**
- * @return the call elapsed time in seconds, -1 if not defined.
- */
- long getCallElapsedTime();
-
- /**
- * Switch between device cameras. The transmitted stream is modified
- * according to the new camera in use.
- * If the camera used in the video call is the front one, calling
- * switchRearFrontCamera(), will make the rear one to be used, and vice versa.
- * If only one camera is available, nothing is done.
- *
- * @return true if the switch succeed, false otherwise.
- */
- boolean switchRearFrontCamera();
-
- /**
- * Indicate if a camera switch was performed or not.
- * For some reason switching the camera from front to rear and
- * vice versa, could not be performed (ie. only one camera is available).
- *
- *
See {@link #switchRearFrontCamera()}.
- *
- * @return true if camera was switched, false otherwise
- */
- boolean isCameraSwitched();
-
- /**
- * Indicate if the device supports camera switching.
- *
See {@link #switchRearFrontCamera()}.
- *
- * @return true if switch camera is supported, false otherwise
- */
- boolean isSwitchCameraSupported();
-
- /**
- * Mute/Unmute the recording of the local video attendee. Set isVideoMuted
- * to true to enable the recording of the video, if set to false no recording
- * is performed.
- *
- * @param isVideoMuted true to mute the video recording, false to unmute
- */
- void muteVideoRecording(boolean isVideoMuted);
-
- /**
- * Return the recording mute status of the local video attendee.
- *
- *
See {@link #muteVideoRecording(boolean)}.
- *
- * @return true if video recording is muted, false otherwise
- */
- boolean isVideoRecordingMuted();
-}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallListener.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallListener.java
deleted file mode 100644
index fd88bad0..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallListener.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import android.view.View;
-
-/**
- * This class tracks the call update.
- */
-public interface IMXCallListener {
-
- /**
- * Called when the call state change
- *
- * @param state the new call state
- */
- void onStateDidChange(String state);
-
- /**
- * Called when the call fails.
- *
- * @param error the failure reason
- */
- void onCallError(String error);
-
- /**
- * The call view has been created.
- * It can be inserted in a custom parent view.
- *
- * @param callView the call view
- */
- void onCallViewCreated(View callView);
-
- /**
- * The call view has been inserted.
- * The call is ready to be started.
- * For an outgoing call, use placeCall().
- * For an incoming call, use launchIncomingCall().
- */
- void onReady();
-
- /**
- * The call was answered on another device.
- */
- void onCallAnsweredElsewhere();
-
- /**
- * Warn that the call is ended
- *
- * @param aReasonId the reason of the call ending
- */
- void onCallEnd(final int aReasonId);
-
- /**
- * The video preview size has been updated.
- *
- * @param width the new width (non scaled size)
- * @param height the new height (non scaled size)
- */
- void onPreviewSizeChanged(int width, int height);
-}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallsManagerListener.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallsManagerListener.java
deleted file mode 100644
index 72298f3a..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/IMXCallsManagerListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import im.vector.matrix.android.internal.legacy.crypto.data.MXDeviceInfo;
-import im.vector.matrix.android.internal.legacy.crypto.data.MXUsersDevicesMap;
-
-/**
- * This class manages the calls events.
- */
-public interface IMXCallsManagerListener {
- /**
- * Called when there is an incoming call within the room.
- *
- * @param call the incoming call
- * @param unknownDevices the unknown e2e devices list
- */
- void onIncomingCall(IMXCall call, MXUsersDevicesMap unknownDevices);
-
- /**
- * An outgoing call is started.
- *
- * @param call the outgoing call
- */
- void onOutgoingCall(IMXCall call);
-
- /**
- * Called when a called has been hung up
- *
- * @param call the incoming call
- */
- void onCallHangUp(IMXCall call);
-
- /**
- * A voip conference started in a room.
- *
- * @param roomId the room id
- */
- void onVoipConferenceStarted(String roomId);
-
- /**
- * A voip conference finished in a room.
- *
- * @param roomId the room id
- */
- void onVoipConferenceFinished(String roomId);
-}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java
deleted file mode 100644
index 4b87a3d7..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- * Copyright 2018 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import android.content.Context;
-import android.os.Handler;
-import android.text.TextUtils;
-import android.view.View;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Timer;
-
-import im.vector.matrix.android.internal.legacy.MXSession;
-import im.vector.matrix.android.internal.legacy.data.Room;
-import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback;
-import im.vector.matrix.android.internal.legacy.rest.model.Event;
-import im.vector.matrix.android.internal.legacy.rest.model.MatrixError;
-import im.vector.matrix.android.internal.legacy.util.Log;
-
-/**
- * This class is the default implementation
- */
-public class MXCall implements IMXCall {
- private static final String LOG_TAG = MXCall.class.getSimpleName();
-
- // defines the call timeout
- public static final int CALL_TIMEOUT_MS = 120 * 1000;
-
- /**
- * The session
- */
- protected MXSession mSession;
-
- /**
- * The context
- */
- protected Context mContext;
-
- /**
- * the turn servers
- */
- protected JsonElement mTurnServer;
-
- /**
- * The room in which the call is performed.
- */
- protected Room mCallingRoom;
-
- /**
- * The room in which the call events are sent.
- * It might differ from mCallingRoom if it is a conference call.
- * For a 1:1 call, it will be equal to mCallingRoom.
- */
- protected Room mCallSignalingRoom;
-
- /**
- * The call events listeners
- */
- private final Set mCallListeners = new HashSet<>();
-
- /**
- * the call id
- */
- protected String mCallId;
-
- /**
- * Tells if it is a video call
- */
- protected boolean mIsVideoCall = false;
-
- /**
- * Tells if it is an incoming call
- */
- protected boolean mIsIncoming = false;
-
- /**
- * Tells if it is a conference call.
- */
- private boolean mIsConference = false;
-
- /**
- * List of events to sends to mCallSignalingRoom
- */
- protected final List mPendingEvents = new ArrayList<>();
-
- /**
- * The sending eevent.
- */
- private Event mPendingEvent;
-
- /**
- * The not responding timer
- */
- protected Timer mCallTimeoutTimer;
-
- // call start time
- private long mStartTime = -1;
-
- // UI thread handler
- final Handler mUIThreadHandler = new Handler();
-
- /**
- * Create the call view
- */
- public void createCallView() {
- }
-
- /**
- * The activity is paused.
- */
- public void onPause() {
- }
-
- /**
- * The activity is resumed.
- */
- public void onResume() {
- }
-
- // actions (must be done after dispatchOnViewReady()
-
- /**
- * Start a call.
- */
- public void placeCall(VideoLayoutConfiguration aLocalVideoPosition) {
- }
-
- /**
- * Prepare a call reception.
- *
- * @param aCallInviteParams the invitation Event content
- * @param aCallId the call ID
- * @param aLocalVideoPosition position of the local video attendee
- */
- public void prepareIncomingCall(JsonObject aCallInviteParams, String aCallId, VideoLayoutConfiguration aLocalVideoPosition) {
- setIsIncoming(true);
- }
-
- /**
- * The call has been detected as an incoming one.
- * The application launched the dedicated activity and expects to launch the incoming call.
- *
- * @param aLocalVideoPosition position of the local video attendee
- */
- public void launchIncomingCall(VideoLayoutConfiguration aLocalVideoPosition) {
- }
-
- @Override
- public void updateLocalVideoRendererPosition(VideoLayoutConfiguration aLocalVideoPosition) {
- Log.w(LOG_TAG, "## updateLocalVideoRendererPosition(): not implemented");
- }
-
- @Override
- public boolean switchRearFrontCamera() {
- Log.w(LOG_TAG, "## switchRearFrontCamera(): not implemented");
- return false;
- }
-
- @Override
- public boolean isCameraSwitched() {
- Log.w(LOG_TAG, "## isCameraSwitched(): not implemented");
- return false;
- }
-
- @Override
- public boolean isSwitchCameraSupported() {
- Log.w(LOG_TAG, "## isSwitchCameraSupported(): not implemented");
- return false;
- }
- // events thread
-
- /**
- * Manage the call events.
- *
- * @param event the call event.
- */
- public void handleCallEvent(Event event) {
- }
-
- // user actions
-
- /**
- * The call is accepted.
- */
- public void answer() {
- }
-
- /**
- * The call has been has answered on another device.
- */
- public void onAnsweredElsewhere() {
-
- }
-
- /**
- * The call is hung up.
- */
- public void hangup(String reason) {
- }
-
- // getters / setters
-
- /**
- * @return the callId
- */
- public String getCallId() {
- return mCallId;
- }
-
- /**
- * Set the callId
- */
- public void setCallId(String callId) {
- mCallId = callId;
- }
-
- /**
- * @return the linked room
- */
- public Room getRoom() {
- return mCallingRoom;
- }
-
- /**
- * @return the call signaling room
- */
- public Room getCallSignalingRoom() {
- return mCallSignalingRoom;
- }
-
- /**
- * Set the linked rooms.
- *
- * @param room the room where the conference take place
- * @param callSignalingRoom the call signaling room.
- */
- public void setRooms(Room room, Room callSignalingRoom) {
- mCallingRoom = room;
- mCallSignalingRoom = callSignalingRoom;
- }
-
- /**
- * @return the session
- */
- public MXSession getSession() {
- return mSession;
- }
-
- /**
- * @return true if the call is an incoming call.
- */
- public boolean isIncoming() {
- return mIsIncoming;
- }
-
- /**
- * @param isIncoming true if the call is an incoming one.
- */
- private void setIsIncoming(boolean isIncoming) {
- mIsIncoming = isIncoming;
- }
-
- /**
- * Defines the call type
- */
- public void setIsVideo(boolean isVideo) {
- mIsVideoCall = isVideo;
- }
-
- /**
- * @return true if the call is a video call.
- */
- public boolean isVideo() {
- return mIsVideoCall;
- }
-
- /**
- * Defines the call conference status
- */
- public void setIsConference(boolean isConference) {
- mIsConference = isConference;
- }
-
- /**
- * @return true if the call is a conference call.
- */
- public boolean isConference() {
- return mIsConference;
- }
-
- /**
- * @return the callstate (must be a CALL_STATE_XX value)
- */
- public String getCallState() {
- return null;
- }
-
- /**
- * @return the callView
- */
- public View getCallView() {
- return null;
- }
-
- /**
- * @return the callView visibility
- */
- public int getVisibility() {
- return View.GONE;
- }
-
- /**
- * Set the callview visibility
- *
- * @return true if the operation succeeds
- */
- public boolean setVisibility(int visibility) {
- return false;
- }
-
- /**
- * @return if the call is ended.
- */
- public boolean isCallEnded() {
- return TextUtils.equals(CALL_STATE_ENDED, getCallState());
- }
-
- /**
- * @return the call start time in ms since epoch, -1 if not defined.
- */
- public long getCallStartTime() {
- return mStartTime;
- }
-
- /**
- * @return the call elapsed time in seconds, -1 if not defined.
- */
- public long getCallElapsedTime() {
- if (-1 == mStartTime) {
- return -1;
- }
-
- return (System.currentTimeMillis() - mStartTime) / 1000;
- }
-
- //==============================================================================================================
- // call events listener
- //==============================================================================================================
-
- /**
- * Add a listener.
- *
- * @param callListener the listener to add
- */
- public void addListener(IMXCallListener callListener) {
- if (null != callListener) {
- synchronized (LOG_TAG) {
- mCallListeners.add(callListener);
- }
- }
- }
-
- /**
- * Remove a listener
- *
- * @param callListener the listener to remove
- */
- public void removeListener(IMXCallListener callListener) {
- if (null != callListener) {
- synchronized (LOG_TAG) {
- mCallListeners.remove(callListener);
- }
- }
- }
-
- /**
- * Remove the listeners
- */
- public void clearListeners() {
- synchronized (LOG_TAG) {
- mCallListeners.clear();
- }
- }
-
- /**
- * @return the call listeners
- */
- private Collection getCallListeners() {
- Collection listeners;
-
- synchronized (LOG_TAG) {
- listeners = new HashSet<>(mCallListeners);
- }
-
- return listeners;
- }
-
- /**
- * Dispatch the onCallViewCreated event to the listeners.
- *
- * @param callView the call view
- */
- protected void dispatchOnCallViewCreated(View callView) {
- if (isCallEnded()) {
- Log.d(LOG_TAG, "## dispatchOnCallViewCreated(): the call is ended");
- return;
- }
-
- Log.d(LOG_TAG, "## dispatchOnCallViewCreated()");
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onCallViewCreated(callView);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnCallViewCreated(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Dispatch the onViewReady event to the listeners.
- */
- protected void dispatchOnReady() {
- if (isCallEnded()) {
- Log.d(LOG_TAG, "## dispatchOnReady() : the call is ended");
- return;
- }
-
- Log.d(LOG_TAG, "## dispatchOnReady()");
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onReady();
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnReady(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Dispatch the onCallError event to the listeners.
- *
- * @param error error message
- */
- protected void dispatchOnCallError(String error) {
- if (isCallEnded()) {
- Log.d(LOG_TAG, "## dispatchOnCallError() : the call is ended");
- return;
- }
-
- Log.d(LOG_TAG, "## dispatchOnCallError()");
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onCallError(error);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnCallError(): " + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Dispatch the onStateDidChange event to the listeners.
- *
- * @param newState the new state
- */
- protected void dispatchOnStateDidChange(String newState) {
- Log.d(LOG_TAG, "## dispatchOnCallErrorOnStateDidChange(): " + newState);
-
- // set the call start time
- if (TextUtils.equals(CALL_STATE_CONNECTED, newState) && (-1 == mStartTime)) {
- mStartTime = System.currentTimeMillis();
- }
-
- // the call is ended.
- if (TextUtils.equals(CALL_STATE_ENDED, newState)) {
- mStartTime = -1;
- }
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onStateDidChange(newState);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnStateDidChange(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Dispatch the onCallAnsweredElsewhere event to the listeners.
- */
- protected void dispatchAnsweredElsewhere() {
- Log.d(LOG_TAG, "## dispatchAnsweredElsewhere()");
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onCallAnsweredElsewhere();
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchAnsweredElsewhere(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Dispatch the onCallEnd event to the listeners.
- *
- * @param aEndCallReasonId the reason of the call ending
- */
- protected void dispatchOnCallEnd(int aEndCallReasonId) {
- Log.d(LOG_TAG, "## dispatchOnCallEnd(): endReason=" + aEndCallReasonId);
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onCallEnd(aEndCallReasonId);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnCallEnd(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * Send the next pending events
- */
- protected void sendNextEvent() {
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- // do not send any new message
- if (isCallEnded() && (null != mPendingEvents)) {
- mPendingEvents.clear();
- }
-
- // ready to send
- if ((null == mPendingEvent) && (0 != mPendingEvents.size())) {
- mPendingEvent = mPendingEvents.get(0);
- mPendingEvents.remove(mPendingEvent);
-
- Log.d(LOG_TAG, "## sendNextEvent() : sending event of type " + mPendingEvent.getType() + " event id " + mPendingEvent.eventId);
- mCallSignalingRoom.sendEvent(mPendingEvent, new ApiCallback() {
- @Override
- public void onSuccess(Void info) {
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- Log.d(LOG_TAG, "## sendNextEvent() : event " + mPendingEvent.eventId + " is sent");
-
- mPendingEvent = null;
- sendNextEvent();
- }
- });
- }
-
- private void commonFailure(String reason) {
- Log.d(LOG_TAG, "## sendNextEvent() : event " + mPendingEvent.eventId + " failed to be sent " + reason);
-
- // let try next candidate event
- if (TextUtils.equals(mPendingEvent.getType(), Event.EVENT_TYPE_CALL_CANDIDATES)) {
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- mPendingEvent = null;
- sendNextEvent();
- }
- });
- } else {
- hangup(reason);
- }
- }
-
- @Override
- public void onNetworkError(Exception e) {
- commonFailure(e.getLocalizedMessage());
- }
-
- @Override
- public void onMatrixError(MatrixError e) {
- commonFailure(e.getLocalizedMessage());
- }
-
- @Override
- public void onUnexpectedError(Exception e) {
- commonFailure(e.getLocalizedMessage());
- }
- });
- }
- }
- });
- }
-
- /**
- * Dispatch the onPreviewSizeChanged event to the listeners.
- *
- * @param width the preview width
- * @param height the preview height
- */
- protected void dispatchOnPreviewSizeChanged(int width, int height) {
- Log.d(LOG_TAG, "## dispatchOnPreviewSizeChanged(): width =" + width + " - height =" + height);
-
- Collection listeners = getCallListeners();
-
- for (IMXCallListener listener : listeners) {
- try {
- listener.onPreviewSizeChanged(width, height);
- } catch (Exception e) {
- Log.e(LOG_TAG, "## dispatchOnPreviewSizeChanged(): Exception Msg=" + e.getMessage(), e);
- }
- }
- }
-
- /**
- * 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().getUserId(), mCallSignalingRoom.getRoomId());
-
- // local notification to indicate the end of call
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- 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() {
- @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);
- }
- });
- }
-
- @Override
- public void muteVideoRecording(boolean isVideoMuted) {
- Log.w(LOG_TAG, "## muteVideoRecording(): not implemented");
- }
-
- @Override
- public boolean isVideoRecordingMuted() {
- Log.w(LOG_TAG, "## muteVideoRecording(): not implemented - default value = false");
- return false;
- }
-}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallListener.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallListener.java
deleted file mode 100644
index 53dd5f37..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallListener.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import android.view.View;
-
-/**
- * This class is the default implementation of IMXCallListener.
- */
-public class MXCallListener implements IMXCallListener {
-
- @Override
- public void onStateDidChange(String state) {
- }
-
- @Override
- public void onCallError(String error) {
- }
-
- @Override
- public void onCallViewCreated(View callView) {
- }
-
- @Override
- public void onReady() {
- }
-
- @Override
- public void onCallAnsweredElsewhere() {
- }
-
- @Override
- public void onCallEnd(final int aReasonId) {
- }
-
- @Override
- public void onPreviewSizeChanged(int width, int height) {
- }
-}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallsManager.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallsManager.java
deleted file mode 100644
index 1d99f693..00000000
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCallsManager.java
+++ /dev/null
@@ -1,1295 +0,0 @@
-/*
- * Copyright 2015 OpenMarket Ltd
- * Copyright 2017 Vector Creations Ltd
- * Copyright 2018 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.matrix.android.internal.legacy.call;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.text.TextUtils;
-import android.util.Base64;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-import im.vector.matrix.android.internal.legacy.MXPatterns;
-import im.vector.matrix.android.internal.legacy.MXSession;
-import im.vector.matrix.android.internal.legacy.crypto.MXCryptoError;
-import im.vector.matrix.android.internal.legacy.crypto.data.MXDeviceInfo;
-import im.vector.matrix.android.internal.legacy.crypto.data.MXUsersDevicesMap;
-import im.vector.matrix.android.internal.legacy.data.Room;
-import im.vector.matrix.android.internal.legacy.data.RoomState;
-import im.vector.matrix.android.internal.legacy.data.store.IMXStore;
-import im.vector.matrix.android.internal.legacy.listeners.MXEventListener;
-import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback;
-import im.vector.matrix.android.internal.legacy.rest.callback.SimpleApiCallback;
-import im.vector.matrix.android.internal.legacy.rest.client.CallRestClient;
-import im.vector.matrix.android.internal.legacy.rest.model.CreateRoomParams;
-import im.vector.matrix.android.internal.legacy.rest.model.Event;
-import im.vector.matrix.android.internal.legacy.rest.model.EventContent;
-import im.vector.matrix.android.internal.legacy.rest.model.MatrixError;
-import im.vector.matrix.android.internal.legacy.rest.model.RoomMember;
-import im.vector.matrix.android.internal.legacy.util.JsonUtils;
-import im.vector.matrix.android.internal.legacy.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-
-public class MXCallsManager {
- private static final String LOG_TAG = MXCallsManager.class.getSimpleName();
-
- /**
- * Defines the call classes.
- */
- public enum CallClass {
- // disabled because of https://github.com/vector-im/riot-android/issues/1660
- //CHROME_CLASS,
- WEBRTC_CLASS,
- DEFAULT_CLASS
- }
-
- private MXSession mSession = null;
- private Context mContext = null;
-
- private CallRestClient mCallResClient = null;
- private JsonElement mTurnServer = null;
- private Timer mTurnServerTimer = null;
- private boolean mSuspendTurnServerRefresh = false;
-
- private CallClass mPreferredCallClass = CallClass.WEBRTC_CLASS;
-
- // active calls
- private final Map mCallsByCallId = new HashMap<>();
-
- // listeners
- private final Set mListeners = new HashSet<>();
-
- // incoming calls
- private final Set mxPendingIncomingCallId = new HashSet<>();
-
- // UI handler
- private final Handler mUIThreadHandler;
-
- /**
- * To create an outgoing call
- * 1- CallsManager.createCallInRoom()
- * 2- on success, IMXCall.createCallView
- * 3- IMXCallListener.onCallViewCreated(callview) -> insert the callview
- * 4- IMXCallListener.onCallReady() -> IMXCall.placeCall()
- * 5- the call states should follow theses steps
- * CALL_STATE_WAIT_LOCAL_MEDIA
- * CALL_STATE_WAIT_CREATE_OFFER
- * CALL_STATE_INVITE_SENT
- * CALL_STATE_RINGING
- * 6- the callee accepts the call
- * CALL_STATE_CONNECTING
- * CALL_STATE_CONNECTED
- *
- * To manage an incoming call
- * 1- IMXCall.createCallView
- * 2- IMXCallListener.onCallViewCreated(callview) -> insert the callview
- * 3- IMXCallListener.onCallReady(), IMXCall.launchIncomingCall()
- * 4- the call states should follow theses steps
- * CALL_STATE_WAIT_LOCAL_MEDIA
- * CALL_STATE_RINGING
- * 5- The user accepts the call, IMXCall.answer()
- * 6- the states should be
- * CALL_STATE_CREATE_ANSWER
- * CALL_STATE_CONNECTING
- * CALL_STATE_CONNECTED
- */
-
- /**
- * Constructor
- *
- * @param session the session
- * @param context the context
- */
- public MXCallsManager(MXSession session, Context context) {
- mSession = session;
- mContext = context;
-
- mUIThreadHandler = new Handler(Looper.getMainLooper());
-
- mCallResClient = mSession.getCallRestClient();
-
- mSession.getDataHandler().addListener(new MXEventListener() {
- @Override
- public void onLiveEvent(Event event, RoomState roomState) {
- if (TextUtils.equals(event.getType(), Event.EVENT_TYPE_STATE_ROOM_MEMBER)) {
- // Listen to the membership join/leave events to detect the conference user activity.
- // This mechanism detects the presence of an established conf call
- if (TextUtils.equals(event.sender, MXCallsManager.getConferenceUserId(event.roomId))) {
- EventContent eventContent = JsonUtils.toEventContent(event.getContentAsJsonObject());
-
- if (TextUtils.equals(eventContent.membership, RoomMember.MEMBERSHIP_LEAVE)) {
- dispatchOnVoipConferenceFinished(event.roomId);
- }
- if (TextUtils.equals(eventContent.membership, RoomMember.MEMBERSHIP_JOIN)) {
- dispatchOnVoipConferenceStarted(event.roomId);
- }
- }
- }
- }
- });
-
- refreshTurnServer();
- }
-
- /**
- * @return true if the call feature is supported
- */
- public boolean isSupported() {
- return /*MXChromeCall.isSupported() || */ MXWebRtcCall.isSupported(mContext);
- }
-
- /**
- * @return the list of supported classes
- */
- public Collection supportedClass() {
- List list = new ArrayList<>();
-
- /*if (MXChromeCall.isSupported()) {
- list.add(CallClass.CHROME_CLASS);
- }*/
-
- if (MXWebRtcCall.isSupported(mContext)) {
- list.add(CallClass.WEBRTC_CLASS);
- }
-
- Log.d(LOG_TAG, "supportedClass " + list);
-
- return list;
- }
-
- /**
- * @param callClass set the default callClass
- */
- public void setDefaultCallClass(CallClass callClass) {
- Log.d(LOG_TAG, "setDefaultCallClass " + callClass);
-
- boolean isUpdatable = false;
-
- /*if (callClass == CallClass.CHROME_CLASS) {
- isUpdatable = MXChromeCall.isSupported();
- }*/
-
- if (callClass == CallClass.WEBRTC_CLASS) {
- isUpdatable = MXWebRtcCall.isSupported(mContext);
- }
-
- if (isUpdatable) {
- mPreferredCallClass = callClass;
- }
- }
-
- /**
- * create a new call
- *
- * @param callId the call Id (null to use a default value)
- * @return the IMXCall
- */
- private IMXCall createCall(String callId) {
- Log.d(LOG_TAG, "createCall " + callId);
-
- IMXCall call = null;
-
- // default
- /*if (((CallClass.CHROME_CLASS == mPreferredCallClass) || (CallClass.DEFAULT_CLASS == mPreferredCallClass)) && MXChromeCall.isSupported()) {
- call = new MXChromeCall(mSession, mContext, getTurnServer());
- }*/
-
- // webrtc
- if (null == call) {
- try {
- call = new MXWebRtcCall(mSession, mContext, getTurnServer());
- } catch (Exception e) {
- Log.e(LOG_TAG, "createCall " + e.getMessage(), e);
- }
- }
-
- // a valid callid is provided
- if (null != callId) {
- call.setCallId(callId);
- }
-
- return call;
- }
-
- /**
- * Search a call from its dedicated room id.
- *
- * @param roomId the room id
- * @return the IMXCall if it exists
- */
- public IMXCall getCallWithRoomId(String roomId) {
- List calls;
-
- synchronized (this) {
- calls = new ArrayList<>(mCallsByCallId.values());
- }
-
- for (IMXCall call : calls) {
- if (TextUtils.equals(roomId, call.getRoom().getRoomId())) {
- if (TextUtils.equals(call.getCallState(), IMXCall.CALL_STATE_ENDED)) {
- Log.d(LOG_TAG, "## getCallWithRoomId() : the call " + call.getCallId() + " has been stopped");
- synchronized (this) {
- mCallsByCallId.remove(call.getCallId());
- }
- } else {
- return call;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Returns the IMXCall from its callId.
- *
- * @param callId the call Id
- * @return the IMXCall if it exists
- */
- public IMXCall getCallWithCallId(String callId) {
- return getCallWithCallId(callId, false);
- }
-
- /**
- * Returns the IMXCall from its callId.
- *
- * @param callId the call Id
- * @param create create the IMXCall if it does not exist
- * @return the IMXCall if it exists
- */
- private IMXCall getCallWithCallId(String callId, boolean create) {
- IMXCall call = null;
-
- // check if the call exists
- if (null != callId) {
- synchronized (this) {
- call = mCallsByCallId.get(callId);
- }
- }
-
- // test if the call has been stopped
- if ((null != call) && TextUtils.equals(call.getCallState(), IMXCall.CALL_STATE_ENDED)) {
- Log.d(LOG_TAG, "## getCallWithCallId() : the call " + callId + " has been stopped");
- synchronized (this) {
- mCallsByCallId.remove(call.getCallId());
- }
-
- call = null;
- }
-
- // the call does not exist but request to create it
- if ((null == call) && create) {
- call = createCall(callId);
- synchronized (this) {
- mCallsByCallId.put(call.getCallId(), call);
- }
- }
-
- Log.d(LOG_TAG, "getCallWithCallId " + callId + " " + call);
-
- return call;
- }
-
- /**
- * Tell if a call is in progress.
- *
- * @param call the call
- * @return true if the call is in progress
- */
- public static boolean isCallInProgress(IMXCall call) {
- boolean res = false;
-
- if (null != call) {
- String callState = call.getCallState();
- res = TextUtils.equals(callState, IMXCall.CALL_STATE_CREATED)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_CREATING_CALL_VIEW)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_READY)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_WAIT_LOCAL_MEDIA)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_WAIT_CREATE_OFFER)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_INVITE_SENT)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_RINGING)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_CREATE_ANSWER)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_CONNECTING)
- || TextUtils.equals(callState, IMXCall.CALL_STATE_CONNECTED);
- }
-
- return res;
- }
-
- /**
- * @return true if there are some active calls.
- */
- public boolean hasActiveCalls() {
- synchronized (this) {
- List callIdsToRemove = new ArrayList<>();
-
- Set callIds = mCallsByCallId.keySet();
-
- for (String callId : callIds) {
- IMXCall call = mCallsByCallId.get(callId);
-
- if (TextUtils.equals(call.getCallState(), IMXCall.CALL_STATE_ENDED)) {
- Log.d(LOG_TAG, "# hasActiveCalls() : the call " + callId + " is not anymore valid");
- callIdsToRemove.add(callId);
- } else {
- Log.d(LOG_TAG, "# hasActiveCalls() : the call " + callId + " is active");
- return true;
- }
- }
-
- for (String callIdToRemove : callIdsToRemove) {
- mCallsByCallId.remove(callIdToRemove);
- }
- }
-
- Log.d(LOG_TAG, "# hasActiveCalls() : no active call");
- return false;
- }
-
- /**
- * Manage the call events.
- *
- * @param store the dedicated store
- * @param event the call event.
- */
- public void handleCallEvent(final IMXStore store, final Event event) {
- if (event.isCallEvent() && isSupported()) {
- Log.d(LOG_TAG, "handleCallEvent " + event.getType());
-
- // always run the call event in the UI thread
- // MXChromeCall does not work properly in other thread (because of the webview)
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- boolean isMyEvent = TextUtils.equals(event.getSender(), mSession.getMyUserId());
- Room room = mSession.getDataHandler().getRoom(store, event.roomId, true);
-
- String callId = null;
- JsonObject eventContent = null;
-
- try {
- eventContent = event.getContentAsJsonObject();
- callId = eventContent.getAsJsonPrimitive("call_id").getAsString();
- } catch (Exception e) {
- Log.e(LOG_TAG, "handleCallEvent : fail to retrieve call_id " + e.getMessage(), e);
- }
- // sanity check
- if ((null != callId) && (null != room)) {
- // receive an invitation
- if (Event.EVENT_TYPE_CALL_INVITE.equals(event.getType())) {
- long lifeTime = event.getAge();
-
- if (Long.MAX_VALUE == lifeTime) {
- lifeTime = System.currentTimeMillis() - event.getOriginServerTs();
- }
-
- // ignore older call messages
- if (lifeTime < MXCall.CALL_TIMEOUT_MS) {
- // create the call only it is triggered from someone else
- IMXCall call = getCallWithCallId(callId, !isMyEvent);
-
- // sanity check
- if (null != call) {
- // init the information
- if (null == call.getRoom()) {
- call.setRooms(room, room);
- }
-
- if (!isMyEvent) {
- call.prepareIncomingCall(eventContent, callId, null);
- mxPendingIncomingCallId.add(callId);
- } else {
- call.handleCallEvent(event);
- }
- }
- } else {
- Log.d(LOG_TAG, "## handleCallEvent() : " + Event.EVENT_TYPE_CALL_INVITE + " is ignored because it is too old");
- }
- } else if (Event.EVENT_TYPE_CALL_CANDIDATES.equals(event.getType())) {
- if (!isMyEvent) {
- IMXCall call = getCallWithCallId(callId);
-
- if (null != call) {
- if (null == call.getRoom()) {
- call.setRooms(room, room);
- }
- call.handleCallEvent(event);
- }
- }
- } else if (Event.EVENT_TYPE_CALL_ANSWER.equals(event.getType())) {
- IMXCall call = getCallWithCallId(callId);
-
- if (null != call) {
- // assume it is a catch up call.
- // the creation / candidates /
- // the call has been answered on another device
- if (IMXCall.CALL_STATE_CREATED.equals(call.getCallState())) {
- call.onAnsweredElsewhere();
- synchronized (this) {
- mCallsByCallId.remove(callId);
- }
- } else {
- if (null == call.getRoom()) {
- call.setRooms(room, room);
- }
- call.handleCallEvent(event);
- }
- }
- } else if (Event.EVENT_TYPE_CALL_HANGUP.equals(event.getType())) {
- final IMXCall call = getCallWithCallId(callId);
- if (null != call) {
- // trigger call events only if the call is active
- final boolean isActiveCall = !IMXCall.CALL_STATE_CREATED.equals(call.getCallState());
-
- if (null == call.getRoom()) {
- call.setRooms(room, room);
- }
-
- if (isActiveCall) {
- call.handleCallEvent(event);
- }
-
- synchronized (this) {
- mCallsByCallId.remove(callId);
- }
-
- // warn that a call has been hung up
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- // must warn anyway any listener that the call has been killed
- // for example, when the device is in locked screen
- // the callview is not created but the device is ringing
- // if the other participant ends the call, the ring should stop
- dispatchOnCallHangUp(call);
- }
- });
- }
- }
- }
- }
- });
- }
- }
-
- /**
- * check if there is a pending incoming call
- */
- public void checkPendingIncomingCalls() {
- //Log.d(LOG_TAG, "checkPendingIncomingCalls");
-
- mUIThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mxPendingIncomingCallId.size() > 0) {
- for (String callId : mxPendingIncomingCallId) {
- final IMXCall call = getCallWithCallId(callId);
-
- if (null != call) {
- final Room room = call.getRoom();
-
- // for encrypted rooms with 2 members
- // check if there are some unknown devices before warning
- // of the incoming call.
- // If there are some unknown devices, the answer event would not be encrypted.
- if ((null != room)
- && room.isEncrypted()
- && 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() {
- @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() {
- @Override
- public void onSuccess(Boolean sendToVerifiedDevicesOnly) {
- if (sendToVerifiedDevicesOnly) {
- dispatchOnIncomingCall(call, null);
- } else {
- room.getJoinedMembersAsync(new ApiCallback