|
|
|
|
@ -3,24 +3,26 @@ package com.hmg.hmgDr.ui.fragment
|
|
|
|
|
import android.Manifest
|
|
|
|
|
import android.annotation.SuppressLint
|
|
|
|
|
import android.app.Activity
|
|
|
|
|
import android.app.Dialog
|
|
|
|
|
import android.content.Context
|
|
|
|
|
import android.content.Intent
|
|
|
|
|
import android.graphics.Color
|
|
|
|
|
import android.graphics.Point
|
|
|
|
|
import android.graphics.drawable.ColorDrawable
|
|
|
|
|
import android.opengl.GLSurfaceView
|
|
|
|
|
import android.os.Bundle
|
|
|
|
|
import android.os.CountDownTimer
|
|
|
|
|
import android.os.Handler
|
|
|
|
|
import android.os.Looper
|
|
|
|
|
import android.util.Log
|
|
|
|
|
import android.view.LayoutInflater
|
|
|
|
|
import android.view.MotionEvent
|
|
|
|
|
import android.view.View
|
|
|
|
|
import android.view.ViewGroup
|
|
|
|
|
import android.view.*
|
|
|
|
|
import android.widget.*
|
|
|
|
|
import androidx.fragment.app.Fragment
|
|
|
|
|
import androidx.annotation.Nullable
|
|
|
|
|
import androidx.fragment.app.DialogFragment
|
|
|
|
|
import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel
|
|
|
|
|
import com.hmg.hmgDr.Model.GetSessionStatusModel
|
|
|
|
|
import com.hmg.hmgDr.Model.SessionStatusModel
|
|
|
|
|
import com.hmg.hmgDr.R
|
|
|
|
|
import com.hmg.hmgDr.ui.VideoCallActivity
|
|
|
|
|
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter
|
|
|
|
|
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView
|
|
|
|
|
import com.hmg.hmgDr.ui.VideoCallPresenterImpl
|
|
|
|
|
@ -31,10 +33,20 @@ import pub.devrel.easypermissions.AppSettingsDialog
|
|
|
|
|
import pub.devrel.easypermissions.EasyPermissions
|
|
|
|
|
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
|
|
|
|
|
import java.util.*
|
|
|
|
|
import kotlin.math.ceil
|
|
|
|
|
|
|
|
|
|
class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener,
|
|
|
|
|
class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener,
|
|
|
|
|
SubscriberKit.VideoListener, VideoCallView {
|
|
|
|
|
|
|
|
|
|
var isFullScreen: Boolean = true
|
|
|
|
|
private var x_init_cord = 0
|
|
|
|
|
private var y_init_cord:Int = 0
|
|
|
|
|
private var x_init_margin:Int = 0
|
|
|
|
|
private var y_init_margin:Int = 0
|
|
|
|
|
private val szWindow: Point = Point()
|
|
|
|
|
private lateinit var mWindowManager: WindowManager
|
|
|
|
|
private var isLeft = true
|
|
|
|
|
|
|
|
|
|
lateinit var videoCallPresenter: VideoCallPresenter
|
|
|
|
|
|
|
|
|
|
private var mSession: Session? = null
|
|
|
|
|
@ -61,11 +73,13 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
private var isSpeckerClicked = false
|
|
|
|
|
private var isMicClicked = false
|
|
|
|
|
|
|
|
|
|
private var mCallBtn: ImageView? = null
|
|
|
|
|
private var mCameraBtn: ImageView? = null
|
|
|
|
|
private var mSwitchCameraBtn: ImageView? = null
|
|
|
|
|
private var mspeckerBtn: ImageView? = null
|
|
|
|
|
private var mMicBtn: ImageView? = null
|
|
|
|
|
private lateinit var videoCallContainer: LinearLayout
|
|
|
|
|
private lateinit var mCallBtn: ImageView
|
|
|
|
|
private lateinit var btnMinimize: ImageView
|
|
|
|
|
private lateinit var mCameraBtn: ImageView
|
|
|
|
|
private lateinit var mSwitchCameraBtn: ImageView
|
|
|
|
|
private lateinit var mspeckerBtn: ImageView
|
|
|
|
|
private lateinit var mMicBtn: ImageView
|
|
|
|
|
|
|
|
|
|
private val progressBar: ProgressBar? = null
|
|
|
|
|
private val countDownTimer: CountDownTimer? = null
|
|
|
|
|
@ -84,6 +98,45 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
requestPermissions()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onStart() {
|
|
|
|
|
super.onStart()
|
|
|
|
|
|
|
|
|
|
dialog?.window?.setLayout(
|
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun getTheme(): Int {
|
|
|
|
|
return R.style.dialogTheme
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog {
|
|
|
|
|
val dialog: Dialog = super.onCreateDialog(savedInstanceState)
|
|
|
|
|
return dialog
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
|
|
super.onViewCreated(view, savedInstanceState)
|
|
|
|
|
|
|
|
|
|
// This is done in a post() since the dialog must be drawn before locating.
|
|
|
|
|
requireView().post {
|
|
|
|
|
val dialogWindow = dialog!!.window
|
|
|
|
|
|
|
|
|
|
if (dialog != null && dialogWindow != null) {
|
|
|
|
|
dialogWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make the dialog possible to be outside touch
|
|
|
|
|
dialogWindow!!.setFlags(
|
|
|
|
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
|
|
|
|
|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
|
|
|
)
|
|
|
|
|
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
|
|
|
|
requireView().invalidate()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
|
|
|
|
savedInstanceState: Bundle?): View? {
|
|
|
|
|
|
|
|
|
|
@ -91,6 +144,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
|
|
|
|
|
Objects.requireNonNull(requireActivity().actionBar)!!.hide()
|
|
|
|
|
initUI(view)
|
|
|
|
|
handleDragDialog()
|
|
|
|
|
|
|
|
|
|
return view
|
|
|
|
|
}
|
|
|
|
|
@ -121,6 +175,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
|
|
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
|
|
private fun initUI(view: View) {
|
|
|
|
|
videoCallContainer = view.findViewById<LinearLayout>(R.id.video_call_ll)
|
|
|
|
|
mPublisherViewContainer = view.findViewById<FrameLayout>(R.id.local_video_view_container)
|
|
|
|
|
mSubscriberViewContainer = view.findViewById<RelativeLayout>(R.id.remote_video_view_container)
|
|
|
|
|
|
|
|
|
|
@ -136,11 +191,29 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
controlPanel = view.findViewById<RelativeLayout>(R.id.control_panel)
|
|
|
|
|
videoCallPresenter = VideoCallPresenterImpl(this, baseUrl)
|
|
|
|
|
mCallBtn = view.findViewById<ImageView>(R.id.btn_call)
|
|
|
|
|
mCallBtn.setOnClickListener {
|
|
|
|
|
onCallClicked(it)
|
|
|
|
|
}
|
|
|
|
|
btnMinimize = view.findViewById<ImageView>(R.id.btn_minimize)
|
|
|
|
|
btnMinimize.setOnClickListener {
|
|
|
|
|
onMinimizedClicked(it)
|
|
|
|
|
}
|
|
|
|
|
mCameraBtn = view.findViewById<ImageView>(R.id.btn_camera)
|
|
|
|
|
mCameraBtn.setOnClickListener {
|
|
|
|
|
onCameraClicked(it)
|
|
|
|
|
}
|
|
|
|
|
mSwitchCameraBtn = view.findViewById<ImageView>(R.id.btn_switch_camera)
|
|
|
|
|
mSwitchCameraBtn.setOnClickListener {
|
|
|
|
|
onSwitchCameraClicked(it)
|
|
|
|
|
}
|
|
|
|
|
mspeckerBtn = view.findViewById<ImageView>(R.id.btn_specker)
|
|
|
|
|
mspeckerBtn.setOnClickListener {
|
|
|
|
|
onSpeckerClicked(it)
|
|
|
|
|
}
|
|
|
|
|
mMicBtn = view.findViewById<ImageView>(R.id.btn_mic)
|
|
|
|
|
|
|
|
|
|
mMicBtn.setOnClickListener {
|
|
|
|
|
onMicClicked(it)
|
|
|
|
|
}
|
|
|
|
|
// progressBarLayout=findViewById(R.id.progressBar);
|
|
|
|
|
// progressBar=findViewById(R.id.progress_bar);
|
|
|
|
|
// progressBarTextView=findViewById(R.id.progress_bar_text);
|
|
|
|
|
@ -316,6 +389,20 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
requireActivity().finish()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) {
|
|
|
|
|
if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) {
|
|
|
|
|
val returnIntent = Intent()
|
|
|
|
|
returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel)
|
|
|
|
|
requireActivity().setResult(Activity.RESULT_OK, returnIntent)
|
|
|
|
|
requireActivity().finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {}
|
|
|
|
|
|
|
|
|
|
override fun onFailure() {}
|
|
|
|
|
|
|
|
|
|
fun onSwitchCameraClicked(view: View?) {
|
|
|
|
|
if (mPublisher != null) {
|
|
|
|
|
isSwitchCameraClicked = !isSwitchCameraClicked
|
|
|
|
|
@ -325,6 +412,25 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onCallClicked(view: View?) {
|
|
|
|
|
disconnectSession()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onMinimizedClicked(view: View?) {
|
|
|
|
|
if (isFullScreen) {
|
|
|
|
|
dialog?.window?.setLayout(
|
|
|
|
|
400,
|
|
|
|
|
600
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
dialog?.window?.setLayout(
|
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
isFullScreen = !isFullScreen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onCameraClicked(view: View?) {
|
|
|
|
|
if (mPublisher != null) {
|
|
|
|
|
isCameraClicked = !isCameraClicked
|
|
|
|
|
@ -334,6 +440,15 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onMicClicked(view: View?) {
|
|
|
|
|
if (mPublisher != null) {
|
|
|
|
|
isMicClicked = !isMicClicked
|
|
|
|
|
mPublisher!!.publishAudio = !isMicClicked
|
|
|
|
|
val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled
|
|
|
|
|
mMicBtn!!.setImageResource(res)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onSpeckerClicked(view: View?) {
|
|
|
|
|
if (mSubscriber != null) {
|
|
|
|
|
isSpeckerClicked = !isSpeckerClicked
|
|
|
|
|
@ -343,31 +458,144 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onMicClicked(view: View?) {
|
|
|
|
|
if (mPublisher != null) {
|
|
|
|
|
isMicClicked = !isMicClicked
|
|
|
|
|
mPublisher!!.publishAudio = !isMicClicked
|
|
|
|
|
val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled
|
|
|
|
|
mMicBtn!!.setImageResource(res)
|
|
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
|
|
fun handleDragDialog(){
|
|
|
|
|
mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
|
|
|
|
getWindowManagerDefaultDisplay()
|
|
|
|
|
|
|
|
|
|
videoCallContainer.setOnTouchListener { _, event ->
|
|
|
|
|
//Get Floating widget view params
|
|
|
|
|
//Get Floating widget view params
|
|
|
|
|
val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
|
|
|
|
|
//get the touch location coordinates
|
|
|
|
|
val x_cord = event.rawX.toInt()
|
|
|
|
|
val y_cord = event.rawY.toInt()
|
|
|
|
|
val x_cord_Destination: Int
|
|
|
|
|
var y_cord_Destination: Int
|
|
|
|
|
|
|
|
|
|
when (event.action) {
|
|
|
|
|
MotionEvent.ACTION_DOWN -> {
|
|
|
|
|
x_init_cord = x_cord
|
|
|
|
|
y_init_cord = y_cord
|
|
|
|
|
|
|
|
|
|
//remember the initial position.
|
|
|
|
|
x_init_margin = layoutParams.x
|
|
|
|
|
y_init_margin = layoutParams.y
|
|
|
|
|
}
|
|
|
|
|
MotionEvent.ACTION_UP -> {
|
|
|
|
|
//Get the difference between initial coordinate and current coordinate
|
|
|
|
|
val x_diff: Int = x_cord - x_init_cord
|
|
|
|
|
val y_diff: Int = y_cord - y_init_cord
|
|
|
|
|
|
|
|
|
|
y_cord_Destination = y_init_margin + y_diff
|
|
|
|
|
val barHeight: Int = getStatusBarHeight()
|
|
|
|
|
if (y_cord_Destination < 0) {
|
|
|
|
|
// y_cord_Destination = 0
|
|
|
|
|
y_cord_Destination =
|
|
|
|
|
-(szWindow.y - (videoCallContainer.height /*+ barHeight*/))
|
|
|
|
|
} else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) {
|
|
|
|
|
y_cord_Destination =
|
|
|
|
|
szWindow.y - (videoCallContainer.height + barHeight)
|
|
|
|
|
}
|
|
|
|
|
layoutParams.y = y_cord_Destination
|
|
|
|
|
|
|
|
|
|
//reset position if user drags the floating view
|
|
|
|
|
resetPosition(x_cord)
|
|
|
|
|
}
|
|
|
|
|
MotionEvent.ACTION_MOVE -> {
|
|
|
|
|
val x_diff_move: Int = x_cord - x_init_cord
|
|
|
|
|
val y_diff_move: Int = y_cord - y_init_cord
|
|
|
|
|
x_cord_Destination = x_init_margin + x_diff_move
|
|
|
|
|
y_cord_Destination = y_init_margin + y_diff_move
|
|
|
|
|
|
|
|
|
|
layoutParams.x = x_cord_Destination
|
|
|
|
|
layoutParams.y = y_cord_Destination
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = layoutParams
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onCallClicked(view: View?) {
|
|
|
|
|
disconnectSession()
|
|
|
|
|
/* Reset position of Floating Widget view on dragging */
|
|
|
|
|
private fun resetPosition(x_cord_now: Int) {
|
|
|
|
|
if (x_cord_now <= szWindow.x / 2) {
|
|
|
|
|
isLeft = true
|
|
|
|
|
moveToLeft(x_cord_now)
|
|
|
|
|
} else {
|
|
|
|
|
isLeft = false
|
|
|
|
|
moveToRight(x_cord_now)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) {
|
|
|
|
|
if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) {
|
|
|
|
|
val returnIntent = Intent()
|
|
|
|
|
returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel)
|
|
|
|
|
requireActivity().setResult(Activity.RESULT_OK, returnIntent)
|
|
|
|
|
requireActivity().finish()
|
|
|
|
|
}
|
|
|
|
|
/* Method to move the Floating widget view to Left */
|
|
|
|
|
private fun moveToLeft(current_x_cord: Int) {
|
|
|
|
|
|
|
|
|
|
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
|
|
|
|
|
|
|
|
|
|
mParams.x =
|
|
|
|
|
(szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt()
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = mParams
|
|
|
|
|
val x = szWindow.x - current_x_cord
|
|
|
|
|
object : CountDownTimer(500, 5) {
|
|
|
|
|
//get params of Floating Widget view
|
|
|
|
|
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
|
|
|
|
|
override fun onTick(t: Long) {
|
|
|
|
|
val step = (500 - t) / 5
|
|
|
|
|
// mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt()
|
|
|
|
|
mParams.x =
|
|
|
|
|
(szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt()
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = mParams
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onFinish() {
|
|
|
|
|
mParams.x = -(szWindow.x - videoCallContainer.width)
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = mParams
|
|
|
|
|
}
|
|
|
|
|
}.start()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {}
|
|
|
|
|
/* Method to move the Floating widget view to Right */
|
|
|
|
|
private fun moveToRight(current_x_cord: Int) {
|
|
|
|
|
// var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
|
|
|
|
|
// mParams.x =
|
|
|
|
|
// (szWindow.x + current_x_cord * current_x_cord - videoCallContainer.width).toInt()
|
|
|
|
|
//
|
|
|
|
|
// dialog!!.window!!.attributes = mParams
|
|
|
|
|
object : CountDownTimer(500, 5) {
|
|
|
|
|
//get params of Floating Widget view
|
|
|
|
|
var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes
|
|
|
|
|
override fun onTick(t: Long) {
|
|
|
|
|
val step = (500 - t) / 5
|
|
|
|
|
mParams.x =
|
|
|
|
|
(szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt()
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = mParams
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onFailure() {}
|
|
|
|
|
override fun onFinish() {
|
|
|
|
|
mParams.x = szWindow.x - videoCallContainer.width
|
|
|
|
|
|
|
|
|
|
dialog!!.window!!.attributes = mParams
|
|
|
|
|
}
|
|
|
|
|
}.start()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun getWindowManagerDefaultDisplay() {
|
|
|
|
|
mWindowManager.getDefaultDisplay()
|
|
|
|
|
.getSize(szWindow)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return status bar height on basis of device display metrics */
|
|
|
|
|
private fun getStatusBarHeight(): Int {
|
|
|
|
|
return ceil(
|
|
|
|
|
(25 * requireActivity().applicationContext.resources.displayMetrics.density).toDouble()
|
|
|
|
|
).toInt()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
@JvmStatic
|
|
|
|
|
@ -376,7 +604,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen
|
|
|
|
|
arguments = args
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val TAG = VideoCallActivity::class.java.simpleName
|
|
|
|
|
private val TAG = VideoCallFragment::class.java.simpleName
|
|
|
|
|
|
|
|
|
|
private const val RC_SETTINGS_SCREEN_PERM = 123
|
|
|
|
|
private const val RC_VIDEO_APP_PERM = 124
|
|
|
|
|
|