package com.example.secretvault; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.media.AudioManager; import android.media.AudioTrack; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.widget.Toast; import com.connectycube.auth.session.ConnectycubeSettings; import com.connectycube.chat.ConnectycubeChatService; import com.connectycube.chat.Signaling; import com.connectycube.chat.WebRTCSignaling; import com.connectycube.chat.listeners.VideoChatSignalingManagerListener; import com.connectycube.users.model.ConnectycubeUser; import com.connectycube.videochat.AppRTCAudioManager; import com.connectycube.videochat.BaseSession; import com.connectycube.videochat.RTCAudioTrack; import com.connectycube.videochat.RTCCameraVideoCapturer; import com.connectycube.videochat.RTCClient; import com.connectycube.videochat.RTCConfig; import com.connectycube.videochat.RTCMediaConfig; import com.connectycube.videochat.RTCMediaStreamManager; import com.connectycube.videochat.RTCScreenCapturer; import com.connectycube.videochat.RTCSession; import com.connectycube.videochat.RTCTypes; import com.connectycube.videochat.RTCVideoCapturer; import com.connectycube.videochat.SignalingSpec; import com.connectycube.videochat.callbacks.RTCClientSessionCallbacks; import com.connectycube.videochat.callbacks.RTCSessionConnectionCallbacks; import com.connectycube.videochat.callbacks.RTCSessionEventsCallback; import com.connectycube.videochat.callbacks.RTCSignalingCallback; import com.connectycube.videochat.exception.RTCSignalException; import com.example.secretvault.Common.Common; import com.example.secretvault.Fragments.PreviewCallFragment; import com.example.secretvault.Fragments.VideoConversationFragment; import org.webrtc.CameraVideoCapturer; import org.webrtc.ContextUtils; import org.webrtc.MediaConstraints; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import static com.example.secretvault.Common.Common.EXTRA_CURRENT_SESSION; import static com.example.secretvault.Common.Common.EXTRA_IS_INCOMING_CALL; import static com.example.secretvault.Common.Common.EXTRA_USERS_LIST; import static com.example.secretvault.Common.Common.INCOMING; import static com.example.secretvault.Common.Common.MAX_OPPONENTS_COUNT; import static com.example.secretvault.Common.Common.PERMISSIONS_FOR_CALL_REQUEST; import static com.example.secretvault.Common.Common.REQUEST_CODE; import static com.example.secretvault.Common.Common.StartCall; import static com.example.secretvault.Common.Common.currentSession; public class CallActivity extends AppCompatActivity implements RTCClientSessionCallbacks, PreviewCallFragment.CallFragmentCallbackListener, VideoConversationFragment.CallFragmentCallbackListener, RTCSessionEventsCallback { ArrayList opponents; AppRTCAudioManager audioManager; RTCClient rtcClient; RTCSession currentSess = null; Boolean needToRestorePreviewFrag = false; final String APP_ID = "2088"; final String AUTH_KEY = "vP8VvE9AcX4Hxz7"; final String AUTH_SECRET = "ZFZScTR73gxHNnq"; final String ACCOUNT_KEY = "FSeNMpUQ-GTuz4SvgzXG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_call); ConnectycubeSettings.getInstance().init(getApplicationContext(),APP_ID,AUTH_KEY,AUTH_SECRET); ConnectycubeSettings.getInstance().setAccountKey(ACCOUNT_KEY); initFields(); initRTCClient(); initAudioManagerIfNeed(); initRingtoneManager(); checkCameraPermissionAndStart(); } private void initRingtoneManager() { } @Override protected void onStart() { super.onStart(); String incoming = getIntent().getStringExtra(INCOMING); if(StartCall.equals("true")){ startCall(); } if(incoming != null) { if (incoming.equals("true")) { onReceiveNewSession(currentSession); } } } private ArrayList getIdsOpponents(Collection selectedUsers) { ArrayList opponentsIds = new ArrayList<>(); if (!selectedUsers.isEmpty()) { for (ConnectycubeUser user : selectedUsers) { opponentsIds.add(user.getId()); } } return opponentsIds; } private void startCall() { if (opponents.size() > 4) { Toast.makeText(this, String.format("Max Group Limit", 4), Toast.LENGTH_LONG).show(); return; } ArrayList opponentsList = getIdsOpponents(opponents); RTCTypes.ConferenceType conferenceType = RTCTypes.ConferenceType.CONFERENCE_TYPE_VIDEO; RTCClient rtcClient = RTCClient.getInstance(ContextUtils.getApplicationContext()); RTCSession newRtcSession = rtcClient.createNewSessionWithOpponents(opponentsList, conferenceType); currentSession = newRtcSession; onStartCall(newRtcSession); } private void initAudioManagerIfNeed() { if (audioManager == null) { audioManager = AppRTCAudioManager.create(this); audioManager.updateAudioDeviceState(); audioManager.setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE); audioManager.setOnWiredHeadsetStateListener(new AppRTCAudioManager.OnWiredHeadsetStateListener() { @Override public void onWiredHeadsetStateChanged(boolean plugged, boolean hasMicrophone) { } }); } } private void startAudioManager() { //initAudioManagerIfNeed(); audioManager.start(new AppRTCAudioManager.AudioManagerEvents() { @Override public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice audioDevice, Set set) { updateAudioDevice(audioDevice); } }); } private void initFields() { opponents = (ArrayList)getIntent().getSerializableExtra(EXTRA_USERS_LIST); } private void initRTCClient() { rtcClient = RTCClient.getInstance(this); ConnectycubeChatService.getInstance().getVideoChatWebRTCSignalingManager().addSignalingManagerListener(new VideoChatSignalingManagerListener() { @Override public void signalingCreated(Signaling signaling, boolean createdLocally) { if(!createdLocally){ RTCClient.getInstance(CallActivity.this).addSignaling((WebRTCSignaling)signaling); } } }); // Configure // RTCConfig.setMaxOpponentsCount(MAX_OPPONENTS_COUNT); setSettingsForMultiCall(); RTCConfig.setDebugEnabled(true); // Add activity as callback to RTCClient rtcClient.addSessionCallbacksListener(this); // Start mange RTCSessions according to VideoCall parser's callbacks rtcClient.prepareToProcessCalls(); } private void setSettingsForMultiCall() { if (opponents.size() == 2) { RTCMediaConfig.setVideoWidth(RTCMediaConfig.VideoQuality.HD_VIDEO.width); RTCMediaConfig.setVideoHeight(RTCMediaConfig.VideoQuality.HD_VIDEO.height); } else { //set to minimum settings RTCMediaConfig.setVideoWidth(RTCMediaConfig.VideoQuality.QVGA_VIDEO.width); RTCMediaConfig.setVideoHeight(RTCMediaConfig.VideoQuality.QVGA_VIDEO.height); RTCMediaConfig.setVideoHWAcceleration(false); } } @Override protected void onResume() { super.onResume(); restorePreviewFragIfNeed(); } @Override public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); if (fragment.getTag().equals("VideoConversationFragment")){ if(currentSession == null){ getSupportFragmentManager().popBackStack(); }else{ VideoConversationFragment videoConversationFragment = (VideoConversationFragment)getSupportFragmentManager().findFragmentByTag("VideoConversationFragment"); videoConversationFragment.initSession(currentSession); //initCurrentSession(currentSession); } } } private void checkCameraPermissionAndStart() { if (!isCallPermissionsGranted()) { requestCameraPermission(); } else { initPreviewFragment(); } } private boolean isCallPermissionsGranted() { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; } private void requestCameraPermission() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PERMISSIONS_FOR_CALL_REQUEST); } private void initPreviewFragIfNeed() { if (!isCurrentPreviewCallFragment()) { if (isCallInForeground()) { initPreviewFragDelayed(); } else { needToRestorePreviewFrag = true; } } } private void restorePreviewFragIfNeed() { if (needToRestorePreviewFrag) { needToRestorePreviewFrag = false; initPreviewFragDelayed(); } } private void initPreviewFragDelayed() { //delay is for releasing Camera by webrtc Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { getSupportFragmentManager().popBackStack(); /*if (isCurrentScreenShareFragment()) initPreviewFragment(); else getSupportFragmentManager().popBackStack();*/ } },1000L); } private Boolean isCallInForeground() { //return isCurrentScreenShareFragment() || isCurrentVideoConversationFragment(); return isCurrentVideoConversationFragment(); } private Boolean isCurrentVideoConversationFragment(){ VideoConversationFragment frag = (VideoConversationFragment)getSupportFragmentManager().findFragmentByTag(VideoConversationFragment.class.getSimpleName()); return frag != null && frag.isVisible() && frag.isResumed(); } private Boolean isCurrentPreviewCallFragment() { PreviewCallFragment frag = (PreviewCallFragment)getSupportFragmentManager().findFragmentByTag(PreviewCallFragment.class.getSimpleName()); return frag != null && frag.isVisible(); } /* private Boolean isCurrentScreenShareFragment() { ScreenShareFragment frag = (ScreenShareFragment)getSupportFragmentManager().findFragmentByTag(ScreenShareFragment.class.getSimpleName()); return frag != null && frag.isVisible() && frag.isResumed(); }*/ private void initPreviewFragment() { PreviewCallFragment previewFragment = PreviewCallFragment.newInstance(opponents); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, previewFragment, PreviewCallFragment.class.getSimpleName()).addToBackStack(null).commit(); getSupportFragmentManager().executePendingTransactions(); } private void initConversationFragment(Boolean incoming) { VideoConversationFragment videoConversationFragment = VideoConversationFragment.newInstance(incoming,opponents); getSupportFragmentManager().beginTransaction().replace( R.id.fragment_container, videoConversationFragment, VideoConversationFragment.class.getSimpleName()).addToBackStack(null).commit(); getSupportFragmentManager().executePendingTransactions(); } private void updatePreviewCallButtons(Boolean show) { PreviewCallFragment previewFrag = (PreviewCallFragment) getSupportFragmentManager().findFragmentByTag(PreviewCallFragment.class.getSimpleName()); if (previewFrag != null) { previewFrag.updateCallButtons(show); } } private void updateAudioDevice(AppRTCAudioManager.AudioDevice audioDevice) { VideoConversationFragment videoFrag = (VideoConversationFragment) getSupportFragmentManager().findFragmentByTag(VideoConversationFragment.class.getSimpleName()); if (videoFrag != null) { videoFrag.audioDeviceChanged(audioDevice); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case REQUEST_CODE:{ if(grantResults[0] == PackageManager.PERMISSION_GRANTED) initPreviewFragment(); else Toast.makeText(getBaseContext(),"Permission Denied", Toast.LENGTH_SHORT).show(); } } } /* //For Screen Sharing @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RTCScreenCapturer.REQUEST_MEDIA_PROJECTION) { if (resultCode == Activity.RESULT_OK) { startScreenSharing(data); } else { Toast.makeText(getApplicationContext(), "You dont have access to Screen Sharing", Toast.LENGTH_SHORT).show(); } } }*/ private void showToastDeniedPermissions(ArrayList permissions) { Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_LONG).show(); } private void startLogout() { ConnectycubeChatService.getInstance().destroy(); } private void initCurrentSession(RTCSession session) { currentSess = session; currentSession = session; currentSession.addSignalingCallback(signalingCallback); } private void releaseCurrentSession() { if (currentSession != null) { currentSession.removeSignalingCallback(signalingCallback); currentSession = null; } } @Override protected void onDestroy() { super.onDestroy(); rtcClient.removeSessionsCallbacksListener(this); rtcClient.destroy(); } private void hangUpCurrentSession() { if (currentSession != null) { Log.d("", "hangUpCurrentSession currentSession != null"); currentSession.hangUp(new HashMap()); } } @Override public void onUserNoActions(RTCSession rtcSession, Integer integer) { } @Override public void onSessionStartClose(RTCSession rtcSession) { /* if (rtcSession == currentSession) { updatePreviewCallButtons(false); }*/ } @Override public void onReceiveNewSession(RTCSession rtcSession) { Toast.makeText(CallActivity.this,"CallActivity onReceive",Toast.LENGTH_LONG).show(); if (currentSess == null) { initCurrentSession(rtcSession); updatePreviewCallButtons(true); } else { rtcSession.rejectCall(null); } } @Override public void onUserNotAnswer(RTCSession rtcSession, Integer integer) { } @Override public void onCallRejectByUser(RTCSession rtcSession, Integer integer, Map map) { currentSession.rejectCall(null); } @Override public void onCallAcceptByUser(RTCSession rtcSession, Integer integer, Map map) { } private String getUserNameOrLogin(int userId){ for (ConnectycubeUser oppo : opponents){ if(oppo.getId() == userId){ return oppo.getLogin(); } } return ""; } @Override public void onReceiveHangUpFromUser(RTCSession rtcSession, Integer userId, Map map) { Toast.makeText(this, getString(R.string.text_status_hang_up), Toast.LENGTH_SHORT).show(); //Toast.makeText(this, "User " + getUserNameOrLogin(userId) + " " + getString(R.string.text_status_hang_up), Toast.LENGTH_SHORT).show(); } @Override public void onSessionClosed(RTCSession rtcSession) { if (rtcSession.equals(currentSession)) { if(audioManager != null) { audioManager.stop(); audioManager = null; } // releaseCurrentSession(); // initPreviewFragIfNeed(); if(Common.CurrentActivity.getLocalClassName().equals("ChatDialogsActivity")){ Intent intent = new Intent(CallActivity.this,ChatDialogsActivity.class); startActivity(intent); }else if(Common.CurrentActivity.getLocalClassName().equals("ChatMessageActivity")){ Intent intent = new Intent(CallActivity.this,ChatMessageActivity.class); intent.putExtra(Common.DIALOG_EXTRA,Common.CommonChatDialog); startActivity(intent); } } } RTCSignalingCallback signalingCallback = new RTCSignalingCallback() { @Override public void onSuccessSendingPacket(SignalingSpec.SignalCMD signalCMD, Integer integer) { Toast.makeText(getApplicationContext(), "Connected… " , Toast.LENGTH_SHORT).show(); } @Override public void onErrorSendingPacket(SignalingSpec.SignalCMD signalCMD, Integer integer, RTCSignalException e) { Toast.makeText(getApplicationContext(), "Disconnected… Please check your Internet connection! " + e.getMessage(), Toast.LENGTH_SHORT).show(); } }; @Override public void onStartCall(RTCSession session) { initCurrentSession(session); startAudioManager(); initConversationFragment(false); } @Override public void onAcceptCall() { startAudioManager(); initConversationFragment(true); } @Override public void onRejectCall() { currentSession.rejectCall(null); } @Override public void onLogout() { startLogout(); finish(); } @Override public void onHangUpCall() { hangUpCurrentSession(); } @Override public void onSwitchAudio() { if (audioManager.getSelectedAudioDevice() != AppRTCAudioManager.AudioDevice.SPEAKER_PHONE) { audioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE); } else { if (audioManager.getAudioDevices().contains(AppRTCAudioManager.AudioDevice.BLUETOOTH)) { audioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.BLUETOOTH); } else if (audioManager.getAudioDevices().contains(AppRTCAudioManager.AudioDevice.WIRED_HEADSET)) { audioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.WIRED_HEADSET); } else { audioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); } } } @Override public void onStartScreenSharing() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return; } RTCScreenCapturer.requestPermissions(CallActivity.this); } @Override public void onSwitchCamera(CameraVideoCapturer.CameraSwitchHandler cameraSwitchHandler) { } }