package com.ecv.activity; import android.app.ActivityManager; import android.app.Dialog; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.graphics.Point; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.LinearLayout; import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.LifecycleOwner; import com.ecv.fragment.CallFragment; import com.ecv.R; import org.webrtc.Logging; import org.webrtc.RendererCommon; import org.webrtc.SurfaceViewRenderer; import java.util.List; import group.ccr.ecv.sdk.EventCallback; import group.ccr.ecv.sdk.videoCall.VideoCall; import group.ccr.ecv.sdk.videoCall.events.CallEventTypes; import group.ccr.ecv.sdk.videoCall.events.VideoCallEvent; import utils.Constant; public class MQVideoActivity extends AppCompatActivity { private static final String TAG = "SDKCallActivity"; public static MQVideoActivity Current; private static final int CAPTURE_PERMISSION_REQUEST_CODE = 1; private static final String[] MANDATORY_PERMISSIONS = {"android.permission.MODIFY_AUDIO_SETTINGS", "android.permission.RECORD_AUDIO", "android.permission.INTERNET", android.Manifest.permission.CAMERA}; private Fragment callFragment; private boolean isScreenCapturing; private Intent startIntent; public String roomId; Animation fadeout2; Animation fadein; Animation localslide; Animation localslidereverse; Animation buttonslide; Animation buttonslidereverse; public static SurfaceViewRenderer pip_video_view; static SurfaceViewRenderer fullscreen_video_view; Button microfoneControl; Boolean microfoneControlState = true; Boolean localCameraControlState = true; Button localCameraControl; RelativeLayout addBackroundForAgentMediaMute; public int mainScreenWidth; public int mainScreenHeight; boolean holdControl = false; Dialog holdDialog; Button btnHangout; LinearLayout containerHold; Context context; public void stopActivityInternal() { ActivityManager mgr = (ActivityManager) getSystemService(ACTIVITY_SERVICE); List taskList = mgr.getRunningTasks(10); finish(); if (taskList.get(0).numActivities == 1) { Intent intent = new Intent(this, MainActivity.class); startActivity(intent); } } public SurfaceViewRenderer getSmallView() { return (SurfaceViewRenderer) findViewById(R.id.localUserPreview); } public SurfaceViewRenderer getLargeView() { return (SurfaceViewRenderer) findViewById(R.id.remoteUserPreview); } void startCall() { Intent intent = startIntent; Bundle bundle = intent.getExtras(); roomId = bundle.getString("EXTRA_ROOMID"); Log.d(TAG, "Room ID: " + roomId); if (roomId == null || roomId.isEmpty()) { Log.e(TAG, "Incorrect room ID in intent!"); setResult(RESULT_CANCELED); stopActivityInternal(); return; } videoCall = Constant.sdkInstance.getVideoCall(roomId); if (videoCall != null && videoCall.getWebRtcConnection() != null) { pip_video_view.init(videoCall.getWebRtcConnection().getEglBase().getEglBaseContext(), null); fullscreen_video_view.init(videoCall.getWebRtcConnection().getEglBase().getEglBaseContext(), null); } else { Log.e(TAG, "WebRtcConnection is null. Cannot initialize renderers."); finish(); return; } videoCall.subscribe((LifecycleOwner) this, new EventCallback() { @Override public void onEvent(@NonNull VideoCallEvent videoCallEvent) { runOnUiThread(() -> { if (videoCallEvent.getType() == CallEventTypes.TakePhotoOn) { SwapView(false); } if (videoCallEvent.getType() == CallEventTypes.TakePhotoOff) { SwapView(true); } if (videoCallEvent.getType() == CallEventTypes.StartHold) { holdControl = true; holdDialog(true); } if (videoCallEvent.getType() == CallEventTypes.EndHold) { holdControl = false; holdDialog(false); } }); } }); videoCall.getWebRtcConnection().startRoom(this); getSmallView().setZOrderMediaOverlay(true); SwapView(true); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(R.id.call_fragment_container, callFragment); ft.commit(); } private static int getSystemUiVisibility() { int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; return flags; } @Override public void onBackPressed() { if (videoCall != null) videoCall.hangup(); stopActivityInternal(); super.onBackPressed(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); getWindow().getDecorView().setSystemUiVisibility(getSystemUiVisibility()); this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.activity_mqvideo); context = this; prepareHoldDialog(); MQVideoActivity.Current = this; pip_video_view = findViewById(R.id.localUserPreview); fullscreen_video_view = findViewById(R.id.remoteUserPreview); // This line was removed because the default state is non-mirrored remote view. Mirroring is now handled in SwapView. // fullscreen_video_view.setMirror(true); fullscreen_video_view.setEnableHardwareScaler(true); fullscreen_video_view.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL); microfoneControl = findViewById(R.id.microfoneControl); microfoneControl.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (videoCall.getWebRtcConnection() == null) return; if (microfoneControlState) { videoCall.getWebRtcConnection().setAudioEnabled(false, false); microfoneControlState = false; microfoneControl.setBackgroundResource(R.drawable.icn_micmute); } else { videoCall.getWebRtcConnection().setAudioEnabled(true, false); microfoneControlState = true; microfoneControl.setBackgroundResource(R.drawable.icn_mic); } } }); localCameraControl = findViewById(R.id.localCameraControl); fadeout2 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.localfadeout); fadein = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fadein); localslide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.localslide); localslidereverse = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.localslidereverse); buttonslide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.buttonslide); buttonslidereverse = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.buttonslidereverse); Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); mainScreenWidth = size.x; mainScreenHeight = size.y; callFragment = new CallFragment(); startIntent = getIntent(); for (String permission : MANDATORY_PERMISSIONS) { if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { Log.e(TAG, "Permission " + permission + " is not granted"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) requestPermissions(MANDATORY_PERMISSIONS, 0); else { setResult(RESULT_CANCELED); stopActivityInternal(); } return; } } startCall(); } public void remoteCamControl() { pip_video_view.setVisibility(View.INVISIBLE); microfoneControl.setVisibility(View.INVISIBLE); localCameraControl.setVisibility(View.INVISIBLE); SwapView(false); } public void remoteCamControlReverse() { pip_video_view.setVisibility(View.VISIBLE); microfoneControl.setVisibility(View.VISIBLE); localCameraControl.setVisibility(View.VISIBLE); SwapView(true); } public void selfcamTap(View v) { if (videoCall.getWebRtcConnection() == null) return; if (localCameraControlState) { pip_video_view.setVisibility(View.INVISIBLE); videoCall.getWebRtcConnection().setVideoEnabled(false, false); localCameraControl.animate().translationY(350); localCameraControlState = false; localCameraControl.setBackgroundResource(R.drawable.icn_selfcam); } else { videoCall.getWebRtcConnection().setVideoEnabled(true, false); pip_video_view.setVisibility(View.VISIBLE); localCameraControl.animate().translationY(0); localCameraControlState = true; localCameraControl.setBackgroundResource(R.drawable.icn_selfcamunmute); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); System.out.println("PERMİSSINOS: " + permissions); for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "Permission not granted, can't start the call"); stopActivityInternal(); return; } } startCall(); } public VideoCall videoCall = null; @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode != CAPTURE_PERMISSION_REQUEST_CODE) return; if (data == null) { isScreenCapturing = false; } } @Override public void onPause() { super.onPause(); // Detach views when the activity is not visible to prevent rendering to a dead surface. if (videoCall != null && videoCall.getWebRtcConnection() != null) { videoCall.getWebRtcConnection().detachLocalView(pip_video_view); videoCall.getWebRtcConnection().detachRemoteView(fullscreen_video_view); videoCall.getWebRtcConnection().detachLocalView(fullscreen_video_view); videoCall.getWebRtcConnection().detachRemoteView(pip_video_view); } } @Override public void onResume() { super.onResume(); SwapView(!checkSwap); } @Override protected void onDestroy() { if (videoCall != null) { videoCall.hangup(); } // Always detach views before releasing them. if (pip_video_view != null) { if (videoCall != null && videoCall.getWebRtcConnection() != null) { videoCall.getWebRtcConnection().detachLocalView(pip_video_view); videoCall.getWebRtcConnection().detachRemoteView(pip_video_view); } pip_video_view.release(); } if (fullscreen_video_view != null) { if (videoCall != null && videoCall.getWebRtcConnection() != null) { videoCall.getWebRtcConnection().detachLocalView(fullscreen_video_view); videoCall.getWebRtcConnection().detachRemoteView(fullscreen_video_view); } fullscreen_video_view.release(); } Current = null; super.onDestroy(); } public void SetBackgroundResize() { if (addBackroundForAgentMediaMute == null || pip_video_view == null) return; addBackroundForAgentMediaMute.getLayoutParams().width = pip_video_view.getWidth(); addBackroundForAgentMediaMute.getLayoutParams().height = pip_video_view.getHeight(); addBackroundForAgentMediaMute.setX(pip_video_view.getX()); addBackroundForAgentMediaMute.setY(pip_video_view.getY()); addBackroundForAgentMediaMute.setVisibility(View.VISIBLE); addBackroundForAgentMediaMute.bringToFront(); } public void SetBackgroundResizeFullSize() { if (pip_video_view == null) return; pip_video_view.bringToFront(); } boolean checkSwap = false; public void SwapView(boolean isSwappedFeeds) { runOnUiThread(new Runnable() { @Override public void run() { if (videoCall == null || videoCall.getWebRtcConnection() == null) return; if (isSwappedFeeds) { videoCall.getWebRtcConnection().attachLocalView(pip_video_view); videoCall.getWebRtcConnection().attachRemoteView(fullscreen_video_view); pip_video_view.setMirror(true); // Local (selfie) view is small, should be mirrored fullscreen_video_view.setMirror(false); // Remote view is large, not mirrored checkSwap = false; UnResizeRemoteView(); SetBackgroundResizeFullSize(); } else { videoCall.getWebRtcConnection().attachRemoteView(pip_video_view); videoCall.getWebRtcConnection().attachLocalView(fullscreen_video_view); pip_video_view.setMirror(false); // Remote view is small, not mirrored fullscreen_video_view.setMirror(true); // Local (selfie) view is large, should be mirrored checkSwap = true; ResizeRemoteView(); SetBackgroundResize(); } } }); } public void ResizeRemoteView() { SurfaceViewRenderer largeView = getLargeView(); ViewGroup.LayoutParams paramsLargeView = largeView.getLayoutParams(); paramsLargeView.width = ViewGroup.LayoutParams.WRAP_CONTENT; paramsLargeView.height = ViewGroup.LayoutParams.WRAP_CONTENT; getLargeView().setLayoutParams(paramsLargeView); largeView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); } public void UnResizeRemoteView() { SurfaceViewRenderer largeView = getLargeView(); ViewGroup.LayoutParams params = largeView.getLayoutParams(); params.width = ViewGroup.LayoutParams.MATCH_PARENT; params.height = ViewGroup.LayoutParams.MATCH_PARENT; getLargeView().setLayoutParams(params); largeView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL); } //-----------------------HOLD DIALOG Implementation---------------------------------- private void holdDialog(boolean show) { containerHold.removeAllViews(); if (show) { prepareHoldDialog(); } else { holdDialog.dismiss(); } } void prepareHoldDialog() { holdDialog = new Dialog(this); holdDialog.setContentView(R.layout.dialog_hold); int width = ViewGroup.LayoutParams.MATCH_PARENT; int height = ViewGroup.LayoutParams.MATCH_PARENT; holdDialog.getWindow().setLayout(width, height); btnHangout = holdDialog.findViewById(R.id.cancelButton); containerHold = holdDialog.findViewById(R.id.containerHold); btnHangout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { holdDialog.dismiss(); } }); } //------------------------------------------------------------------------------------------ }